首先我们必须知道,sizeof()是一个关键字(在编译期间就进行计算),而不是一个函数,这一点我们可以证明:
int main()
{
int a = 5;
short b = 3;
printf( "%d\n", sizeof (b = a + 2));
printf( "b=%d\n", b);
system( "pause");
return 0;
}
我们可以观察到,b的值没有发生变化,所以sizeof是一个关键字,而不是一个函数。
2、在求数组大小时,只能在数组声明的代码块里面求取。
例:
int num_arr(int arr[]) //形参arr其实是数组的首地址,所以对他求内存相当于对arr[0]求内存
{
int b = sizeof (arr);
return b;
}
int main()
{
int arr[10];
int ret=num_arr(arr);
printf( "sizeof(arr)=%d\n", sizeof (arr)); //这个arrs是整个数组的地址,相当于&arr
printf( "ret=%d\n", ret);
system( "pause");
return 0;
}
3、int arr[10];
因为sizeof()是一个关键字 所以这两种方式都是正确的
sizeof arr;
sizeof(arr);
但是:
sizeof(int) 正确
sizeof int 错误
这是因为int也是一个关键字,所以两个关键字放在一起,会产生语法错误。
4、求内存和长度的差异:
1、整形数组:
int a[] = { 1, 2, 3, 4 };
printf( "%p\n",a); //a代表首元素地址
printf( "%p\n",a+1); //a+1表示第二个元素的地址
printf( "%p\n",&a); //&a代表整个数组的首地址
printf( "%p\n",&a+1); //&a代表数组的地址,&a+1则跳过整个数组
printf( "%d\n", sizeof (a)); //a在sizeof()中代表整个数组, 16
printf( "%d\n", sizeof (a + 0)); //代表&a[0],32位下所有的地址大小都为4 4
printf( "%d\n", sizeof (*a)); //表示a[0],int占4个字节 4
printf( "%d\n", sizeof (a + 1)); //表示&a[1],32位下所有的地址大小都为4 4
printf( "%d\n", sizeof (a[1])); //表示a[1],int占4个字节 4
printf( "%d\n", sizeof (&a)); //代表整个数组的地址,32位下所有的地址大小都为4 4
printf( "%d\n", sizeof (&a + 1)); //因为&a代表整个数组地址,&a+1跳过整个数组,但还是一个地址
printf( "%d\n", sizeof (&a[0])); //表示a[0]的地址 4
printf( "%d\n", sizeof (&a[0] + 1)); //表示a[1]的地址 4
printf( "%d\n", sizeof (*&a)); //&a代表整个数组,再*引用访问这块地址,就相当于求取真个数组的大小 16
2、字符数组:
char name[] = "abcdef" ; //这时字符串不代表首元素地址,而是字符数组的一种初始化方式,并且字符串总是默认以’\0‘结尾
printf( "%d\n", sizeof (name[0])); //表示a,32位下char大小为1 1
printf( "%d\n", sizeof (&name)); //表示整个数组的地址,32位下地址就是4 4
printf( "%d\n", sizeof (*name)); //表示 a 1
printf( "%d\n", sizeof (&name+1)); //表示指向整个数组之后的一块空间,但还是一个地址 4
printf( "%d\n", sizeof (name+1)); //表示b的地址 4
printf( "%d\n", sizeof (name)); //代表整个数组,还要加上‘\0' 7
printf( "%d\n", strlen(name)); //求取字符串长度,不包括’\0‘ 6
printf( "%d\n", strlen(&name)); //代表整个数组的地址,&name==name,strlen遇到’\0‘停下 6
printf( "%d\n", strlen(&name + 1)); //是一个随机值,表示指向整个数组之后的一个地址,从这个地址开始向后寻找'\0',因为’\0‘位置不确定所以是随机值
printf( "%d\n", strlen(name + 1)); //表示b的地址
3、字符指针:
char *name = "abcdef" ; //字符串放在等号右边代表首元素地址
printf( "%d\n", sizeof (name[0])); //以下标形式访问,代表 a 1
printf( "%d\n", sizeof (&name)); //表示字符指针name的地址 4
printf( "%d\n", sizeof (*name)); //通过*访问,表示a 1
printf( "%d\n", sizeof (&name+1)); //表示指针name之后的一块地址 4
printf( "%d\n", sizeof (name+1)); //表示b的地址 4
printf( "%d\n", sizeof (name)); //代表a的地址, 4
printf( "%d\n", strlen(name)); //代表字符串首元素地址 6
printf( "%d\n", strlen(&name)); //表示指针name本身地址,因为从name开始向后’\0‘的位置不确定,所以是个随机值
printf( "%d\n", strlen(&name + 1)); //表示指针name本身地址之后的地址,因为’\0‘的位置不确定,所以是个随机值
printf( "%d\n", strlen(name + 1)); //代表b的地址 5