之前就知道数组名和指针不同,因为运算符sizeof对数组名和指向数组的指针的运算结果是不同的–sizeof数组名得到的是数组空间的大小,而sizeof指向数组的指针获得的是指针自身占据空间大小。而如果是对指针进行解引用,即对象是指针指向的,那么sizeof得到的是这个对象的大小。
举例:
char aszFoo_Name[4];
char *pcFoo_Name = aszFoo_Name;
sizeof(aszFoo_Name) = 4;
sizeof(pcFoo_Name) = 8;
sizeof(*pcFoo_Name) = 1;
今天恰好看到关于linux(注意可移植性)里面对于0数量成员的数组的一些解释,举例:
typedef struct tagFoo_xxx
{
char cT1;
char acT2[0];
}Foo_xxx;
acT2就是我说的这种成员数量为0的数组,sizeof(Foo_xxx)得到的大小是1,可以验证acT2这种数组是不占空间的,引用别人博客的一段话:
char a[1]里面的a和char *b的b相同吗?《 Programming Abstractions in C》(Roberts,
E. S.,机械工业出版社,2004.6)82页里面说:“arr is defined to be identical to
&arr[0]”。也就是说,char a[1]里面的a实际是一个常量,等于&a[0]。而char *b是有一个实实在在的指针变量b存在。
所以,a=b是不允许的,而b=a是允许的。
上面这种东西的用法大致如下,也是从别人的博客搞来的:
#include
#include
struct line {
int length;
char contents[0]; // C99的玩法是:char contents[]; 没有指定数组长度
};
int main(){
int this_length=10;
struct line *thisline = (struct line *)malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
memset(thisline->contents, 'a', this_length);
return 0;
}
上面这段代码的意思是:我想分配一个不定长的数组,于是我有一个结构体,其中有两个成员,一个是
length,代表数组的长度,一个是contents,代码数组的内容。后面代码里的this_length(长度是10)代表是我想分配的数据的长度。(这看上去是不是像一个C++的类?)这种玩法英文叫:FlexibleArray,中文翻译叫:柔性数组。
需要注意的是后面根的缓冲区不能自己释放,所以要手动释放,防止内存泄露。。。
我感觉可以结合一下理解下数组名是什么东西。
而且对数组名取地址和数组名的值是相同的,那么 数组名指向的是首个元素的地址,数组名取地址指向的是数组的地址,所以这两者的值是相同的。结合数组指针来理解一下:
char acTest[3]={1,2,3};
char (*pacTest1)[3]=&acTest;
char *pacTest2= acTest;
printf("%d",acTest);
printf("%d",&acTest);
printf("%d",*acTest);
printf("%d",*(&acTest));
数组指针pacTest1必须要将数组名的取地址的值赋给它,直接用数组名赋值编译错误,同样char指针必须用数组名赋值。而四个printf的输出结果,一二四是相同的,都是同一地址,而第三输出为1.这样就可以佐证上面的说法是正确的。
那么二维数组又是怎样的呢:
char acTest[2][3]={1,2,3,4,5,6};
char (*pacTest1)[3]=acTest;
char (*pacTest2)[2][3]=&acTest;
printf("%d",acTest);
printf("%d",&acTest);
printf("%d",*acTest);
printf("%d",*(&acTest));
这次四个表达式的值是相同的。二维数组可分解为多个一维数组,即以一维数组为成员,如二维数组acTest可分解为拥有三个成员的数组:acTest[0],acTest[1],acTest[2],所以数组名直接指向的是其成员:一维数组,而对其取地址得到的才是二维数组地址,这和上面的结论相同。那么四个值相同,acTest指向一维数组acTest[0],其为一维数组的地址。&acTest指向二维数组本身。*acTest即acTest[0],也就是第一个一维数组的第一个成员的地址。最后一个与第一个相同。
数组名取地址的类型是一个数组指针类型,但它不是数组指针;而数组名的类型为这个数组的成员的类型的指针的类型,它同样不是指针(好绕。。)因为指针的sizeof都是指针自身空间的大小~~~