c语言常见笔试题总结(13类+包括答案)

时间:2024.4.5

【1 使用宏】

1.1

#ifdef NDEBUG

#define TRACE(S) S

#else

#define TRACE(S) printf(”%s;\n”, #S); S

#endif

问:以上TRACE()宏的作用是什么?

1.2 #error的作用?

1.3 定义一个宏,求出给定数组中的元素的个数

#define NELEMENTS(array) ??

1.4 定义一个宏,求出给定结构中给定成员的偏移量

#define OFFSET(structure, member) ??

【2 数据声明和定义】

给定以下类型的变量a的定义式:

a) An integer

b) A pointer to an integer

c) A pointer to a pointer to an integer

d) An array of 10 integers

e) An array of 10 pointers to integers

f) A pointer to an array of 10 integers

g) A pointer to a function that takes an integer as an argument and returns an integer

h) An array of ten pointers to functions that take an integer argument and return an integer

【3 复杂类型(1)】

有如下表达式:

char (*(*x())[])();

请用文字描述x是什么。

【4 复杂类型(2)】

jmp_buf的定义:

typedef struct _jmp_buf

{

REG_SET reg;

int extra[3];

} jmp_buf[1];

setjmp函数的原型:

extern int setjmp (jmp_buf __env);

问:调用setjmp时传递__env的内容,还是传递指针?

【5 头文件】

问:为什么标准头文件都有类似以下的结构?

#ifndef __INCvxWorksh

#define __INCvxWorksh

#ifdef __cplusplus

extern “C” {

#endif

/*…*/

#ifdef __cplusplus

}

#endif

#endif /* __INCvxWorksh */

【6 static关键字】

请说出static关键字的3种用处:

(1)用于全局变量;

(2)用于局部变量;

(3)用于函数。

/* file.c */

static int a;

int b;

static int fn()

{

static int x;

int y;

}

【7 const关键字】

7.1 const关键字的意义是什么?

7.2 解释以下的变量定义:

const int a1;

int const a2;

const int *a3;

int * const a4;

int const * const a5;

【8 volatile关键字】

8.1 volatile意义?例如

volatile int *p;

8.2 volatile能和const一起使用吗?例如 volatile const int *p;

【9 sizeof()】

有以下定义:

char *pmsg = “A”;

char msg[] = “A”;

char ch = ?A?;

问:

sizeof(pmsg) = ?

sizeof(msg) = ?

sizeof(“A”) = ?

sizeof(ch) = ?

sizeof(?A?) = ? (在C++中等于多少?)

void f(char param[100])

{

// sizeof(param) = ?

}

【10 字符串】

有以下代码

char *pmsg = “hello, world!”;

strcpy(pmsg, “hi, there.”);

试评论该代码。

【11 混合运算】

有以下代码:

void foo()

{

unsigned int a = 6;

int b = -20;

(a+b > 6) ? puts(”大于 6″) : puts(” 小于或等于6″);

}

请问调用foo()的输出

【12 内存访问】

有以下代码:

void fn()

{

int a[100];

int *p;

p = (int *)((unsigned int)a + 1);

printf(“p=0x%x\n”, *p);

}

试评论以上代码。

【13 C库函数】

请说明以下函数的意义:

void perror(const char *__s);

fdprintf(int, const char *, …);

isspace(), isxdigit(), strerr(), sprintf()

答案,仅供参考:

1.1 这道题主要考察#的功能,S是一个表达式。TRACE()的作用就是在DEBUG状态下,计算表达式S的值之前先打印S。

1.2 #error用于向编译器报错,并输出它后面带的错误信息。例如:

#ifndef SOMETHING

#error SOMETHING not defined!

#endif

如果在这段代码之前未定义过SOMETHING,则在编译时出错,并给出”SOMETHING not defined!”的错误信息。

1.3 #define NELEMENTS(array) (sizeof(array) / sizeof((array)[0]))

1.4 #define OFFSET(structure, member) ((int) &(((structure *)0)->member)) 2 (a) An integer:int a;

(b) A pointer to an integer:int *a;

(c) A pointer to a pointer to an integer:int **a;

(d) An array of 10 integers:int a[10];

(e) An array of 10 pointers to integers:int *a[10];

(f) A pointer to an array of 10 integers:int (*a)[10];

(g) A pointer to a function that takes an integer as an argument and returns an integer:int (*a)(int);

(h) An array of 10 pointers to functions that take an integer argument and return an integer:int (*a[10])(int);

3 char (*(*x())[])();

这道题来自”The C Programming Language”中的一个例子。

首先,确定标识符:x

