参考答案:stdout和stderr是不是同设备描述符。stdout是块设备,stderr则不是。对于块设备,只有当下面几种情况下才会被输入,1)遇到回车,2)缓冲区满,3)flush被调用。而stderr则不会。 |
1、 下面的程序并不见得会输出 hello-std-out,你知道为什么吗? #include <stdio.h>#include <unistd.h> int main() { while(1) { fprintf(stdout,"hello-std-out"); fprintf(stderr,"hello-std-err"); sleep(1); } return 0; } |
1、 下面的程序会有什么样的输出呢?
include<stdio.h> intmain() { inti=43; printf("%d\n",printf("%d",printf("%d",i))); return 0;} | 参考答案:程序会输出4321,你知道为什么吗?要知道为什么, 你需要知道printf的返回值是什么。printf返回值是输出的字符个数。 |
#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;} | 参考答案:该程序在编译时,可能会出现一条warning: unreachable code at beginning of switchstatement。 我们以为进入switch后,变量b会被初始化,其实并不然, 因为switch-case语句会把变量b的初始化直接就跳过了。所以,程序会输出一个随机的内存值。 |
下面的两个文件可以编译通过吗?如果可以通过,结果是什么? e:\vcccc\exteron_error\externfile.cpp int arr[10]={12,34,55}; e:\vcccc\exteron_error\mainfile.cpp extern int *arr; char *p=NULL; int main(){ extern int *arr;// extern int arr[]; extern char *p; p=(char *)malloc(12); strcpy(p,"he"); printf("%s\n",p); free(p); p=NULL; printf("hello\n"); printf("arr[1]=%d\n",arr[1]); return; } |
参考答案:该程序可以编译通过,但运行时会出错。为什么呢? 原因是,在另一个文件中用 extern int *arr来外部声明一个数组并不能得到实际的期望值,因为他们的类型并不匹配。 所以导致指针实际并没有指向那个数组。注意:一个指向数组的指针,并不等于一个数组。 修改:externint arr[]。(参考:ISO C语言 6.5.4.2 节) p可以. extern 数组和指针有什么不同. (1)extern char a[]; 分析:这是一个外部变量的声明,它声明了一个名为a的字符数组,编译完成之后也得到一个中间文件,连接器遍历这个文件, (2) extern char * a; 分析:这是一个外部变量的声明,它声明了一个名为a的字符指针,经过一番搜索,找到了一个分配过空间的名为a的地方(也就是我们先定义的那个字符数组),连接器并不知道它们的类型, 仅仅是发现它们的名字一样,就认为应该把extern声明的标号连接到数组a的首地址上, 因此连接器把指针a对应的标号替换为数组a的首地址。这里问题就出现了: 由于在这个文件中声明的a是一个指针变量而不是数组,连接器的行为实际上是把指针a自身的地址定位到了 另一个.c文件中定义的数组首地址之上,而不是我们所希望的把数组的首地址赋予指针a (这很容易理解:指针变量也需要占用空间,如果说把数组的首地址赋给了指针a,那么指针a本身在哪里存放呢?) |
#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;} int a=0010;则a为8,以0开头的是8进制 参考答案:如果你觉得输出分别是,10,4,11,那么你就错了,错在了第三个,第一个是10没有什么问题,第二个是4,也没有什么问题,因为是32位机上一个int有4个字节。但是第三个为什么输出的不是11呢?居然还是10?原因是,sizeof不是一个函数,是一个操作符,其求i++的类型的size,这是一件可以在程序运行前(编译时)完全的事情,所以,sizeof(i++)直接就被4给取代了,在运行时也就不会有了i++这个表达式。 |
3).用 #defines 和 bit masks 操作。这是一个有极高可移植性的方法,是应该被用到的方法。最佳的解决方案如下:
#define BIT3 (0×1<<3)//这个宏定义也是一个考点,程序的可维护性.
staticint a;
void set_bit3(void)
{ a |= BIT3;}
voidclear_bit3(void){ a &= ~BIT3;} 一些人喜欢为设置和清除值而定义一个掩码同时定义一些说明常数,这也是可以接受的。我希望看到几个要点:说明常数、|=和&=~操作。