你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

10个C语言的迷题以及答案

[复制链接]
gaosmile 发布时间:2020-10-12 22:46
本文展示了10个C语言的迷题以及答案,而且有相当的一些例子可能是我们日常工作可能会见得到的。通过这些迷题,希望你能更了解C语言。

如果你不看答案,不知道是否有把握回答各个谜题?让我们来试试。

1
会输出"hello-std-out"

#include<stdio.h>
int main()
{
while (1)
    {
        fprintf(stdout, "hello-std-out");
        fprintf(stderr, "hello-std-err");
        sleep(1);
    }
    return 0;
}

参考答案:
stdout和stderr是不同设备描述符。stdout是块设备,stderr则不是。对于块设备,只有当下面几种情况下才会被输入:遇到回车;缓冲区满;flush被调用。而stderr则不会。
2
这段程序是有问题吗?

#include<stdio.h>
int main()
{
    int a = 1,2;
    printf("a : %d\n",a);
    return 0;
}
参考答案:
这个程序会得到编译出错(语法出错)。逗号表达式是没错,可是在初始化和变量声明时,逗号并不是逗号表达式的意义。这点要区分,要修改上面这个程序,你需要加上括号:"int a = (1,2);"。

3
下面的程序会有什么样的输出呢?

#include<stdio.h>
int main()
{
    int i=43;
    printf("%d\n",printf("%d",printf("%d",i)));
    return 0;
}
参考答案
程序会输出4321,你知道为什么吗?要知道为什么,你需要知道printf的返回值是什么。printf返回值是输出的字符个数。

4
下面的程序会输出什么?

#include<stdio.h>
int main()
{
float a = 12.5;
printf("%d\n", a);
printf("%d\n", (int)a);
printf("%d\n", *(int*)&a);
return 0;
}
参考答案
该项程序输出:"0 12 1095237632"。
原因是:浮点数是4个字节,12.5f转成二进制是:01000001010010000000000000000000,十六进制是:0x41480000,十进制是:1095237632。所以,第二和第三个输出相信大家也知道是为什么了。
而对于第一个,为什么会输出0,我们需要了解一下float和double的内存布局,如下:
  • float: 1位符号位(s)、8位指数(e),23位尾数(m,共32位)。
  • double: 1位符号位(s)、11位指数(e),52位尾数(m,共64位)。

然后,我们还需要了解一下printf由于类型不匹配,所以,会把float直接转成double,注意,12.5的float和double的内存二进制完全不一样。别忘了在x86芯片下使用是的反字节序,高位字节和低位字位要反过来。所以:
  • float版:0x41480000 (在内存中是:00 00 48 41)。
  • double版:0x4029000000000000 (在内存中是:00 00 00 00 00 00 29 40)。

而我们的%d要求是一个4字节的int,对于double的内存布局,我们可以看到前四个字节是00,所以输出自然是0了。这个示例向我们说明printf并不是类型安全的,这就是为什么C++要引如cout的原因了。

5
下面的程序输出是多少?并解释为什么?

#include<stdio.h>
int main()
{
int a = 1;
switch (a)
{
int b = 20;
case 1:
printf("b is %d\n", b);
break;
default:
printf("b is %d\n", b);
break;
}
return 0;
}
参考答案
该程序在编译时,报错:“b”的初始化操作由“case”标签跳过,“default”标签跳过“b”的初始化操作

6
下面的程序会有什么潜在的危险

#include<stdio.h>
int main()
{
char str[10];
printf("Enter the string:");
scanf("%s", str);
printf("You entered:%s\n", str);
return 0;
}
参考答案
本题很简单了。这个程序的潜在问题是,如果用户输入了超过80个长度的字符,那么就会有数组越界的问题了,你的程序很有可能会crash了。

7
请问下面的程序输出什么

#include<stdio.h>
int main()
{
int i;
i = 10;
printf("i : %d\n", i);
printf("sizeof(i++) is: %d\n", sizeof(i++));
printf("i : %d\n", i);
return 0;
}
参考答案
如果你觉得输出分别是:10,4,11。那么你就错了。
错在了第三个,第一个是10没有什么问题,第二个是4,也没有什么问题,因为是32位机上一个int有4个字节。但是第三个为什么输出的不是11呢?居然还是10?原因是,sizeof不是一个函数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译时)完全的事情,所以,sizeof(i++)直接就被4给取代了,在运行时也就不会有了i++这个表达式。

8
下面的程序的输出值是什么

#include<stdio.h>
#define SIZEOF(arr) (sizeof(arr)/sizeof(arr[0]))
#define PrintInt(expr) printf("%s:%d\n",#expr,(expr))

int main()
{
/* The powers of 10 */
int pot[] = {
0001,
0010,
0100,
1000
};
int i;
for (i = 0; i < SIZEOF(pot); i++)PrintInt(pot);
return 0;
}
参考答案
如果你对于PrintInt这个宏有问题的话,可以去看一看资料。不过,本例的问题不在这里,本例的输出会是:1,8,64,1000。其实很简单了,在C/C++中,以0开头的数字都是八进制的。

9
下面的输出是什么

#include<stdio.h>
int main()
{
int i = 6;
if (((++i < 7) && (i++ / 6)) || (++i <= 9));
printf("%d\n", i);
return 0;
}
参考答案
本题并不简单的是考前缀++或反缀++,本题主要考的是&&和||的短路求值的问题。
所谓短路求值:对于(条件1 && 条件2),如果“条件1”是false,那“条件2”的表达式会被忽略了。对于(条件1 || 条件2),如果“条件1”为true,而“条件2”的表达式则被忽略了。
所以,我相信你会知道本题的答案是什么了。

10
下面的C程序是合法的吗

#include<stdio.h>
int main()
{
int a = 3, b = 5;
printf(&a["Ya!Hello! how is this? %s\n"], &b["junk/super"]);
//等价printf("Hello! how is this? %s\n", "super");
printf(&a["WHAT%c%c%c %c%c %c !\n"], 1["this"], 2["beauty"], 0["tool"], 0["is"], 3["sensitive"], 4["CCCCCC"]);
return 0;
}
参考答案
本例是合法的,输出为:"Hello! how is this? super That is C !"
本例主要展示了一种另类的用法。下面的两种用法是相同的:
  • "hello"[2]
  • 2["hello"]
如果你知道:a 其实就是 *(a+i)也就是 *(i+a),所以如果写成 i[a] 应该也不难理解了。

收藏 评论0 发布时间:2020-10-12 22:46

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版