开启掘金成长之旅!这是我参与「掘金日新计划 · 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)对于联合的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于结构的不同成员赋值是互不影响的。