x是一个函数,没有参数:x()

返回值是一个指针:*x()

这个指针指向一个数组:(*x())[]

数组中的每个元素是指针:*(*x())[]

指向一个不带参数的函数:(*(*x())[])()

函数的返回值是char:char (*(*x())[])()

这里,要知道*、()和[]的优先级。

4 这个定义有点怪,它的意思是:jmp_buf这种类型是一个数组,只有一个元素,元素类型为struct{…}。数组名作为函数参数时,应该是传递地址/指针。

5 在编译源文件时,C编译器和C++编译器都会对符号(函数或变量)名作某些修正,但两者采用的修正方法不同,所以两者生成的目标文件不能互相链接。在C++中使用extern “C”可以让C++符号获得C链接特性。由于C++编译器会自动定义__cplusplus宏,所以在C语言头文件中采用这种结构可以保证无论使用何种编译器,生成的目标文件都具有C链接特性,能够与标准C编译器所生成的目标文件相链接。

6 (1)用于全局变量:外部静态变量,只能在本源文件中被引用,不能被其它源文件所引用。

(2)用于局部变量:局部静态变量,在函数返回后存储单元不释放;下一次调用该函数时,该变量为上次函数返回时的值。

(3)用于函数:内部函数,只能被本源文件中的函数所调用,不能被其它源文件调用。

7.1 const关键字在C语言中用于声明”常变量”,其值不可修改,但具有确定的数据类型。C编译器总是为其分配相应的存储单元。

在C++中,const关键字用于声明常量,C++编译器视具体情况决定是为其分配存储单元还是仅将其作为编译期间的常量。

7.2 const int a1; a1是整型常量。

int const a2; a2是整型常量。等同于const int a2;

const int *a3; a3是指针(a3是可变的),指向一个整型常量。等同于int const *a3; int * const a4; a4是常量指针(a4不可变),指向一个整型变量。

int const * const a5; a5是常量指针(a5不可变),指向一个整型常量。等同于const int * const a5;

8.1 volatile关键字用于声明内存映射的易失型变量,这类变量的值随时可能由于某种编译器所不知道的原因(例如,外部设备对其写入)所改变,所以编译器在进行代码优化时不能对其做任何的假设和依赖。

8.2 volatile可以和const一起使用,不过很少见。

const关键字的意思是限制编程者自己不能修改变量的值;两者并不矛盾。

例如一个内存映射的、只读的硬件寄存器,假设它的地址是p,则可以这样声明:volatile const UINT32 *p;

9 sizeof(pmsg) = 指针变量的长度

sizeof(msg) = 2 (字符数组的长度)

sizeof(”A”) = 2 (字符串的长度)

sizeof(ch) = 1 (字符变量的长度)

sizeof(?A?) = 整型变量的长度 (在C语言中,字符常量的数据类型实际上是int;在C++中,它的数据类型是char,从而原式等于1)

sizeof(param) = 指针变量的长度 (数组名作参数时,传递的是数组的起始地址)

10 这种写法是和编译器&操作系统相关的,所以不应当这样写。在WIN2K+VC环境下debug程序时会出现异常。

不过这样写,编译器不会报错。按道理,”hello…”的类型是const char [N],它是不能赋值给char *的,

因为会丢失常量属性。但在const关键字成为C标准之前,大家都这样写程序,所以char *pmsg = “hello…”

这种写法被给予特别豁免,即使在C++中也是如此,在”The C++ Programming Language”的附录里对此有讨论。

“hello, world!”是字符串常量(string literal),它的类型是const char [N],N为字符串的长度(包括结尾的0)。

“The C Programming Language”指出,写字符串常量的结果是未定义的(undefined)。所以在有些平台(操作系统+编译器)

上程序不会出错,而在其它平台上程序出现异常。

GNU手册里这样说:

Writing into string constants is a very bad idea; “constants” should be constant.

不过在GNU中它提供另外的选择:使用-fwritable-strings进行编译就可以。

那么,为什么不允许修改字符串常量呢(它不也在内存中吗)?

这可能和另外一个特点有关,即重复字符串的合并。现在的编译器应该会主动帮助我们合并程序中相同的字符串常量

以节省内存。如果string literal可写,就会出现问题。例如:

void foo()

{

printf(”%s\n”, “how are you?”);

}

void bar()

{

char *p = “how are you?”;

strcpy(p, “WHO ARE YOU?”);

}

调用foo()当然会打印”how are you”。但如果编译器合并字符串,那么先调用bar(),再调用foo(),foo()打印的就是

“WHO ARE YOU?”。这当然不是我们想要的结果。

