今天有上课了,王老师与我们分享了一些笔试容易出错的问题,我把它总结出来与大家一起学习。
1. 求下面程序的结果:
点击(此处)折叠或打开
- int
main(void)
{
unsigned short A = 10;
printf("~A = %u\n", ~A);
char c = 128;
printf("c = %d\n", c);
}
运算结果:4294967285(我的机子上,short是16位的) -128
2. 求输出结果:
点击(此处)折叠或打开
- void
GetMemory(char **p, int num)
{
*p = (char *)malloc(num);
}
int
main(void)
{
char *str = NULL;
GetMemory(str, 100);
strcpy(str, "hello");
free(str);
if( str != NULL )
strcpy(str, "world");
printf("str is %s\n", str);}运行结果:str is world
我们紧接着又给str拷贝了world,可能很多人会和我有一样的感觉,就是这是错误的,明明将空间释放掉了,怎么能拷贝到里面呢? 在拷贝world之前,有一条if()语句,判断str是否为NULL,从上面的打印结果可以看到,str并不为NULL,所以会进行下面的拷贝语句。不过,特别要注意,打印出str is world,这完全是一个巧合,因为我们在free与后来的拷贝之间并没有进行新的空间申请,所以,虽然释放了空间,但是我们可以找到地址,在这块内存上进行复制操作。如果我们在free后,又申请了新的空间,刚刚好把这块空间申请了,可能结果就不是我们想要的了。 我们自己平时使用时,一定要避免这种错误。方法是在free()后,将指针置为NULL,这样,由于指针为空,所以对它进行复制操作必然会发生错误。
3. 求下面程序的运行结果:
点击(此处)折叠或打开
- int
main(void)
{
char a[10];
printf("%d\n", strlen(a));
return 0;
}
点击(此处)折叠或打开
- int
main(void)
{
char a[10];
int i;
for(i = 0; i < 10; i)
printf("a[%d]:%d\n", a[i]);
printf("length:%d\n", strlen(a));
return 0;
}
从运行结果可以看到,a数组中存入的值为垃圾值。length()求的是字符串的长度,到'\0'为止的长度。由此可知,strlen(a)的结果为2。2是一个随机值,每个人的机子上运行出来的结果可能都不一样,因为每个人机子上,数组初始化几个元素是不定的。有的人的机子上可能会打印出大于10的值,这是因为strlen()在求值的时候,从数组第一个元素开始查找,找到连续内存中的第一个'\0'停止,即为strlen()的结果。 特别强调一下,如果上述strlen()换为sizeof()的话,结果为10。strlen()与数组的初始化有关,而sizeof()与初始化无关。
4. x = 9999, 求下面函数的返回值
点击(此处)折叠或打开
- int
func(int x)
{
int countx = 0;
while(x)
{
countx ;
x = x (x-1);
}
return countx;
}运行结果:8
5. 求sizeof(A) = ?(32位机)
点击(此处)折叠或打开
- struct A
{
char t:4;
char k:4;
unsigned short i:8;
unsigned long m;
};运行结果:8(gcc编译器,版本为4.6.3)