读书人

出了几道C语言的题视察各位内功邀

发布时间: 2012-08-11 20:50:31 作者: rapoo

出了几道C语言的题,考查各位内功,邀请各位一做
1. 有以下程序片段:
int a[] = { 1, 2 };
int *p = a;
问:
当sizeof(int) = 4时,
sizeof(a)=?
sizeof(p)=?
分别为什么?

2. 以下循环是死循环吗?
for (int i = 1; i > 0; i++)
printf("%d\n", i);
为什么?
3. 有以下程序片段:
int a[] = { 1, 2 };
int i = 5;
printf("%d\n", a[-1]);
输出结果可能是什么?
4. 有以下程序片段:
int i = 5;
int a[] = { 1, 2 };
printf("%d\n", a[3]);
输出结果可能是什么?
5. 有以下程序片段:
int array[ARRAY_SIZE];
int *pi;

for (pi = &array[0]; pi < &array[ARRAY_SIZE];)
*++pi = 0;
(1)修改for (pi = &array[0]; pi < &array[ARRAY_SIZE];)这一行,改为等价程序。
(2)谈谈这个程序可能运行结果。
(3)小明说这个程序如果后来pi被设置为空指针的话,会导致死循环,还会破坏N多数据。你同意小明的观点吗?如果之后pi真的变成空指针的话,那一般在Windows/Linux下这个程序会是死循环吗?不是的话会发生什么?
6. 有一个函数如下:
char *strcpy(char *dest, const char *src)
{
char *temp = dest;

if (dest == src)
return dest;
if (dest == NULL || src == NULL)
return NULL;
while (*dest++ = *src++)
;
return temp;
}
小明说如果把if (dest == NULL || src == NULL) return NULL;改为if (dest != NULL || src != NULL)就可以巧妙地利用顺序结构的特点简化掉一个return NULL;,你同意他的做法吗?
7. 有这样一个程序:
#include <stdio.h>
void foo (void)
{
int i;
printf("%d\n", i);
i = 999;
}
int main (void)
{
foo();
foo();
return 0;
}
运行结果可能为什么?为什么?在foo();之间加个printf("hello\n");呢?
8. 某人为了给学生讲讲什么是指针写了如下程序:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[5] = { 1, 2, 3, 4, 5 };
unsigned int p;
}
程序还没写完,请把p当作指针用它来遍历数组a,输出数组a的所有元素。
写完后思考一下,不用unsigned int用int行不行?为什么?

[解决办法]
1. 有以下程序片段:
int a[] = { 1, 2 };
int *p = a;
问:
当sizeof(int) = 4时,
sizeof(a)=? 8,数组嘛,数组个数乘以每个元素大小
sizeof(p)=? 4,所有指针都是4
分别为什么?

2. 以下循环是死循环吗?
for (int i = 1; i > 0; i++)
printf("%d\n", i);
为什么?
理论上不会死循环,因为到了i到了2147483647的时候,再+1会变成-2147483648,就会结束循环,但是估计好几天之后才能运行到那个时候
3. 有以下程序片段:
int a[] = { 1, 2 };
int i = 5;
printf("%d\n", a[-1]);
输出结果可能是什么?
正常编译器的话,会输出i的值,原因是栈区数据,既然是栈那么定义a变量之后,再定义i,根据栈的特性,会放到a的前面,a[-1]表示的就是i,虽然越界很危险,但是确实windows,linux都会输出i的值5
4. 有以下程序片段:
int i = 5;
int a[] = { 1, 2 };
printf("%d\n", a[3]);
输出结果可能是什么?
同问题3,还是局部栈的原因,但是不一定会输出5,有个关于数组内存对齐情况在内,VC和linux的GCC应该输出5,别的编译器不一定
5. 有以下程序片段:
int array[ARRAY_SIZE];
int *pi;

for (pi = &array[0]; pi < &array[ARRAY_SIZE];)
*++pi = 0;
(1)修改for (pi = &array[0]; pi < &array[ARRAY_SIZE];)这一行,改为等价程序。
for (pi = &array[0]; pi < &array[ARRAY_SIZE];*++pi = 0;) 这样?
(2)谈谈这个程序可能运行结果。
第一个元素没有成功初始化为0,程序会出现越界问题。。原因是:运行到最后一步,pi=&array[ARRAY_SIZE-1] , 运行*++pi=0会越界
(3)小明说这个程序如果后来pi被设置为空指针的话,会导致死循环,还会破坏N多数据。你同意小明的观点吗?如果之后pi真的变成空指针的话,那一般在Windows/Linux下这个程序会是死循环吗?不是的话会发生什么?
windows/linux如果pi成了0,会出现段错误,程序直接跳出,不会死循环破坏N多数据
6. 有一个函数如下:
char *strcpy(char *dest, const char *src)
{
char *temp = dest;

if (dest == src)
return dest;
if (dest == NULL || src == NULL)
return NULL;
while (*dest++ = *src++)
;
return temp;
}
小明说如果把if (dest == NULL || src == NULL) return NULL;改为if (dest != NULL || src != NULL)就可以巧妙地利用顺序结构的特点简化掉一个return NULL;,你同意他的做法吗?
if (dest != NULL && src != NULL) 至少在windows里边,这个应该能行得通
7. 有这样一个程序:
#include <stdio.h>
void foo (void)
{
int i;
printf("%d\n", i);
i = 999;
}
int main (void)


