分类: C/C++
2008-09-26 18:49:27
1. 假设有数组int numbers[] = {1, 2, 3, 4, 5};下面哪个选项能正确求出数组元素的个数(数组长度):
A. sizeof(int)
B. sizeof(numbers)
C. sizeof(numbers)/sizeof(int)
D. numbers.length
C(A,4B,20,C5,D,length是structure和union的函数)
2. 考虑下面的程序片断
char * name;
printf(“what is your name?”);
scanf(“%s”, name);
printf(“%s”, name);
如果执行此程序,在键盘上输入Zhang San,那么运行结果是什么?
A. ZhangSan
B. Zhang
C. San
D. 无输出
D(段错误),指针name没有赋值,不知道指哪了
3. 考虑下面的程序片断
int a = 2147483647; // biggest int
a++;
printf(“%d”, a);
运行结果如何?
A. 2147483648
B. 0
C. -2147483648
D. 编译未通过
C(10000000000000.。。)
4. 认真观察下面的程序:
#include
int main(void) {
float n1 = 3.0;
double n2 = 3.0;
long n3 = 2000000000;
long n4 = 1234567890;
printf(“%ld %ld %ld %ld\n”, n1, n2, n3, n4);
return 0;
}
这个程序运行能不能打印出四个数中至少一个正确的值?如果不能,写出可能的值(不确定的垃圾值用* 表示),并说明理由:
int:4
long:4
float:4
,double8
一个也不能
0 ,1074266112 ,0, 1074266112
5. 考虑下面的代码片断:
int a = 11;
int b = (++a) * 11 + (++a) * 10;
运行这段程序后,b的值是多少?
A. 12 * 11 + 13 * 10;
B. 13 * 11 + 12 * 10;
C. 11 * 11 + 11 * 10;
D. 运行结果随编译器和硬件不确定
D(乘法在加法前面算,编译器决定先算哪个)
5. 考虑下面的程序片断:
char ch;
while((ch = getchar()) != '\n') {
printf("%c", ch);
}
如果运行这段程序,用户在键盘上输入一个字符之后,会有什么反映,用户是否有机会第二次输入字符? 说明原因,以及解决方案.
:不会有反应,数据都存缓冲区里了,直到碰到‘\n’再开始读取。
设置为无缓冲区
6. 考虑以下程序片断:
char str1[] = “hello”;
char * str2 = “hello”;
printf(“%p\n%p”, str1, str2);
运行这段代码,打印出的两个字符串的地址是否一样?如果不一样,说明两种定义字符串的机制的不同 和性能有何不同.
不一样,*str2,常量区,str1先在栈里
7. 考虑以下程序片断:
char str1[] = {‘h’, ‘e’, ‘l’, ‘l’, ‘o’, ‘\
printf(“%s”, str1);
运行这段代码,结果是什么?
hello
8. 考虑以下代码片断:
int a = 10;
int c[] = {1, 2, 3, 4, 5};
int b = 20;
c[5] = 100;
运行这段程序,会不会产生编译错误,如果没有错误,可能产生什么样的结果?
不会,c5超越边界,出现不确定性
9. 考虑以下代码片断:
char * str = “zhangsan”;
str++;
printf(“%s”, str);
运行以下这段代码,运行结果是什么?
Hangsan
10. 考虑以下代码片断:
const int a = 10;
int * p = &a;
*p = 11;
这段代码会不会通过编译,由此解释const真正的含义.
Const 是建议,c里可以改,在c++中不能这样,const真正的含义是只读
11. 考虑以下代码:
char str[] = “zhangsan”;
str++;
printf(“%s”, str);
这段代码能否通过编译,由此解释数组名真正的含义.
不能,数组名是一个地址常量,不能++,指向该数组的首地址,str是个右值
12. 考虑以下各个数组大小的指定,判断哪些是正确的,哪些是错误的(以C99之前的标准判断),由此猜想C 编译器在编译的时候是如何处理数组的.
#define SIZE 10
int main(void) {
int m = 10;
float a1[5];
float a2[5*2 + 1];
float a3[sizeof(int) + 1];
float a4[-4];
float a5[0];
float a6[3.5];
float a7[(int)2.5];
float a8[m];
float a9[SIZE];
}
正确: a1; a2,a3,,a5,a7,a9
后面必须是常量,编译的时候就会确定大小,而编译的时候不会关系m的值的。
C99之后可以,a8
13. 考虑以下代码:
int a[][] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
int **p = a;
printf(“%d”, *((*p)+1)+1);
运行这段代码,结果是什么?
??6/1
14. 把数组名传送给一个函数,函数内部修改数组的元素值,实参数组是否会真正改变?
会,传的地址
15. 考虑以下代码:
int a[] = {1, 2, 3, 4};
int * p = &a;
printf(“%d\%d”, sizeof(a), sizeof(p));
运行代码,结果是什么?
16,4
16. 试说明*和++运算符的优先级,并设计程序验证.
++高与*
Main()
{
Int a[]={1,10};
Int *p=a;
Printf(“%d\n”,*p++);
Printf(“%d\n”,(*p)++);
}
17. 考虑如下代码:
int * p1,* p2;
说明p1 - p2的含义.
地址差
18. 视图说明puts和fputs以及gets和fgets函数的区别,它们的为什么会有这种区别.
Puts不会检测输入字串的大小,如果比缓冲区大,就会溢出,fputs会检测,如果比缓冲区大,截断
19. 说明下面的代码有什么问题:
char * name;
scanf(“%s”, name);
可能会段错误,name不知指向何处
20. 假设有两个源文件a.c和b.c有一个头文件d.h,现在如果在头文件中声明一个static的变量,那么此变量 是不是会被两个文件共享,这与static的语义是否矛盾.
都可以用,但各不相干,没矛盾;
21. 试说明register, restrict, volatile关键字的含义
Restrict:建议只能通过某个指针访问
Register:建议把变量存到寄存器里,意思是说,不会通过其他地方改变该值
Volatile:易变的告诉编译器不要去优化它
22. 分别自定义一个结构体,联合,说明它们各自的作用和区别.
Struct student{
Char id[10];
Char name[10];
}
相当于自己定义了一个类型的变量,他可以存放一组数据
23. 假设有下面两句语句:
typedef char * STRING;
#define STRING char *
这样两个定义是否完全等价,如果不是,举一个例子来说明它们的不同.
24. 说明以下语句的含义:
char * fump();
char (* frump)();
char(* flump[3])();
1、函数
2、函数指针
3、函数指针数组
25. 说明以下typedef语句的含义:
typedef char (* FRPTC())[5];
以后可以直接谢 FRPTC来代表这这些东西了
26. 考虑以下代码
typedef int arr5[5];
typedef arr5 * p_arr5;
typedef p_arr5 arrp10[10];
arr5 togs;
p_arr5 p2;
arrp10 ap;
现分别说明togs, p2, ap代表的数据类型.
Tops 含有5个元素的int数组
P2 指向 tops的地址
Ap
27. 有人说用预编译器拼凑C代码相当于用JSP拼凑JavaScript代码,这样说合适么?
合适,
28. 说明下面代码的含义:
struct {
unsigned int field1: 1;
unsigned int : 2;
unsigned int field2: 1;
unsigned int : 0;
unsigned int filed3: 1;
} stuff;
位字段
29. 定义一个求完全平方的宏:
#define SQUARE(X) X*X
说明这个宏有什么潜在的问题.
宏只是简单的复制,比如令x=4+5,问题就出现了
30. 利用自己所学的知识实现strcpy(const char * str1, char * str2)字符串赋值函数.
31. 论证,printf函数为什么能够接收任意多个参数.
他有个参数栈,参数从右向左读入栈(并且计算表达式),然后一次从栈中读出