C语言迷惑行为大赏

C语言迷惑行为大赏析。

代码0:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//来源:公众号【编程珠玑】
#include<stdio.h>
int main(void)
{
int c = 5;
switch(c)
{
case 0 ... 10:
printf("0-->10\n");
break;
case 11 ... 20:
printf("11-->20\n");
break;
default:
printf("other\n");
}
return 0;
}

输出结果:

1
0-->10

以上特性被常见编译器支持,但是标准中并未提到。

代码1

1
2
3
4
5
6
#include<stdio.h>
int main(void)
{
printf("%m\n");
return 0;
}

输出结果:

1
Success

等价于:

1
printf("%s\n",stderr(errno));

由于你的代码前面并没有执行出错设置errno,因此errno会是0,而对应的描述信息就是Success。

代码2

1
2
3
4
5
6
7
8
9
#include<stdio.h>
int main(void)
{
int i = 10;
printf("%zu\n",sizeof(i++));
printf("%zu\n",sizeof(++i));
printf("%d\n",10);
return 0;
}

输出结果:

1
2
3
4
4
10

sizeof实际作用的对象是类型。sizeof中的表达式本身并不会被执行。

代码3

1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <unistd.h>
int main(void)
{
while(1)
{
fprintf(stdout,"公众号");
fprintf(stderr,"编程珠玑");
sleep(10);
}
return 0;
}

输出结果:

1
编程珠玑编程珠玑编程珠玑

为什么不会输出公众号呢?原因在于标准输入默认是行缓冲,而标准错误是无缓冲。这在《》中已经有解释了。

代码4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
int main(void)
{
int a = 10;
switch(a)
{
int b = 20;
case 10:
printf("%d\n",a + b);
break;
default:
printf("%d\n",a + b);
break;
}
return 0;
}

输出结果:

1
10

switch中的int b = 20,并不会被执行,你编译时就会发现有警告。

代码4

1
2
3
4
5
6
#include <stdio.h>
int main(void)
{
printf("%c\n",4["hello 公众号编程珠玑"]);
return 0;
}

输出结果:

1
o

等价于:

1
2
char *str = "hello 公众号编程珠玑";
printf("%c\n",str[4]);

代码5

1
2
3
4
5
6
7
8
9
//来源:公众号编程珠玑
//https://www.yanbinghu.com
#include<stdio.h>
int main(void)
{
char arr[] = {'h','e','l','l','o'};
printf("%s\n",arr);//灾难!
return 0;
}

代码6

没啥用,还会core dump的超短代码:

1
main=0;

代码7

1
2
3
4
5
6
7
8
9
10
11
#include<stdio.h>
int main(void)
{
int arr[] = {5,4,3,2,1};
for(int i = -1; i < sizeof(arr)/sizeof(int) - 1; i++)
{
printf("%d\n",arr[i+1]);
}
printf("end\n");
return 0;
}

输出结果:

1
end

原因也很简单,sizeof(arr)/sizeof(int)的结果是unsigend, int类型的i 和unsigned比较,被转换为一个很大的unsigned数,所以for循环的条件不满足。

代码8

1
2
3
4
5
6
7
8
9
10
11
12
#include<stdio.h>
test()
{
long b = 12345678987654321;
return b;
}
int main(void)
{
long a = test();
printf("%ld\n",a);
return 0;
}

输出结果:

1
1653732529

代码9

1
2
3
4
5
6
7
8
#include<stdio.h>
int main(void)
{
float a = 3;
int b = 2;
printf("%d\n",a/2);
return 0;
}

输出结果:

1
1199094392

原因:浮点数在计算机中按照IEEE754标准存储

守望 wechat
关注公众号[编程珠玑]获取更多原创技术文章
出入相友,守望相助!