先說說數組和指針吧:看看下面的東西做個准備哈,,,
int q[3][4]={{1,3,5,7},{3,4,6,7},{1,6,8,9}};
a 二維數組名,指向一維數組a[0],即零行的地址
a[0],*(a+0),*a 0行0列的地址
a+1,&a[1] 1行的首地址
a[1],*(a+1) 1行0列元素a[1][0]的地址(同a[1]+0,*(a+1)+0)
a[1]+2,*(a+1)+2,&a[1][2] 1行零列元素a[1][2]的地址(同上)
*(a[1]+2),*(*(a+1)+2),a[1][2] 1行2列夫元素a[1][2]的值
如果不懂就多看幾遍吧,由於我文章重點不是在這個,今天主演是想象談談sizeof( ),所以你懂的!呵呵
首先要指出很多初學者易犯的錯誤,那就是很多人在學完C或C++的時候總會認為sizeof()是一個函數。其實sizeof( )根本就不是什麼函數。而是一個長度運算符。其實自己在一開始也總是這麼認為的,呵呵,,沒什麼一起來探討這個問題吧!
首先在說說為什麼sizeof( )為什麼不是函數吧!其實也沒有什麼為什麼吧,他本來就不是啊,還是舉個例子說明一下吧!
#include<stdio.h>
void main()
{
int a,b;
b=sizeofa;
printf("%d\n",b);
getchar();
};
看看運行結果:
想象如果是函數,sizeof( )的括號可以省略嗎?顯然是函數這是不可能的!
現在我們進入我的正題吧,看看sizeof( )的計算長度時,這裡面有好幾個地方都特別容易出錯,現在為大家總結一下,呵呵,,不多說最好的例子就是代碼了,看看下面的代碼吧:
運行結果:
#include<stdio.h>
void main()
{
int int_data=0;
float float_data=(float)1.2;
double double_data=(double)4.3;
int *int_ptr_1=&int_data;
char ch='a';
char *char_ptr_2=&ch;
char char_1[5]={'a','b','c','d','e'};
char char_2[4][5]={
{'a','b','c','d','e'},
{'a','b','c','d','e'},
{'a','b','c','d','e'},
{'a','b','c','d','e'},
};
printf("sizeof(int_data) %d\n",sizeof(int_data));
printf("sizof(float_data) %d\n",sizeof(float_data));
printf("sizeof(double_data)%d\n",sizeof(double_data));
printf("sizeof(int_ptr_1) %d\n",sizeof(int_ptr_1));
printf("sizeof(char_ptr_2) %d\n",sizeof(char_ptr_2)); //指針變量將分配一個機器字節用於存放地址的值
printf("sizeof(char_1) %d\n",sizeof(char_1));
printf("sizeof(char_2) %d\n",sizeof(char_2));
printf("sizeof(char_2[1]) %d\n",sizeof(char_2[1]));
printf("sizeof(*(char_2+1))%d\n",sizeof(*(char_2+1)));
printf("sizeof(char_2+1) %d\n",sizeof(char_2+1));
printf("sizeof(&char_2[1]) %d\n",sizeof(&char_2[1]));
printf("sizeof(char_2[1][2])%d\n",sizeof(char_2[1][2]));
}
運行結果如下:
稍微解釋一下上面的情況!
1,sizeof(char_ptr_2)); //指針變量將分配一個機器字長(一般4個字節,不同位數機器不同)用於存放地址的值,盡管char_ptr_2只指向的是一個char 類型的.
2, sizeof(char_1), sizeof(char_2)中char_1和char_2都是數組名;代表了整個數組,盡管地址是char_2代表的是零行的地址,但是他代表的是二維數組char_2[4][5];所以,,,,,
,char_1盡管指向的則是一位數組char_1[5]的首地址,但他是一位數組名,代表的是一位數組這個整體。注意和那個sizeof(chr_1_ptr)和sizeof(char_2_ptr)的區別,指針變量char_1_ptr和char_2_ptr他們的值就是一個地址,也就是一個機器字長!
3,對於char_2[1]是1行0列元素char_2 [1][0]的地址,其實也就是二位數組的第二行的首地址,其實二維數組的第二行就是一個一維數組,而cahr_2[1]則和char_1的含義是一樣的(扮演的角色一樣)。都是一維數組的首地址,所以sizeof(char_1)和sizeof(char_2[1])的值是一樣的。
4,與3不同的是對於sizeof(char_2+1)的情況就不樣了,你可以看看cahr_2+1值得是第二行的地址,此時他的值也就是一個地址,也就是一個機器字長!
特別注意3,4的微妙的區別,在一個指針代表一個地址時候,並且是一個數組的名字時(也就是代表一個數組時,無論書一維還是多維的),他們在sizeof( )所計算時的結果將是不樣的。
再就是說下在函數的返回不管是數組名還是指針變量作為函數的返回值時都返回地址,所以對於sizeof( )計算後的結果最後應該就是一樣的!
例如:
view plainc
view plain#include<stdio.h>
char *place_1();
char *place_2(char *);
void main()
{
<span style="white-space:pre"> </span> char a[5]={'a','b','c'};
<span style="white-space:pre"> </span> char *p=a;
<span style="white-space:pre"> </span> printf("sizeof(a) %d\n",sizeof(a));
<span style="white-space:pre"> </span> printf("sizeof(p) %d\n",sizeof(p));
<span style="white-space:pre"> </span> printf("sizeof(place_1()) %d\n\n",sizeof(place_1()));
<span style="white-space:pre"> </span> printf("sizeof(place_2(p)) %d\n",sizeof(place_2(p)));
}
char *place_1()
{
<span style="white-space:pre"> </span> char a[5]={'a','b','c'};
<span style="white-space:pre"> </span> printf("sizeof(a) %d\n",sizeof(a));
<span style="white-space:pre"> </span>return a;
}
char *place_2(char *p)
{
<span style="white-space:pre"> </span> printf("sizeof(p) %d\n",sizeof(p));
<span style="white-space:pre"> </span> return p;
}
運行結果如下:
參考書目:《C程序設計(第三版)》,《C語言深度剖析》