另外一方面,这样写也有问题(确实有人这么写):

if (func() == “something”)

func()是:

char *func()

{

return “something”;

}

这就假设编译器一定会帮我们合并字符串,然而那也不一定。

11 输出”> 6″。

混合运算时的数据类型转换次序:int –> unsigned –> long –> double。

另外,char和short必定转换为int,float必定转换为double。

12 p = (int *)((unsigned int)a + 1);

代码的意图是想使p指向数组的第二个元素,但通常的写法是:p=a+1。这里存在这样的问题:a是个常量地址,

a+1指向下一个数组元素,而((unsigned int)a + 1)指向下一个内存地址。如果地址是字节计数的,则p指向的

是数组第一个元素的第二个字节。还有一个效果就是:在RISC上该printf语句会出异常,因为不允许非对齐访问

(mis-aligned access)。对齐访问就是访问2字节变量的地址要能被2整除,4字节变量的地址要能被4整除,etc。

13 这些函数到处都查得到,就不用做了吧.

1.1

#ifdef NDEBUG

#define TRACE(S) S

#else

#define TRACE(S) printf("%s;\n", #S); S

#endif 问:以上TRACE()宏的作用是什么?

答:这道题主要考察#的功能,S是一个表达式。TRACE()的作用就是在DEBUG状态下,计算表达式S的值之前先打印S。

1.2 #error的作用?

答:#error用于向编译器报错,并输出它后面带的错误信息。例如:

#ifndef SOMETHING

#error SOMETHING not defined!

#endif

如果在这段代码之前未定义过SOMETHING,则在编译时出错,并给出"SOMETHING not defined!"的错误信息

1.3 定义一个宏,求出给定数组中的元素的个数

#define NELEMENTS(array) ??

答:#define NELEMENTS(array) (sizeof(array) / sizeof((array)[0]))

1.4 定义一个宏,求出给定结构中给定成员的偏移量

#define OFFSET(structure, member) ??

答: #define OFFSET(structure, member) ((int) &(((structure *)0)->member))

【2 数据声明和定义】

给定以下类型的变量a的定义式:

a) An integer

b) A pointer to an integer

c) A pointer to a pointer to an integer

d) An array of 10 integers

e) An array of 10 pointers to integers

f) A pointer to an array of 10 integers

g) A pointer to a <I>function</I> that takes an integer as an argument and returns an integer

h) An array of ten pointers to <I>function</I>s that take an integer argument and return an integer

答:(a) An integer:int a;

(b) A pointer to an integer:int *a;

(c) A pointer to a pointer to an integer:int **a;

(d) An array of 10 integers:int a[10];

(e) An array of 10 pointers to integers:int *a[10];

(f) A pointer to an array of 10 integers:int (*a)[10];

(g) A pointer to a <I>function</I> that takes an integer as an argument and returns an integer:int (*a)(int);

(h) An array of 10 pointers to <I>function</I>s that take an integer argument and return an integer:int (*a[10])(int);

【3 复杂类型(1)】

有如下表达式:

char (*(*x())[])();

请用文字描述x是什么。

答:这道题来自"The C Programming Language"中的一个例子。

首先,确定标识符:x

x是一个函数,没有参数:x()

返回值是一个指针:*x()

这个指针指向一个数组:(*x())[]

数组中的每个元素是指针:*(*x())[]

指向一个不带参数的函数:(*(*x())[])()

函数的返回值是char:char (*(*x())[])()

这里,要知道*、()和[]的优先级。

【4 复杂类型(2)】

jmp_buf的定义:

typedef struct _jmp_buf

{

REG_SET reg;

int extra[3];

} jmp_buf[1];

setjmp函数的原型:

extern int setjmp (jmp_buf __env);

问:调用setjmp时传递__env的内容,还是传递指针?

答:这个定义有点怪,它的意思是:jmp_buf这种类型是一个数组,只有一个元素,元素类型为struct{...}。数组名作为函数参数时,应该是传递地址/指针。

【5 头文件】

问:为什么标准头文件都有类似以下的结构?

#ifndef __INCvxWorksh

#define __INCvxWorksh

#ifdef __cplusplus

extern "C" {

#endif

/*...*/

#ifdef __cplusplus

}

#endif

#endif /* __INCvxWorksh */

答:在编译源文件时,C编译器和C++编译器都会对符号(函数或变量)名作某些修正,但两者采用的修正方法不同,所以两者生成的目标文件不能互相链接。在C++中使用extern "C"可以让C++符号获得C链接特性。由于C++编译器会自动定义__cplusplus宏,所以在C语言头文件中采用这种结构可以保证无论使用何种编译器,生成的目标文件都具有C链接特性,能够与标准C编译器所生成的目标文件相链接。

