设为首页 加入收藏

TOP

c语言,有时莫名,有时奇妙----小话c语言(25) (一)
2014-11-23 23:39:54 来源: 作者: 【 】 浏览:43
Tags:语言 有时 莫名 奇妙 ---- 小话

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,

首页 上一页 1 2 3 4 下一页 尾页 1/4/4
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇[面试]字符串专题 下一篇 C语言的一些特殊用法(#define)

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: