Q1: 为什么下面的输出不按照代码的顺序显示?
[cpp]
#include
#include
int main(int argc, char **argv)
{
while(1)
{
fprintf(stdout, "stdout.");
fprintf(stderr, "stderr.");
sleep(1);
}
return 0;
}
#include
#include
int main(int argc, char **argv)
{
while(1)
{
fprintf(stdout, "stdout.");
fprintf(stderr, "stderr.");
sleep(1);
}
return 0;
}
A: 如果把代码改为如下,输出就按照代码顺序显示了:
[cpp]
#include
#include
int main(int argc, char **argv)
{
setbuf(stdout, NULL); // set stdout to no buffer
while(1)
{
fprintf(stdout, "stdout.");
fprintf(stderr, "stderr.");
sleep(1);
}
return 0;
}
#include
#include
int main(int argc, char **argv)
{
setbuf(stdout, NULL); // set stdout to no buffer
while(1)
{
fprintf(stdout, "stdout.");
fprintf(stderr, "stderr.");
sleep(1);
}
return 0;
}
Q2: 下面的代码中printf函数返回为什么不是1?
[cpp]
#include
#define PRINT_D(intValue) printf(#intValue" is %d\n", (intValue));
int main(int argc, char **argv)
{
char *str = "我";
PRINT_D(printf(str));
return 0;
}
#include
#define PRINT_D(intValue) printf(#intValue" is %d\n", (intValue));
int main(int argc, char **argv)
{
char *str = "我";
PRINT_D(printf(str));
return 0;
}
上面的代码保存的编码为UTF-8.
A: 在我的另一篇帖子中已经有详细解释: http://blog.csdn.net/cxsjabcabc/article/details/7528227
如果把代码文件的编码改为其它,答案就出来了: printf返回的是实际输出的字节数。
Q3: 下面代码的输出为什么改变了b的数值?
[cpp]
#include
#define PRINT_D(intValue) printf(#intValue" is %d\n", (intValue));
int main(int argc, char **argv)
{
int a = 1;
switch(a)
{
int b = 2;
case 1:
PRINT_D(b)
break;
default:
PRINT_D(b)
break;
}
return 0;
}
#include
#define PRINT_D(intValue) printf(#intValue" is %d\n", (intValue));
int main(int argc, char **argv)
{
int a = 1;
switch(a)
{
int b = 2;
case 1:
PRINT_D(b)
break;
default:
PRINT_D(b)
break;
}
return 0;
}
A: 原因在于c标准规定:switch语句体的复合语句中,位于第一个case或者default标号前面的语句永远不会被执行到。所以,b相当于没有初始化。
另外,我们查看一下汇编,能够得到结论,其实case标号和default标号相当于一个地址,编译器内部会使用jmp, je, jne等语句直接跳到对应位置来执行,而不会分析它前面的初始化过程。
[cpp]
0x00001f10 : push %ebp
0x00001f11 : mov %esp,%ebp
0x00001f13 : sub $0x28,%esp
0x00001f16 : mov 0xc(%ebp),%eax
0x00001f19 : mov 0x8(%ebp),%ecx
0x00001f1c : movl $0x0,-0x4(%ebp)
0x00001f23 : mov %ecx,-0x8(%ebp)
0x00001f26 : mov %eax,-0xc(%ebp)
0x00001f29 : movl $0x1,-0x10(%ebp)
0x00001f30 : xor %dl,%dl
0x00001f32 : test %dl,%dl
0x00001f34 : jne 0x1f52
0x00001f36 : jmp 0x1f38
0x00001f38 : lea 0x1fa0,%eax
0x00001f3e : mov -0x14(%ebp),%ecx
0x00001f41 : mov %eax,(%esp)
0x00001f44 : mov %ecx,0x4(%esp)
0x00001f48 : call 0x1f7a
0x00001f4d : mov %eax,-0x18(%ebp)
0x00001f50 : jmp 0x1f6a
0x00001f52 : lea 0x1fa0,%eax
0x00001f58 : mov -0x14(%ebp),%ecx
0x00001f5b : mov %eax,(%esp)
0x00001f5e : mov %ecx,0x4(%esp)
0x00001f62 : call 0x1f7a
0x00001f67 : mov %eax,-0x1c(%ebp)
0x00001f6a : mov $0x0,