C语言面试基础题,程序员必备面试题~

82 阅读5分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第3天,点击查看活动详情

变量

1、全局变量和局部变量在内存中的区别?

全局变量储存在静态数据区,局部变量在堆栈中

2、局部变量能否和全局变量重名?

能,局部会屏蔽全局。要用全局变量,需要使用"::"。

局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内

3、如何引用一个已经定义过的全局变量?

可以用引用头文件的方式,也可以用extern 关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变量,假定你将那个变量写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。

4、全局变量能否定义在被多个.C文件包含的头文件中?

可以,在不同的 C 文件中以static 形式来声明同名全局变量

可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错。

结构体

1、结构体的赋值?

C语言中对结构体变量的赋值或者在初始化或者在定义后按字段赋值

方式1:初始化

struct tag

{

     char a;

     int b;

}x = {‘A’, 1};/初始化/

struct tag

{

char a;

int b;

};

struct tag x = {‘A’,1};/在定义变量时初始化/

方式2:定义变量后按字段赋值

struct tag

{

char a;

int b;

};

struct tag x;/定义变量/

x.a =‘A’;/按字段赋值/

x.b = 1; /按字段赋值/

此时使用初始化的方式来赋值时,如x = {‘A’,1};则出错。

方式3:结构变量间的赋值

struct tag

{

     chara;

     int b;

};

struct tag x,y;

x.a=’A’;

x.b=1;

y = x;/结构变量间直接赋值/

2、结构体变量如何比较?

虽然结构体变量之间可以通过=直接赋值,但不能通过比较符(==)来比较,因为比较符只作用于基本数据类型。这个时候,只能通过int memcmp(const void *s1, const void *s2, size_t n);来进行内存上的比较。

3、结构体位域

(1)位域的定义:

位域是一个或多个位的字段,不同长度的字段(如声明为unsigned int类型)存储于一个或多个其所声明类型的变量中(如整型变量中)。

(2)位域的类型:

可以是char、short、int,多数使用int,使用时最好带上signed或unsigned。

(3)位域的特点:

字段可以不命名,如unsigned int :1;可用来填充;unsigned int :0; 0宽度用来强制在下一个整型(因此处是unsigned int类型)边界上对齐。

(4)位域的使用:

struct st1

{

unsigned char a:7;/字段a占用了一个字节的7个bit/

unsigned char b:2;/字段b占用了2个bit/

unsigned char c:7;/字段c占用了7个bit/

}s1;

sizeof(s1)等于3。因为一个位域字段必须存储在其位域类型的一个单元所占空间中,不能横跨两个该位域类型的单元。也就是说,当某个位域字段正处于两个该位域类型的单元中间时,只使用第二个单元,第一个单元剩余的bit位置补0。

struct st2

{

unsigned int a:31;

unsigned int b:2;/前一个整型变量只剩下1个bit,容不下2个bit,所以只能存放在下一个整型变量/

unsigned int c:31;

}s2;

于是可知sizeof(s2)等于3*sizeof(int)即12。

(5)位域的好处:

a.有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态,用一位二进位即可。这样节省存储空间,而且处理简便。这样就可以把几个不同的对象用一个字节的二进制位域来表示。

b.可以很方便的利用位域把一个变量给按位分解。比如只需要4个大小在0到3的随机数,就可以只rand()一次,然后每个位域取2个二进制位即可,省时省空间。

(6)位域的缺点:

不同系统对位域的处理可能有不同的结果,如位段成员在内存中是从左向右分配的还是从右向左分配的,所以位域的使用不利于程序的可移植性

4、结构体成员数组大小为0

结构体数组成员的大小为0是GNU C的一个特性。好处是可以在结构体中分配不定长的大小。如:

typedef struct st

{

int a;

int b;

char c[0];

}st_t;

sizeof(st_t)等于8,即char c[0]的大小为0。

5、结构体与联合体的区别?

(1)结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块地址空间), 而结构的所有成员都存在(不同成员的存放地址不同)。

(2)对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。