函数指针: 定义:typedef void (F1)(int p1, int p2) typedef void (*F2)(int p1, int p2) test (int p1, int p2);
F1 * fp1; F2 fp2; F1 fp3; 问: 语句 fp3 = test; fp2 = test; fp1 = test 是否成立? 答案:第一条语句有错,其余两天语句正确。
指针运算: int *p1, *p2; int value;
p1 = (int *)0x500; p2 = (int *) 0x508; value = p2-p1; 问:value的值?
答案:2
定义union,并说明如何使用。如何在union中进行位域的定义?
枚举类型: enum type1 { A, B }; enum type2 { C =1, D, E, F } 问:A,B,D,E,F 的值分别是多少? 答案:0,1,2,3,4 宏定义函数与普通函数调用的区别?
宏定义中若有多行,如何连接 答案:用反斜杠’\’ #define fn_max(x,y) \ do { \ ..... \ ..... \ }while(0)
int main() { fn_max(x,y); } 问:为什么要用do……while(0)把宏定义的多条语句括起来? 答案:便于优化
struct struct_A{ int a; char b; int c; short d; } struct struct_B{ int a; char b; short c; int d; } struct_A a; struct _B b; 问:sizeof(struct_A a) = ? sizeof(struct_A b) = ? 答案:sizeof(a) 为16,sizeof(struct_A b)为12
9. #include main() { char **p; char *m[] = {“Welcome \n”, “to \n”, “join \n”, “us! \n” }; p = m; printf(“%s\n”,*p++); printf(“%c\n”,**p); } 问:写出程序的执行结果 答案:“Welcome”和“t”
10. static局部变量和static全局变量的区别 答案:主要是作用域的不同,static局部变量只在函数内部或者程序块内有效,而static全局变量在整个C文件模块中都有效,注意它在其它C文件中无效。
11. 指向常量的指针和常指针的区别 答案:指向常量的指针所指向的内容不能被修改但能够指向其它的量,而常指针是指向的内容可以被修改但指针不能再指向其它地方。
12. if (a=b) printf(“a==b”) else printf(“a!=b”); 输出结果为: A.a==b B.a!=b C.不一定 D.不能运行 答案:不一定,这要根据b的内容来决定。通常再编程时不要使用此类的赋值语句。
13.在内联函数中使用static变量,比如 inline test() { static couter = 0; counter++; } 会有什么问题? 答案:会造成多次定义该变量,因此再内联函数中禁止定义静态变量
14. F是一个结构类型,有如下定义: F f1,f2; 问:f1=f2;语句是否成立? 答案:该语句成立,不过有的编译器不支持。实际上编译器也是用内存拷贝函数来实现的。
15.全局变量、局部变量、模块变量在内存空间中如何存放?(数据区or栈空间?) 答案:全局变量在全局空间分配,局部变量在栈空间分配,模块变量在全局空间分配。
16.struct A{ ...... ...... union { int x; ..... }; } struct A a; 问:a.x这样的表示法是否成立? 答案:成立
如果结构定义改为如下定义 .struct A{ ...... int x; union { int x; ..... }; } 那a.x表示法是否成立? 答案:不成立,编译时会报x变量重定义
17. #define REDEF(name,arg1,arg...) \ _##name (arg1,##arg) 问:以下两个语句宏展开的结果 REDEF(test_fn1,int a,int b); REDEF(test_fn2,int a); 答案: _test_fn1(int a ,int b) _test_fn2(int a); 注意:在VC中不支持,gcc才支持该参数宏函数。
18. fnxxxx_max(char str[]) { putchar str[0]; str++; //(1) printf(“%s”,str); } main() { char str[20]={“ABCDEFG”}; fnxxxx_max(str); str++; //(2) printf(“%s”,str); } 问:语句(1)和语句(2)是否成立? 答案:语句(1)成立,语句(2)不成立 19.#define SRR 0x001; #define SRT 0x002; #define SRI 0x0900;
EVENT = SRR|SRT|SRI 问:上面的语句有什么问题?EVENT的值会是多少? 答案:宏展开后变为: EVENT = 0x001; 0x002;0x0900; 因此EVENT的值为0x001,所以在编程时一定要小心,一定不要在常量宏定义的后面加上分号。
公司面试题及答案(C语言)2 |
副标题: |
作者:唐僧 文章来源:本站原创 点击数:414 更新时间:2006-1-18 |
|
|
1. #include "stdio.h" int main() { int a; int *p;
p = &a; *p = 0x500; a = (int )(*(&p)); a = (int )(&(*p)); if(a == (int)p) printf("equal !\n"); else printf("not equal !\n"); } 请问本程序的输出显示是什么? 答案:输出显示为”equal!”
2. struct { signed int bit0:1; signed int bit1:1; signed int bit2:1; signed int bit3:1; signed int bit4:1; signed int bit5:1; signed int bit6:1; signed int bit7:1; }bits; 请问sizeof(bits)是否是正确的表达式? 请
问语句bits mybits;
的定义是否正确?如果不正确,要如何修改上述的结构定义才能使该语句正确?修改后的结构定义是否会影响sizeof(bits)的正确性?如果正确则该表
达式的值为多少?如果将上述的结构中int类型改为char类型,此时sizeof(bits)的大小为多少? 答案:1)是正确的表达式,因为sizeof后面的内容可以是类型,也可以是变量。 2)该语句的定义不正确,因为此时的bits为一个变量;应该这样修改结构的定义 typedef struct { signed int bit0:1; signed int bit1:1; signed int bit2:1; signed int bit3:1; signed int bit4:1; signed int bit5:1; signed int bit6:1; signed int bit7:1; }bits; 修改后sizeof(bits)表达式依然正确,其值为4;类型改为char后其值为1,注意该值是在VC环境中的32位程序中得到的值,在不同的编译器其值有可能不同,因此在编程时不能自己假定类似结构的大小。 3. struct bit{ unsigned int a[0]:1,a[1]:1,a[2]:1….a[7]:1; } 请问这种写法是否正确?为什么? 答案:不正确,位域中的变量不能是数组。
4. struct a { int x; char y; struct a z; struct a *p; } 请问这种定义结构正确否? 如果有问题,问题在哪里? 答案:结构中不能对定义结构本身的非指针变量,如果编译器支持则会导致无限嵌套,因此一般编译器都会认为struct a是未定义的类型,即使提前声明也不会有任何用处。
5. 什么是可重入函数?C语言中写可重入函数,应注意的事项? 答案:可重入函数是指能够被多个线程“同时”调用的函数,并且能保证函数结果的正确性的函数。在编写可重入函数时通常要注意如下的一些问题: 尽量不要使用全局变量,静态变量,如果使用了应该注意对变量访问的互斥。通常可以根据具体的情况采用:信号量机制,关调度机制,关中断机制等方式来保证函数的可重入性。 不要调用不可重入的函数,调用了不可重入的函数会使该函数也变为不可重入的函数。 注意对系统中的临界资源,互斥资源的访问方式,防止使函数成为不可重入的函数。 一般驱动程序都是不可重入的函数,因此在编写驱动程序时一定要注意重入的问题。
6. 简述stack frame 的含义。 答案:stack frame的中文译名为:栈框架,表示函数在栈空间的调用层次,以x86平台的函数调用为例,通常一个函数编译成汇编程序,都有如下的结构:
其中的leave指令相当于:mov ebp,esp ;pop ebp
各个函数在栈空间的映象为:
test1函数
test2函数
test3函数
因此在函数test3中,就可以根据这种栈框架的形式得到函数调用层次上的每个函数的基址指针,当前栈指针,以及函数调用点等信息。
7. printf (“%d%d\n”,++n, power(2,n)); 其中power(2,n)为实现一定功能的函数 如 2^n 。 请问这种表示方法有什么潜在的问题? 答案:编译器的不同,对++n 和power(2,n)处理的先后顺序不一样,形成二义性,造成程 序的移植性差,因此最好把++n 写在printf函数外面,以消除二义性。
printf (s); 请问这样的语句有没有问题?(s为一指向有效字符串的指针) 答案:没有%的话,可以这样表达,如果有%在s中的话,有意想不到的输出结果。
9. 两段代码共存于一个文件,编译时有选择的编译其中的一部分,请问如何实现? 答案:有两种简单的办法可以实现: 在源码中使用条件编译语句,然后在程序文件中定义宏的形式来选择需 要的编译代码。 在源码中使用条件编译语句,然后在编译命令的命令中加入宏定义命令 来实现选择编译。 10.数据结构指针传给函数,函数能访问数据单元,但不能修改实际的内容,如何实现? 答案:定义为指向常量的指针,这样指针所指的数据结构中的内容就不会被改变。如: const 类型 *p 或 类型 const *p
11. 在头文件中定义静态变量,可能产生什么问题? 答案:在使用了该头文件的每个c程序文件中都单独存在一个该静态变量,这样造成空间的浪费并且很容易引起错误。因此建议不要在头文件中定义任何变量。
12.malloc()与 calloc()的区别? 答案: 1)参数上的区别 malloc (size_t size); calloc (size_t n , size_t size); malloc分配一块size大小的内存块,而calloc分配一个n*size大小的内存块 2)返回内存块的状态不同 malloc分配的内存块没有被清零,而calloc分配的内存块是清了零的。但是建议在使用内存时,如果需要初始化,则最好自己按照需要来进行初试化,不要依赖函数的实现说明。
13.寄存器变量可不可以访问其地址?可否是全局变量?在什么场合使用寄存器变量? 答案:这些问题都与编译器的实现有关,建议不要声明全局变量为寄存器变量,即使是局部变量都最好不要声明其为寄存器变量,现在的编译器在优化时都会较为合理的安排寄存器变量的使用,而人为的安排有时会造成优化的低效。 14."\n" '\n' 的区别? 答案:前者是一个字符串并且以’/0’结束,而后者只是一个简单的字符。
15.包含预定义头文件< > 和" "的区别? 答案:< >只在指定的目录里寻找被包含文件;" "先在当前目录下查找 ,再在指定目录下查找;通常<>方式用于系统的头文件,而一般用户的头文件用" "的方式。
16.strunt S_A{ int a[10]; }; void f() { int i; strunt S_A *s_ptr; for (i=0,i<10,i++) s_ptr -> a[i] = i; } 请问这段代码正确否? 答案:这段代码不正确,没有对s_ptr指针进行初始化,在编程中要注意此类低级错误的发生。 |
|