题目:宏定义和操作符的区别。
【答案】
宏定义是C语言开始提供的3种预处理功能的其中一种。这3种预处理分别是:宏定义、文件包含和条件编译。宏定义是一个一环操作,不做计算和表达式求解,不占用内存和编译时间。
题目:以下宏MIN,输出结果为多少。
#define MIN(a,b) (a)<(b)?(a):(b)
int main()
{
int a =2;
int b =4;
int min = MIN(++a, b);
printf("%d",min);
return 0;
}
【答案】
4
【答案】
因为宏Min作为模拟函数,编译器会把它识别为(++a)<(b)?(++a):(b),a自加满足条件后,则还会自加一次。
题目:用宏定义写出swap(x,y),即交换两数。
【答案】
#define swap(x, y) (x)=(x)+(y);(y)=(x)–(y);(x)=(x)–(y);
题目:我想定义一些函数式的宏,例如:
#define square(x) x*x
但它们并不总是正确的。为什么?
【答案】
宏扩展是纯粹的文本扩展。为了避免意外,在定义函数式的宏的时候,请记住下边所列的三条规则。
(1)宏扩展必须使用括号,以便保护表达式中低优先级的操作符。例如对于上边问题中(错误)的square()宏,调用
1/square(n)
会被扩展为
1/n*n
这等价于(1/n)*n。而你需要的是
1/(n*n)
在这里,问题出在结合性而不是优先级上,但效果是一样的。
(2)在宏定义内部,所有参数的出现都必须用括号括起来,以便保护实参中任何低优先级的操作符不受宏扩展其他部分的影响。同样以square()为例,调用
square(i++)
会被扩展为
i++*i++
而这时未定义的。
题目:带参宏与带参函数的区别(至少说出5点)?
【答案】
|
带参宏 |
带参函数 |
处理时间 |
编译时 |
运行时 |
参数类型 |
无 |
需定义 |
程序长度 |
变长 |
不变 |
占用存储空间 |
否 |
是 |
运行时间 |
不占运行时间 |
调用和返回占用 |
题目:对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++ 中应用什么实现?
【答案】c用宏定义,c++用inline
题目:对于用户定义类型,typedef和#define有什么区别?
【答案】
typedef:关键字,具有类型检查功能。在定义数组、指针、结构体等比较方便。typ edef具有遵守作用域规则的优点,不仅仅可以函数外部声明,也可以在函数或块内声明。
define:预处理指令,不做类型检查,只有在编译已被展开的源程序时才会发现可能的错误并报错。定义常量、变量、编译开关(比如字符编码格式开关)等。define有判断优势,使用#ifdef。
【解析】
举例分析:
typedef char *String_t;
#define String_d char*
String_t s1,s2;
String_d s3,s4;
s1,s2和s3都被定义成了char*,但s4却被定义成了char类型。
题目:结构和联合有何区别?
【答案】
1.结构和联合都是由多个不同的数据类型成员组成,但在任何同一时刻,联合中只存放了一个被选中的成员(所有成员共用一块地址空间),而结构的所有成员都存在(不同成员的存放地址不同)。
2.对于联合的不同成员赋值,将会对其它成员重写,原来成员的值就不存在了,而对于结构的不同成员赋值是互不影响的。
题目:下面关于“联合”的题目的输出?
(a)
#include<stdio.h>
union
{
int I;
char x[2];
}a;
void main()
{
a.x[0]=10;
a.x[1]=1;
printf(“%d”,a.i);
}
【答案】
266(低位低地址,高位高地址,内存占用情况是0X010A)
如果x数组没有初始化,结果为0.
如果a.x[1]=1,结果为522
题目:我似乎不能成功定义一个链表,我试过
typedef struct
{
char *item;
NODEPTR next;
}*NODEPTR;
但是编译器报了错误信息,难道在C语言中结构不能包含指向自己的指针吗?
【答案】
typedef定义了一个新的类型名称,然而新的类型名称在结尾处。在结构体内使用该名称是错误的,因为在此之前,还没有实现真正意义上的定义新类型名称,而是在结构体结尾处。
解决方案1:
typedef struct node
{
char* item;
struct node *next;
}*NODEPTR;
解决方案2:
struct node
{
char *item;
struct node *next;
};
typedef struct node *NODEPTR;
题目:如何定义一对相互引用的结构?我试过
typedef struct
{
int afield;
BPTR bpointer;
}*APTR;
typedef struct
{
int bfield;
APTR apointer;
}*BPTR;
但是编译器在遇到第一次使用BPTR的时候,它还没有定义。
【答案】
与上一题相似。
struct a;
struct b;
typedef struct a *APTR;
typedef struct b *BPTR;
struct a
{
int afield;
BPTR bpointer;
};
struct b
{
int bfield;
APTR apointer;
};
题目:“typedef int (*funcptr)();”是什么意思?【答案】
它定义了一个类型funcptr,表示指向返回值为int型(参数未指明)的函数的指针。
题目:我在一个文件中定义了一个extern数组,然后在另一个文件中使用:
源文件1:
int array[]={1,2,3};
源文件2:
extern int array[];
为什么在源文件2中,sizeof娶不到array的大小?
【答案】
未指定大小extern数字是不完全类型。不能对它使用sizeof,因为sizeof在编译时发生作用,它不能获得定义在另一个文件中的数组大小。
解决1:
源文件1:
int array[]={1,2,3};
int arrayz=sizeof(array);
源文件2:
extern int array[];
extern int arraysz;
解决2:
头文件1:
#define ARRAYSZ 3
源文件1:
#include”头文件1”
int array[ARRAYSZ];
源文件2:
#include”头文件1”
extern int array[ARRAYSZ];
解决3:
源文件1:
int array[]={1,2,3,-1};//最后一个元素是”哨兵”值(通常是0、-1、NULL)来确定数组的长度。
源文件2:
extern int array[];
题目:这样的代码为什么不对?
struct x{…};
x thestruct;
【答案】
C不是C++。不能用结构标签自动生成类型定义名。事实上,C语言中的结构是这样用关键字struct声明的:struct x thestruct;
解决2:使用typedef。
typedef struct {…} tx;
tx thestruct;