{
foo();
foo();
return 0;
}
运行结果可能为什么?为什么?在foo();之间加个printf("hello\n");呢?
第一次不可预知(如果在VC里的话,应该是0xcccccccc的10进制形式-858993460),第二次输出999;如果之间加个hello,第二次不一定(VC里可能是6,linux里应该还是999),依赖编译器
8. 某人为了给学生讲讲什么是指针写了如下程序:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[5] = { 1, 2, 3, 4, 5 };
unsigned int p;
}
程序还没写完,请把p当作指针用它来遍历数组a,输出数组a的所有元素。
写完后思考一下,不用unsigned int用int行不行?为什么?

C/C++ code
int main(int argc, char *argv[]){    int a[5] = { 1, 2, 3, 4, 5 };    unsigned int p;    p = (unsigned int)a;    for( int i = 0; i < 5; ++i )    {        printf( "%d,", ((int*)p)[i] );  //*(int*)(p+i*sizeof(unsigned int))    }    return 0;}
[解决办法]
探讨
1. 有以下程序片段:
int a[] = { 1, 2 };
int *p = a;
问:
当sizeof(int) = 4时,
sizeof(a)=?
sizeof(p)=?
分别为什么?sizeof()函数的只计算类型a的类型是一个数组所以是数组的大小,p的类型是一个int型指针所以是4

2. 以下循环是死循环吗?
for (int i = 1; i > 0; i++)
printf("%d\n", i);
为什么?必须死循环,不解释
3. 有以下程序片段:
int a[] = { 1, 2 };
int i = 5;
printf("%d\n", a[-1]);
输出结果可能是什么?越界访问,鬼知道是什么什么都有可能取决于那块地址存的什么玩意

4. 有以下程序片段:
int i = 5;
int a[] = { 1, 2 };
printf("%d\n", a[3]);
输出结果可能是什么?永远不要寻找这种未定义行为的结果,没意义!!!
5. 有以下程序片段:
int array[ARRAY_SIZE];
int *pi;

for (pi = &array[0]; pi < &array[ARRAY_SIZE];)
*++pi = 0;
(1)修改for (pi = &array[0]; pi < &array[ARRAY_SIZE];)这一行,改为等价程序。
(2)谈谈这个程序可能运行结果。
for(pi = array; pi < array+ARRAY_SIZE; pi++)
(3)小明说这个程序如果后来pi被设置为空指针的话,会导致死循环,还会破坏N多数据。你同意小明的观点吗?如果之后pi真的变成空指针的话,那一般在Windows/Linux下这个程序会是死循环吗?不是的话会发生什么?
6. 有一个函数如下:
char *strcpy(char *dest, const char *src)
{
char *temp = dest;

if (dest == src)
return dest;
if (dest == NULL || src == NULL)
return NULL;
while (*dest++ = *src++)
;
return temp;
}
小明说如果把if (dest == NULL || src == NULL) return NULL;改为if (dest != NULL || src != NULL)就可以巧妙地利用顺序结构的特点简化掉一个return NULL;,你同意他的做法吗?
7. 有这样一个程序:
#include <stdio.h>
void foo (void)
{
int i;
printf("%d\n", i);
i = 999;
}
int main (void)
{
foo();
foo();
return 0;
}
运行结果可能为什么?为什么?在foo();之间加个printf("hello\n");呢?
又是未定义行为,i是一个局部变量怎么复制除了大括号就没有了!!
8. 某人为了给学生讲讲什么是指针写了如下程序:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[5] = { 1, 2, 3, 4, 5 };
unsigned int p;
}
程序还没写完,请把p当作指针用它来遍历数组a,输出数组a的所有元素。
写完后思考一下,不用unsigned int用int行不行?为什么?
这个没什么意思吧

[解决办法]
8. 某人为了给学生讲讲什么是指针写了如下程序:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[5] = { 1, 2, 3, 4, 5 };
unsigned int p;
}
程序还没写完,请把p当作指针用它来遍历数组a,输出数组a的所有元素。
写完后思考一下,不用unsigned int用int行不行?为什么?

C/C++ code
#include <stdio.h>int main(int argc, char *argv[]){    int a[5] = { 1, 2, 3, 4, 5 };    unsigned int p;     p = (unsigned int)a;    while((int*)p < &a[5]){        printf("%d\n", *(int *)p);            p = p + sizeof(int);    }        return 0;     } 

读书人网 >C语言

热点推荐