以下提到的题目全部来自C语言面试题大汇总.本文章将对其中的题目根据自己的理解进行详细的解答。存在不足或错误的地方敬请指正出来。
结构体大小
问:设有以下说明和定义:
typedef union
{
long i;
int k[5];
char c;
} DATE;
struct data
{
int cat;
DATE now;
double dog;
} too;
DATE max;
则语句:
printf("%d",sizeof(struct date)+sizeof(max));
的执行结果是__
答: 52
在详细解释答案之前,我们先来熟悉以下的几个概念。
结构struct
结构的声明
结构声明的形式:
struct tag {
member-list
} variable-list;
声明1:
struct {
int a;
char b;
float c;
} x;
这个声明创建了一个叫做x的变量。
声明2:
struct {
int a;
char b;
float c;
} y[20], *z;
这个声明创建了y和z。
注意:这两个声明被编译器当做两种截然不同的类型,虽然他们的成员列表完全相同,因此下面的语句是非法的。
z = &x;
声明3:
struct SIMPLE {
int a;
char b;
float c;
};
SIMPLE是一个结构标签。
这个声明把标签SIMPLE和这个成员列表联系起来,该声明并没有提供变量列表,所以它并未创建任何变量。
struct SIMPLE x;
struct SIMPLE y[20], z;
此时x,y,z都是同一种类型的结构变量。
声明4:使用typedef
typedef struct {
int a;
char b;
float c;
} Simple;
Simple是一个类型名。
Simple x;
Simple y[20], *z;
注意上面四种结构的声明,可别弄混淆了。
结构的自引用
自引用1:
struct SELF_REF1 {
int a;
struct SELF_REF1 b;
int c;
};
这样写是非法的,问题出在结构成员
struct SELF_REF1 b;
其内部还将包含自己的成员b,如此下去将一直包含下去永无止境。而且还可以这么说:
如果按照这样的引用方式,编译器永远不知道要为这个结构分配多少的空间,所以肯定是错误的。
自引用2:
struct SELF_REF2 {
int a;
struct SELF_REF2 *b;
int c;
};
此时的b是一个指针而不是一个结构体,此种自引用方式编译器知道整个结构的大小了。你看,这样的自引用方式是不是和链表的一样啊。。。
自引用3:
typedef struct{
int a;
SELF_REF3 *b;
int c;
} SELF_REF3;
这个也是非法的,因为结构只有到最后才知道这个类型名字是叫做SELF_REF3,在结构的内部中它还未被定义。改成下面的方式就可以了。
自引用4:
typedef struct SELF_REF3_TAG{
int a;
struct SELF_REF3_TAG *b;
int c;
} SELF_REF3;
结构的存储分配
struct ALIGN {
char a;
int b;
char c;
};
那么这个结构在内存中的存储方式如下:
但是:因为编译器可在一个结构的起始位置跳过几个字节来满足边界对齐要求,因此所有结构的起始存储位置必须是结构中要求最严格的数据类型所要的位置。
要解决因为边界对齐带来的空间损失,可以在声明中对结构的成员的列表重新排列,让那些对边界要求最严格的成员排首先出现,对边界要求最弱的成员最后出现。
所以上述可以改成如下声明方式:
struct ALIGN {
int b;
char a;
char c;
};
我去,回到题目中看到struct data 并没有涉及到边界对齐的问题,那个题目主要还是union的存储问题。好吧,你赢了。
联合union
联合中所有成员引用的是内存中的相同位置。也就是说,无论成员里面都包含哪些鬼,它们在内存中的位置是相同的。
比如说有一张床(一个联合)可以睡一个高个和矮个的人(两个成员),那么这张床要多大呢(占用的内存空间多大)?
很显然,肯定是要以那个高个子的成员来制定床的大小了,如果以矮个的成员来制定,那么高个的肯定睡不了那张床。
于是我们就可以回到题目中去:
typedef union
{
long i;
int k[5];
char c;
} DATE;
这个叫做DATE的union占用的内存空间肯定要按照最大的成员来制定的,也就是
int k[5];
共4bytes*5 = 20bytes。接下来的计算大家应该都懂了。
**问:**const与#define的区别?
问:如下程序,那么
foo(5, 5);
的结果是多少?
int foo(int x, int y)
{
if((x == 0) || (y == 0))
return 2;
else
return foo(x-1, y)+foo(x, y-1);
}
**问:**C++中的数组引用与引用数组区别?