【6 static关键字】

请说出static关键字的3种用处:

(1)用于全局变量;

(2)用于局部变量;

(3)用于函数。

/* file.c */

static int a;

int b;

static int fn()

{

static int x;

int y;

}

答:(1)用于全局变量:外部静态变量,只能在本源文件中被引用,不能被其它源文件所引用。

(2)用于局部变量:局部静态变量,在函数返回后存储单元不释放;下一次调用该函数时,该变量为上次函数返回时的值。

(3)用于函数:内部函数,只能被本源文件中的函数所调用,不能被其它源文件调用。

【7 const关键字】

7.1 const关键字的意义是什么?

答:const关键字在C语言中用于声明"常变量",其值不可修改,但具有确定的数据类型。C编译器总是为其分配相应的存储单元。

在C++中,const关键字用于声明常量,C++编译器视具体情况决定是为其分配存储单元还是仅将其作为编译期间的常量。

7.2 解释以下的变量定义:

const int a1;

int const a2;

const int *a3;

int * const a4;

int const * const a5;

答:const int a1; a1是整型常量。

int const a2; a2是整型常量。等同于const int a2;

const int *a3; a3是指针(a3是可变的),指向一个整型常量。等同于int const *a3;

int * const a4; a4是常量指针(a4不可变),指向一个整型变量。

int const * const a5; a5是常量指针(a5不可变),指向一个整型常量。等同于const int * const a5;

【8 volatile关键字】

8.1 volatile意义?例如

volatile int *p;

答:volatile关键字用于声明内存映射的易失型变量,这类变量的值随时可能由于某种编译器所不知道的原因(例如,外部设备对其写入)所改变,所以编译器在进行代码优化时不能对其做任何的假设和依赖。

8.2 volatile能和const一起使用吗?例如

volatile const int *p;

答:volatile可以和const一起使用,不过很少见。

const关键字的意思是限制编程者自己不能修改变量的值;两者并不矛盾。

例如一个内存映射的、只读的硬件寄存器,假设它的地址是p,则可以这样声明:volatile const UINT32 *p;

【9 sizeof()】

有以下定义:

char *pmsg = "A";

char msg[] = "A";

char ch = 'A';

问:

sizeof(pmsg) = ?

sizeof(msg) = ?

sizeof("A") = ?

sizeof(ch) = ?

sizeof('A') = ? (在C++中等于多少?)

void f(char param[100])

{

// sizeof(param) = ?

}

答:sizeof(pmsg) = 指针变量的长度

sizeof(msg) = 2 (字符数组的长度)

sizeof("A") = 2 (字符串的长度)

sizeof(ch) = 1 (字符变量的长度)

sizeof('A') = 整型变量的长度 (在C语言中,字符常量的数据类型实际上是int;在C++中,它的数据类型是char,从而原式等于1)

sizeof(param) = 指针变量的长度 (数组名作参数时,传递的是数组的起始地址)

【10 字符串】

有以下代码

char *pmsg = "hello, world!";

strcpy(pmsg, "hi, there.");

试评论该代码。

答:这种写法是和编译器&操作系统相关的,所以不应当这样写。在WIN2K+VC环境下debug程序时会出现异常。

不过这样写,编译器不会报错。按道理,"hello..."的类型是const char [N],它是不能赋值给char *的,

因为会丢失常量属性。但在const关键字成为C标准之前,大家都这样写程序,所以char *pmsg = "hello..."

这种写法被给予特别豁免,即使在C++中也是如此,在"The C++ Programming Language"的附录里对此有讨论。

"hello, world!"是字符串常量(string literal),它的类型是const char [N],N为字符串的长度(包括结尾的0)。

"The C Programming Language"指出,写字符串常量的结果是未定义的(undefined)。所以在有些平台(操作系统+编译器)

上程序不会出错,而在其它平台上程序出现异常。

GNU手册里这样说:

Writing into string constants is a very bad idea; "constants" should be constant.

不过在GNU中它提供另外的选择:使用-fwritable-strings进行编译就可以。

那么,为什么不允许修改字符串常量呢(它不也在内存中吗)?

这可能和另外一个特点有关,即重复字符串的合并。现在的编译器应该会主动帮助我们合并程序中相同的字符串常量

以节省内存。如果string literal可写,就会出现问题。例如:

void foo()

{

printf("%s\n", "how are you?");

}

void bar()

{

char *p = "how are you?";

strcpy(p, "WHO ARE YOU?");

}

