📄 c语言常见笔试题.txt
字号:
c语言常见笔试题总结
【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 <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
【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()
coon @ 23:44:01 | 阅读全文 | 评论 0 | 引用 0 | 编辑
c语言笔试题(九)
2006-09-06
Tag: C语言
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指针进行初始化,在编程中要注意此类低级错误的发生。
coon @ 23:37:37 | 阅读全文 | 评论 0 | 引用 0 | 编辑
c语言笔试题(八)
2006-09-06
Tag: C语言
#pragma pack(8)
struct s1{
short a;
long b;
};
struct s2{
char c;
s1 d;
long long e;
};
#pragma pack()
问
1.sizeof(s2) = ?
2.s2的s1中的a后面空了几个字节接着是b?
如果您知道答案请在讨论中写出,以下是部份网友的答案,供参考:
网友rwxybh(行云)的答案:
内存布局是
1*** 11**
1111 ****
1111 1111
所以答案就是24和3
下面是一个测试的程序,试一试就知道了,我用的是VC2005
#pragma pack(8)
struct s1{
short a; // 2 BYtes
long b; // 4 Bytes
};
struct s2{
char c; // 1 Byte
s1 d; // 8 Bytes
long long e; // 8 Bytes
};
// 1*** 11**
// 1111 ****
// 1111 1111
//
// 00 01 02 03 04 05 06 07
// 00 01 02 03 04 05 06 07
// 00 01 02 03 04 05 06 07
//
#pragma pack()
int main(int argc, char* argv[])
{
s2 a;
char *p = (char *)&a;
for(int i=0;i<24;++i)
p[i] = (char)(i%8);
printf("%d\n",sizeof(a));
printf("c=0x%lx\n",a.c);
printf("d.a=0x%x\n",a.d.a);
printf("d.b=0x%x\n",a.d.b);
printf("e=0x%llx\n",a.e);
return 0;
}
结果:
24
c=0x0
d.a=0x504
d.b=0x3020100
e=0x706050403020100
网友 redleaves (ID最吊的网友)的答案和分析:
如果代码:
#pragma pack(8)
struct S1{
char a;
long b;
};
struct S2 {
char c;
struct S1 d;
long long e;
};
#pragma pack()
sizeof(S2)结果为24.
成员对齐有一个重要的条件,即每个成员分别对齐.即每个成员按自己的方式对齐.
也就是说上面虽然指定了按8字节对齐,但并不是所有的成员都是以8字节对齐.其对齐的规则是,每个成员按其类型的对齐参数(通常是这个类型的大小)和指定对齐参数(这里是8字节)中较小的一个对齐.并且结构的长度必须为所用过的所有对齐参数的整数倍,不够就补空字节.
S1中,成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐;成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8;
S2中,c和S1中的a一样,按1字节对齐,而d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e.这时,长度为24,已经可以被8(成员e按8字节对齐)整除.这样,一共使用了24个字节.
a b
S1的内存布局:11**,1111,
c S1.a S1.b d
S2的内存布局:1***,11**,1111,****11111111
这里有三点很重要:
1.每个成员分别按自己的方式对齐,并能最小化长度
2.复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度
3.对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -