本篇文章posted on 2019-12-23 12:58
本人之前写过一篇类似的文章(链接:sizeof运算符和strlen()函数),也比较深入,但是和本篇相比,本篇更加深入。
首先请看下面的代码,这个代码应该输出什么。
下面是C语言代码。
1 #include<stdio.h> 2 3 int main(void) 4 { 5 int a=2,b=0; 6 sizeof(b=a++); 7 printf("a=%d,b=%d\n",a,b); 8 return 0; 9 }
输出结果如下。
a=2,b=0
首先本人需要强调的是,如果没有sizeof运算符,仅仅是b=a++,那么本题相当容易,就是一道普通的C语言题,输出结果自然就是a=3,b=2,但是令人想不明白的是,在这个赋值运算外面加上一个sizeof运算符,竟然会对赋值的效果产生改变,首先这个sizeof运算符的运算结果是4,unsigned int型,没有问题,但是这个结果没有保存起来,所以不用管。现在我们要考虑的问题是,sizeof里面的赋值运算还执行不执行了,按照习惯,给人的感觉好像是C语言的运算符先按优先级再按结合方向依次执行,好像是先++再=再sizeof(这部分如果不能理解可以看我另一篇文章,链接:自增自减与赋值运算),但是需要额外考虑的是sizeof运算符的结果在运行程序前就是已知的了,在编译阶段就算好了,所以里面的赋值根本不执行,尽管里面对变量进行赋值,仍然不被执行。
下面是一个类似的C语言代码。
1 #include<stdio.h> 2 3 int main(void) 4 { 5 int a=2; 6 sizeof(a=3); 7 sizeof(a+=++a); 8 printf("a=%d\n",a); 9 return 0; 10 }
输出结果如下。
a=2
下面是一个和转义字符相结合的C语言代码。
1 #include<stdio.h> 2 #include<string.h> 3 4 int main(void) 5 { 6 char s1[]="\\0\012\028\080\088"; 7 char s2[]="\00\\0\\\018\012\1bc\123\a23\abc\081\088"; 8 printf("strlen(s1):%d\n",strlen(s1)); 9 printf("sizeof(s1):%d\n",sizeof(s1)); 10 printf("sizeof(s2):%d\n",sizeof(s2)); 11 return 0; 12 }
输出结果如下。
strlen(s1):5 sizeof(s1):12 sizeof(s2):24
本题比较难,因为涉及的知识点比较多。首先提一个简单的知识点,sizeof("\0")的值是2,因为里面有2个字符串结尾标记。
下面本人将s1数组和s2数组的内部分配字符方式展示一下。
char s1[]="\\0\012\028\080\088";
char s2[]="\00\\0\\\018\012\1bc\123\a23\abc\081\088";(背景颜色是一样的,如果觉得不一样那是视觉效果)
本人需要强调的是,'\0'确实是字符串结尾标记,几乎所有的C语言教材都是这么描述的,但是当'\0'后再跟数字时,可能会拼接成其它字符,所以本人认为,应该用'\000'来表示字符串结尾标记。这种风格本人原先是没有的,但经历过上文中的C语言理论题后就产生这种风格了。