调用foo()当然会打印"how are you"。但如果编译器合并字符串,那么先调用bar(),再调用foo(),foo()打印的就是

"WHO ARE YOU?"。这当然不是我们想要的结果。

另外一方面,这样写也有问题(确实有人这么写):

if (func() == "something")

... func()是: char *func() { ... return "something"; } 这就假设编译器一定会帮我们合并字符串,然而那也不一定。 【11 混合运算】 有以下代码: void foo() { unsigned int a = 6; int b = -20; (a+b > 6) ? puts("> 6") : puts(" < = 6"); } 请问调用foo()的输出? 答:输出 > 6。 混合运算时的数据类型转换次序:int --> unsigned --> long --> double。 另外,char和short必定转换为int,float必定转换为double。 【12 内存访问】 有以下代码: void fn()

{

int a[100];

int *p;

p = (int *)((unsigned int)a + 1);

printf("p=0x%x\n", *p);

}

试评论以上代码。

答:p = (int *)((unsigned int)a + 1);

代码的意图是想使p指向数组的第二个元素,但通常的写法是:p=a+1。这里存在这样的问题:a是个常量地址,

a+1指向下一个数组元素,而((unsigned int)a + 1)指向下一个内存地址。如果地址是字节计数的,则p指向的

是数组第一个元素的第二个字节。还有一个效果就是:在RISC上该printf语句会出异常,因为不允许非对齐访问

(mis-aligned access)。对齐访问就是访问2字节变量的地址要能被2整除,4字节变量的地址要能被4整除,etc。

更多相关推荐:
C语言总结

--------13软件工程一班郭笑笑------------老师:徐静经过一学期的对c语言这门课程学习,我对其有了一定的了解,但是也仅仅是停留在了解的范围,对里面的好多东西还是很陌生,更多的在运用起来的时候还…

C语言总结

15个常考知识点与15个常见编程问题★15个常考知识点:(1)int/int结果仍为int类型;(2)与或表达式的短路特性;(3)switch与break语句;(4)forwhile循环与breakcontin…

C语言总结

1、C程序是由函数构成的。2、机器语言使用的编码是:二进制编码3、U盘出于保护状态时,其中数据可以阅读。但不可以修改4、在计算机系统中,可执行的程序是:机器语言代码5、计算机直接识别的是:机器语言6、可移植性最…

c语言总结

[原创]C语言总结总算把C语言又看了一遍,总结如下:1.二制数中原码.反码.补码以及进制之间的转换:原码:由符号位和该数的绝对值的二进制数组成.反码:负数的反码为除符号位以外所有位均取反的结果.正数的反码与原码…

C语言总结复习参考20xx-5

C语言程序设计考试要求(20xx-20xx学年第2学期)一、教学内容第1章程序设计概述1.1程序设计语言1.2算法1.3程序设计与实现1.4C语言程序的基本结构第2章简单程序设计2.1printf()函数输出数…

C语言总结之基本结构

基本控制结构这里列出C语言的各种控制结构,并给出简短的解释。复合语句:在形式上是一对花括号,其中可以有一系列的定义或说明,后跟一系列的语句。这两部分都可以没有。(3.1)条件语句:if(表达式)语句1if(表达…

按任意键结束_c语言总结

1、按Esc键结束程序让一个C语言的循环程序不是在等待输入,而是正在运行中,在这期间按任意键就能跳出循环,请问高手们如何实现?#includebios.h#defineEsc0x11b/*这两句加在程序头部*/…

c语言填空题总结

二填空题10道小题共20分1一个C源程序中至少应包含一个main函数2a是整型变量则执行表达式a2533后a的值为23intm5y2则表达式yymy的值为164执行下列语句inta1b2aabbabaabpri...

c语言教学工作总结

c语言教学工作总结,内容附图。

C语言知识点总结

C语言知识点总结C语言知识点总结1一常量2二标识符2三变量2四表达式3五输入输出函数4六C语言的语句5七C程序的基本结构5八选择结构语句5if表达式语句1else语句25条件运算符表达式1表达式2表达式36sw...

C语言总结

目录111213141516171819110111112113114115116117118119120121122123124C基础知识1函数与头文件2C预处理器3将一个字符转换为long型4strcpy函...

51单片机c语言总结

入门有针对性的解决一些简单的实际问题边理论边实践学一样会一样基本实验流水灯数码管显示键盘控制音乐播放继电器控制通信实验串口通信实验红外线遥控信号解码实验等单片机的定义分类和内部组成1单片机就是中央处理器CPU随...

c语言总结(68篇)