结构体、共用体,位运算
一、结构体与共用体
在C语言中,结构体( struct )和共用体( union )都是用户自定义的数据类型,用于组合不同类型的数据,但两者的核心区别在于内存分配方式,这直接决定了它们的用法和场景。
1.1结构体
结构体是将不同类型的数据成员“打包”成一个整体,每个成员拥有独立的内存空间,互不干扰。例如:
struct Student {
char name[20]; // 姓名(字符串)
int age; // 年龄(整数)
float score; // 成绩(浮点数)
};
结构体可以被整体引用,也可以嵌套使用,比如:
struct Student
{
int id;
char name[20];
float score;
struct Date birthday;
};
int main(void)
{
//struct Student s = {1, "zhangsan", 97.5, {2002, 3, 12}};
struct Student s = {
.id = 1,
.score = 97.5,
.birthday = {
.year = 2002,
.month = 3,
}
};
结构体未初始化的部分为0。其中,s.id 中的.为结构体声明运算符。机构体也可以传参指针,指针表示结构体内容可以写做->:
void printStudent(struct Student *p)
{
printf("%d, %s, %f\n", p->id, p->name, p->score);
}
void printStudents(struct Student a[], int len)
{
int i;
for(i = 0;i < len;++i)
{
printStudent(a + i);
}
}
结构体大多选择指针传参(效率高)。
现在我们已经了解了结构体是如何定义的,那么定义的内容,尤其是不同的类型在内存中是如何存储的呢,简单来说就是cpu存储这些内容是按照一定要求进行存储,按照顺序,分配的地址值一定能被该类型整除,详细展开论述可以总结为以下三点:
(1).默认按CPU位数对齐18字节),最终大小必须是8的整数;
(2).在结构体成员中,找到最长成员,最终按照该成员对齐;
(3).按照结构体声明顺序依次将成员保存到结构体内存中.保存的偏移量/ sizeof(类型)==0!
以空间换取时间。
1.2共同体
共用体是将不同类型的成员“共享同一块内存空间”,所有成员共用同一段内存,内存大小由最大的成员决定。例如:
union Data
{
int i; // 整数
float f; // 浮点数
char c; // 字符
};
最终内存空间由int或者float决定,这样方便对同一变量进行多类型赋值。
1.3 枚举
枚举也属于用户自定义函数类型,但与上面两者不同,它是定义一组命名的函数常量,最终利用到函数中。例如:
enum Week
{
Sun, Mon, Tue , Wes, Thu, Fri, Sat
};
int main(void)
{
enum Week w;
w = Sun;
printf("%d\n", w + 1);
switch(w)
{
case Sun:
puts("lol");
break;
case Mon:
case Tue:
puts("study");
break;
default:
break;
}
return 0;
}
默认第一个函数从0开始,按顺序递增只至结尾,也可以单独对某数标序,剩下的常量也会依次排列。
1.4 typedef函数
全称为typedefine,也属于自定义函数,他的主要作用是放着同一函数变量声明多次出现冗余,在其前加typedef函数,会得到新的函数名,此后本函数名将代替原变量类型 和函数,直接定义变量,例如:
用typedef为函数指针类型创建别名FuncPtr
typedef int (*FuncPtr)(int, int);
接下来定义 声明函数指针变量f,类型是FuncPtr(等价于int (*f)(int, int))
FuncPtr f;
对于参数或返回值复杂的函数(如带指针参数、多参数), typedef 能极大简化代码。而FuncPtr 是将函数的变量名变为类型的类型名。
二、位运算
位运算必须要求整型成以整型相兼容的类型
一般是两个二进制数进行比较
按位与 &, 两个二进制数全1为1,其他为0,作用是指定位清零;
按位或 |, 有1为1.无1为0., 指定位置置1,其他不变;
按位异或 ^ , 相为同为0,不同为1 , 指定位翻转.;
取反 ~ , 二进制按位取反, 全翻转
左移 《 , 两二进制数左移n次.后面补0 低位向高位移动, 例如 1《 2,意思为1从低位向高位移两位;
右移 》 , 二进制数右移n次.前面补0. 高位移向低位, 例如 1 》2,表示1从高位向低位移两位。