c语言机构体,枚举,宏
结构体:
结构体初始化顺序:
先定义结构体,后初始化
定义结构体时同时初始化
匿名自定义初始化结构体
计算结构体在内存中的内存占用的字节数:
先找对齐模数,是结构体中的基本数据类型占用字节数最大的那个
如果剩下的可以存的下则存,如果存不下则重新分配
如果局部结构体和全局结构体重名则覆盖全局结构体
结构体指针:
struct s{
int lunxi;
int speed;
}car1;
struct s *p = NULL;
p = &car1;
struct Student stu1 = {18, "张三丰"};
struct Stucent *p = &stu1;
两种方法:
1) (*p).age 访问年龄
(*p).name 访问姓名
2) p->age
p->name
printf("%s%d", (*p).name, (*p).age);
printf("%s%d", p->name, p->age);
结构体嵌套:结构体定义的里面有其他结构体
结构体不可以嵌套自己变量,可以嵌套指向自己这种类型的指针
例:
struct Date{
int year;
int month;
int day;
}
struct Student{
char *name;
int age;
float score;
struct Date birthday;
//struct Student stu; 错误的
struct Student *stu; 正确的
};
struct Student stu1 = {"张三丰", 28, 59.99f, {1200, 12, 12}};
printf("姓名:%s, 年龄:%d(生日:%d-%02d-%02d), 成绩:%.2f\n",
stu1.name, stu1.age, stu1.birthday.year, stu1.birthday.month, stu1.birthday.day, stu1.score);
struct Person{
char *naem;
int age;
struct Person *child;
};
struct Person kim = {"kim", 8, NULL};
struct Person p1 = {"林志颖", 38, &kim};
printf("%s的儿子是:%s, 儿子的年龄:%d\n", p1.name, (*p.child).age, p1.childj->name);
用结构体变量做为函数的形参,结构体属性是改不掉的,实际上还是值传递
结构体指针作为函数形参
例:
void xiuche2(struct Car *c1){
c1->lunzi = 2;
}
struct Cat car1 = {4, 200};
xiuche2(&car1);
printf("%d\n", car.lunzi);
7)枚举类型:
枚举类型定义:
enum iColor {
white, black, blue
}
enum iColor iPhoneColor
enum Sex{Man, Women, Yao} sex; sex取值为 Man, Women, Yao 中的一个
枚举变量定义完成后,系统会自动给枚举的每个元素赋值一个整形的初值,从第一个元素0开始,每个元素加1。//Man = 0; Women = 1; Yao = 2;
也可以手动赋初值,后面元素自动加一
8)typedef:
typedef int ARRAY[5]; //int a[5];数组长度是5
ARRAY a1, b1; // int a1[5], b1[5]
int sum(int a, int b){
return a+b;
}
int jian(int a, int b){
return a-b;
}
int (*p)(int, int);
typedef int (*FUN)(int, int); //FUN是一个别名
FUN f1, f2;
f1 = sum;
f2 = jian;
printf("%d\n", f1(67, 23));
9)宏:
宏的分类:
1)无参宏 #define M 10
2)有参宏 #define SUM(a) a+a
int relult = SUM(3); //result = 6;
#define M1(x, y) x*y+x+y
result = M1(4, 5); //result = 29;
#define M3(x, y) x = a(a = 2) + 2; y = 4 * 3;
#dfine MAX(a, b) (a > b) ? a : b
int n = MAX(43, 888);
#define 和 typedef 的区别//宏定义只是简单的字符串代换,是在预处理完成的,而typedef是在编译时处理的,他不是简单的代换而是对类型说明符重新命名。被命名打标识符具有类型定义说明的功能
#define INT int*
typedef int* INT1
INT a, b; //a是指针变量, b是普通变量
INT1 a1, b1; //a1是指针变量, b1是指针变量
以#开头的指令都是预处理指令
在编译程序预处理时,对程序中所有出现的宏名,都用宏定义中的字符串去替换,字符串中的宏不会替换
#undef M //取消宏定义
宏定义可以嵌套
例:
#define R 4
#define PI 3.14
#define AREA PI*R*R
可以用宏定义表示数据类型,式书写方便
例:
#define P1 printf
#define P2 "%d\n"
#define INT int
#define P struct Person
P{
int age;
char *name;
}
10)条件编译:
#if--#elif--#else--#endif
#ifdef DEBUG1 //如果EDBUG1已定义,则a = 0,否则 a = 10000
a = 0; //#ifdef 检查宏是否定义 DEBUG是系统已定义宏
#else //#ifndef 如果没有定义宏
a = 10000;
#endif
if(score < 60) printf("E\n");
else if(score <= 69) printf("D\n");
else if(score <= 79) printf("C\n");
else if(score <= 89) printf("B\n");
else if(score <= 100) printf("A\n");
#if score <= 60
printf("E\n");
#elif score <= 69
printf("D\n");
#elif score <= 79
printf("C\n");
#elif score <= 89
printf("B\n");
#elif score <= 100
printf("A\n");
#endif
#define DEBUG = 1 //只需把1改成0将不显示调试信息
#if DEBUG ==1 //显示调试信息
#define log(format, ...) printf(format, ##__VA_ARGS__) //...表示可变参数个数,
//## 表示可以有参数也可无
#else //不显示调试信息
#define Log(format, ...)
#endif
条件编译发生在预处理阶段,在编译之前做的事情
核心:根据条件编译指定的代码
条件不同,编译的部分也不同,生成的目标文件(.o)的大小也不同
注释不参与编译