前言
本菜鸡开始了学习C语言的旅途。用这个来记录一下上课所学到的一些东西。仅作为自己的一个学习笔记。里面的内容也只是我对学到的东西的一些理解,可能有很多错误,大佬们勿喷。如果发现我理解的有哪些错误,欢迎评论区指出,希望大佬们不吝赐教。
结构体
1.结构体概念:
由C语言提供的各种基础类型中自定义的数据类型,比如把整型 、字符 、 浮点 、长整型等等一些基础的数据类型打包成为一个新的数据类型,用来方便描述一类事物的通用属性。
定义格式
struct 结构体标签
{
成员1 ;
成员2 ;
成员3 ;
......
};
示例:定义一个学生结构体
struct student
{
char num[100]; //学号
char sex; //性别
char name[100]; //姓名
float H; //身高
float W; //体重
unsigned int age; //年龄
char major[100]; //专业
};
2.结构体变量的引用
1): “.” 域操作符(成员引用符)
格式:
结构体变量名 . 成员变量名
表示取该结构体成员中的某个成员变量
示例:
#include <stdio.h>
// 结构体变量声明 不占用运行的内存空间
struct student
{
char num[100]; //学号
char sex; //性别
char name[100]; //姓名
float H; //身高
float W; //体重
unsigned int age; //年龄
char major[100]; //专业
};
int main(int argc, char const *argv[])
{
//定义结构体变量
struct student stu1;
stu1.sex = 'm';
stu1.age = 18;
stu1.num = "12345"; //不能这么用,因为是赋值
strcpy(stu1.num, "201809010000001");
printf("%c\n", stu1.num[0]);
2): -> 指针操作符
格式:
指针变量名->成员变量名
int main()
{
struct student stu2;
struct student *ps = &stu2;
ps->age = 18; //左值
printf("age:%d\n", ps->age); //右值
ps->sex = 'f';
strcpy(ps->num, "201809010000001");
}
3.结构体成员的初始化
struct student
{
char num[100]; //学号
char sex; //性别
char name[100]; //姓名
unsigned int age; //年龄
};
1):按定义时的顺序依次初始化各成员变量,用逗号隔开
struct student stu1 = {
"12345",
'm',
{"cxk"},
20
};
stu1.num 里面的内容就是12345\0
2):不按顺序, . 成员变量名 = 值
struct student stu1 = {
.age = 20,
.num = "12345",
.name = "cxk",
.sex = 'm'
};
3):结构体数组如何初始化
struct student stu[3] = {
{
.age = 20,
.num = "12345",
.name = "cxk",
.sex = 'm'
},
{
"12345648",
'f',
"tll",
18
},
{
"12345648",
'm',
"lkj",
20
}
};
推荐第二种赋值方式,因为第一种赋值方式当成员变动,或者赋值时漏掉一个,就会导致后面的全部出错。
4.结构体大小
struct student
{
char num[100]; //学号
char sex; //性别
char name[100]; //姓名
unsigned int age; //年龄
};
sizeof(struct student) == 208
内存布局:字节对齐(为了提高cpu访问内存的效率)
1):结构体类型所占空间是各成员变量所占空间之和(可能会填充)
2):结构体各成员变量按定义时出现的次序,一次存放
对齐规则:
对齐系数:windows(VS)默认对齐为8,linux系统32位是4, 64位为8
对齐数 :对齐系数 和 最大成员变量大小 取较小值
总大小 :结构体总字节大小是对齐数的整数倍
struct test1
{
int a;
char c;
};
sizeof(struct test1) == 8
struct test2
{
char c1;
int a;
char c;
};
sizeof(struct test2) == 12
struct test3
{
char c1;
char c;
int a;
};
sizeof(struct test3) == 8
struct test4
{
char c1;
short c;
int a;
};
sizeof(struct test4) == 8
struct test5
{
char c1;
char c;
short t;
char c2;
int a;
};
sizeof(struct test5) == 12
struct test6
{
double d;
char c;
};
sizeof(struct test6) == 16
struct test7
{
double d;
char c;
int a;
};
sizeof(struct test6) == 16
5.共用体(联合体)
union 共用体名
{
成员类型1 成员变量1;
成员类型2 成员变量2;
…
成员类型n 成员变量n;
};
共用体和结构体的最大区别:
结构体的内存大小是各成员变量字节之和
共用体的内存大小是各成员变量最大的那个
联合体的各个成员的关系类似于堆叠的效果:
- 联合体的整体尺寸大小应该以,成员中最大的为准。
- 给联合体某个成员赋值的时候,会覆盖其他成员的值。
- 联合体成员之间的值是互斥的,有某一时刻只有一个成员是有效的。
初始化:共用体的初始化只能指定一个成员变量的值,因为共用体本身只表示一个变量
//示例:
union test
{
int a;
char b;
};
sizeof(union test) == 4
int main()
{
union test t = {6};
//union test t = {.a=6};
}
共用体初始化时如果你指定了多个成员的初值,那么最后的值(空间的值)将是最后一次赋值的值
union test t1 = {.a=0xff01,.b='0'};
printf("%x\n", t1.a);
共用体在给成员变量赋值的时候,只会改变变量自己所属的空间中的值
t1.a = 0xff01;
printf("%x\n", t1.a);
t1.b = '1';
printf("%x\n", t1.a);
大端模式、小端模式:cpu内部寄存器是按bit位来存储信息的,
但是cpu中寄存器的数量是有限的,我们经常要把寄存器中的数据放到存储器(内存)中
但是内存不是按照bit来寻址,按地址(字节编号)来寻址,来找到cpu需要的数据
如果要把寄存器的内容存储到 内存中去,那么: 0x12345678
内存中的低地址存放的是低字节还是高字节?
大端模式:0x12345678 — 78是低字节
低地址存放高字节
12 34 56 78
地址从左至右由低到高
小端模式:
低地址存放低字节
78 56 34 12
地址从左至右由低到高
6.枚举
枚举本质上是一种取值范围被限制的整型,比如0-6表示7种颜色 0-3 表示4个不同的状态…
枚举定义:
enum 类型名
{
枚举的具体值
};
示例:
enum weekday
{
SUN,
MON,
TUE=1024,
WED,
THU,
FRI=2,
SAT
};
上例,如果没有没有赋值,首个默认为0, 之后的如果不赋值则取他前面枚举常量值+ 1 , 赋值前面的常量值不受影响。
即SUN=0,MON=1,TUE=1024,WED=1025,THU=1026,FRI=2,SAT=3.
- 在C语言种枚举类型等价于整型, 可以支持整型的所有运算
- 枚举常量最重要的作用,是使没有意义的数字,用有意义的单词来表示,提高程序的可读性。