披着函数外衣的关键字
2016-05-11 12:54
363 查看
首先我们必须知道,sizeof()是一个关键字(在编译期间就进行计算),而不是一个函数,这一点我们可以证明:
我们可以观察到,b的值没有发生变化,所以sizeof是一个关键字,而不是一个函数。
2、在求数组大小时,只能在数组声明的代码块里面求取。
例:
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
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
相关文章推荐
- [SCU 4504] 奶牛合影 (最小表示法)
- 【Arduino官方教程第一辑】示例程序 3-6 LED亮度渐隐
- 用代码告诉你“问世间情为何物,直教人生死相许”
- 总结常见的ES6新语法特性
- font-size使用em
- [swift学习之九]异常处理
- 安卓动态调试七种武器之离别钩 – Hooking(下)
- 如何提高循环效率
- red hat linux使用yum 出现Loaded plugins: rhnplugin, security
- Concurrent包中Queue(2)----ArrayBlockingQueue
- EventBus使用详解(一)——初步使用EventBus
- 数组名与数组名取地址的差异
- 《java入门第一季》之好玩的正则表达式
- mac Homebrew
- 《java入门第一季》之好玩的正则表达式
- C++数据类型
- Activity传递对象的方法《转载》
- In-memory Computing with SAP HANA读书笔记 - 第三章:Software components and data replication methods
- Concurrent包中Queue(1)----LinkedBlockingQueue
- Oracle字符,数值等操作