No1
以下C程序的预期输出是打印数组中的元素。 但是当实际运行时,它不会这样做
#include<stdio.h>
#define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
int array[] = {23, 34, 12, 17, 204, 99, 16};
int main()
{
int d;
for(d = -1; d <= (TOTAL_ELEMENTS-2); d++)
printf("%d\n", array[d + 1]);
return 0;
}
它看起来似乎没有问题,但当你运行的时候会出现以下的说明
comparison of integer expressions of different signedness: ‘int’ and
‘long long unsigned int’ [-Wsign-compare]
翻译以下:有符号性的整数表达式的比较:“ int”和“ long long unsigned int” [-Wsign-compare]
即d <= (TOTAL_ELEMENTS-2)
中d
为int
型,TOTAL_ELEMENTS
为long long unsigned int
型,虽然为警告信息,但程序却输出不了任何内容
NO2
下面的程序是一个完美的C程序。但是在编译时,却存在一个愚蠢的错误
#include<stdio.h>
void OS_Solaris_print()
{
printf("Solaris - Sun Microsystems\n");
}
void OS_Windows_print()
{
printf("Windows - Microsoft\n");
}
void OS_HP-UX_print()
{
printf("HP-UX - Hewlett Packard\n");
}
int main()
{
int num;
printf("Enter the number (1-3):\n");
scanf("%d",&num);
switch(num)
{
case 1:
OS_Solaris_print();
break;
case 2:
OS_Windows_print();
break;
case 3:
OS_HP-UX_print();
break;
default:
printf("Hmm! only 1-3 :-)\n");
break;
}
return 0;
}
错误void OS_HP-UX_print()
和OS_HP-UX_print()
的表达出现了不应该的符号-
,切记,切记在C语言中-
不可以出现,除了注释
No3
以下程序的预期输出是多少?为什么?
#include<stdio.h>
enum {false,true};
int main()
{
int i=1;
do
{
printf("%d\n",i);
i++;
if(i < 15)
continue;
}while(false);
return 0;
}
代码解释:枚举是 C
语言中的一种基本数据类型,它可以让数据更简洁,更易读。枚举语法定义格式为:enum 枚举名 {枚举元素1,枚举元素2,……}
,如果没有enum {false, true}
,do{}while(false)
将会报错
输出:1 解释:do{}while
语句先执行后做判断
NO4
下面的程序“似乎”不会打印“hello-out”
#include <stdio.h>
#include <unistd.h>
int main()
{
while(1)
{
fprintf(stdout,"hello-out");
fprintf(stderr,"hello-err");
sleep(1);
}
return 0;
}
执行程序,得到下面的结果
hello-out hello-err hello-out hello-err hello-out hello-err 。。。
为什么?我不清楚
NO5
仅通过查看程序,您“可能”会期望输出是相同的,这两个printf语句也是如此
#include <stdio.h>
#define f(a,b) a##b
#define g(a) #a
#define h(a) g(a)
int main()
{
printf("%s\n", h(f(1, 2)));
printf("%s\n", g(f(1, 2)));
return 0;
}
但是实际的输出却是
12
f(1, 2)
解释说明:C语言中,a##b表示将a和b连接起来,#a是将a字符串化。在类似函数的宏中出现的参数(除非它是#或##的操作数)会在替换它并重新扫描整个以进行进一步扩展之前进行扩展。因为g的参数是#的操作数,所以参数不会展开,而是立即被字符串化(“f(1,2)”)。因为h的参数不是#或者##的操作数,所以首先扩展参数(12),然后替换(g(12)),然后重新扫描并进一步扩展(“12”)
NO6
您认为下面程序的输出是什么?为什么?
#include <stdio.h>
int main()
{
float f = 0.0f;
int i;
for(i = 0; i < 10; i++)
f = f + 0.1f;
printf("%f", f);
if(f == 1.0f)
printf("f is 1.0 \n");
else
printf("f is NOT 1.0\n");
return 0;
}
程序输出:1.000000f is NOT 1.0。这是计算机中浮点数机制导致的,浮点数是一个麻烦的Thing
NO7
我认为下面的C程序是完全有效的(在阅读了C中的逗号操作符之后)。
但是下面的程序有错误,你能找出来吗?
#include <stdio.h>
int main()
{
int a = 1, 2;
printf("a : %d\n", a);
return 0;
}
解释说明:int a = 1, 2
会有错误的表示,正确的大概应该是这样子int a, b = 2
NO8
下面的C程序的输出是什么?(它是有效的C程序吗?)
#include <stdio.h>
int main()
{
int i = 43;
printf("%d\n", printf("%d", printf("%d", i)));
return 0;
}
解释说明:首先执行括号最里面的printf("%d", i)
,执行结果是43,此时printf("%d", i)
的值是2,因为printf()函数的返回值是是输出的字符个数,输出"4"和"3"两个字符,所示printf("%d", i)
的值是2,printf("%d", printf("%d", i))
输出的是2,只有"2"这一个字符,所以printf("%d\n", printf("%d", printf("%d", i)))
输出的1
NO9
下面的两个函数原型一样吗?
int foobar(void);
int foobar();
不一样,foobar(void)的参数必须是空(void),foobar()的参数可有可无
NO10
以下程序的输出是什么?为什么?
#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
首先: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芯片下使用是的反字节序,高位字节和低位字位要反过来
所以12.5的双版本表示如下:
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的原因了
NO11
解释以下C程序的输出(输出b不是20)
#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;
}
解释说明:
switch(a)
{
int b = 20; //此语句被跳过不执行
case 1: printf("b is %d\n", b);
break;
default:printf("b is %d\n", b);
break;
}
switch-case语句会跳过switch与case之间的语句
NO12
以下程序的输出是什么?(同样,它不是40(如果整数的大小是4))
#include<stdio.h>
#define SIZE 10
void size(int arr[SIZE])
{
printf("Size of array is:%d\n", sizeof(arr));
}
int main()
{
int arr[SIZE];
size(arr);
return 0;
}
解释说明:C语言下,sizeof的可能大小
short x
sizeof(float) = 4
sizeof(void(*)(void)) = 8
sizeof(char[10]) = 10
sizeof 'a' = 4
sizeof &main = 8
sizeof "hello" = 6
sizeof x = 2
sizeof (x+1) = 4
arr表示数组的首地址,地址的大小就是8
NO13
下面的C程序有什么潜在问题?
#include <stdio.h>
int main()
{
char str[80];
printf("Enter the string:");
scanf("%s", str);
printf("You entered:%s\n", str);
return 0;
}
潜在问题1:输入了超过80个长度的字符,那么就会有数组越界的问题了,程序很有可以会崩溃;潜在问题2:输入的字符串有空格等一些字符,那么程序的只输出空格等这些字符之前的字符,比如Hello World程序输出的是Hello
NO14
下面的程序的输出是什么?
#include <stdio.h>
int main()
{
int i;
i = 10; //i初始化为10
printf("i : %d\n", i); //打印i : 10
printf("sizeof(i++) is: %d\n", sizeof(i++)); //int类型的sizeof为4
printf("i : %d\n", i); //i=10,不是i=11
return 0;
}
解释说明:第三个为什么输出的不是11,而是10呢原因是,sizeof不是一个函数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译时)完全的事情,所以sizeof(i++)直接就被4给取代了,在运行时也就不会有了i++这个表达式