1.结构体
1.1 概述
1.2 结构体变量的定义和初始化
//结构体类型的定义
struct stu
{
char name[50];
int age;
};
//先定义类型,再定义变量(常用)
struct stu s1 = { "mike", 18 };
//定义类型同时定义变量
struct stu2
{
char name[50];
int age;
}s2 = { "lily", 22 };
struct
{
char name[50];
int age;
}s3 = { "yuri", 25 };
2.联合体
#include <stdio.h>
//共用体也叫联合体
union Test
{
unsigned char a;
unsigned int b;
unsigned short c;
};
int main()
{
//定义共用体变量
union Test tmp;
//1、所有成员的首地址是一样的
printf("%p, %p, %p\n", &(tmp.a), &(tmp.b), &(tmp.c));
//2、共用体大小为最大成员类型的大小
printf("%lu\n", sizeof(union Test));
//3、一个成员赋值,会影响另外的成员
//左边是高位,右边是低位
//低位放低地址,高位放高地址
tmp.b = 0x44332211;
printf("%x\n", tmp.a); //11
printf("%x\n", tmp.c); //2211
tmp.a = 0x00;
printf("short: %x\n", tmp.c); //2200
printf("int: %x\n", tmp.b); //44332200
return 0;
}
3.指针
3.1 指针变量的定义和使用
#include <stdio.h>
int main()
{
int a = 0;
char b = 100;
printf("%p, %p\n", &a, &b); //打印a, b的地址
//int *代表是一种数据类型,int*指针类型,p才是变量名
//定义了一个指针类型的变量,可以指向一个int类型变量的地址
int *p; p = &a;//将a的地址赋值给变量p,p也是一个变量,值是一个内存地址编号
printf("%d\n", *p);//p指向了a的地址,*p就是a的值
char *p1 = &b;
printf("%c\n", *p1);//*p1指向了b的地址,*p1就是b的值
return 0;
}
4.宏定义
宏定义又称为宏替换、宏代换,简称“宏”,是C提供的三种预处理功能的其中一种。其主要目的是为程序员在编程时提供一定的方便,并能在一定程度上提高程序的运行效率。
1. #define命令
#define命令是C语言中的一个宏定义命令,它用来讲一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。该命令有两种格式:一种是简单的宏定义(不带参数的宏定义),另一种是带参数的宏定义。
(1) 简单的宏定义
格式:#define <宏名/标识符> <字符串>
eg:#define PI 3.1415926535
说明:①宏名一般用大写
②宏定义末尾不加分号;
③可以用#undef命令终止宏定义的作用域
④宏定义可以嵌套
⑤字符串“”中永远不包含宏
⑥宏替换在编译前进行,不分配内存,变量定义分配内存,函 数调用在编译后程序运行时进行,并且分配内存
⑦预处理是在编译之前的处理,而编译工作的任务之一就是语 法检查,预处理不做语法检查
⑧使用宏可提高程序的通用性和易读性,减少不一致性,减少 输入错误和便于修改。例如:数组大小常用宏定义
(2)
目录
带参数的宏定义(除了一般的字符串替换,还要做参数代换)
格式:#define <宏名>(<参数表>) <字符串>
eg:#define S(a,b) a*b
area=S(3,2);
第一步被换为area=a*b;第二步换为area=3*2;
一个标识符被宏定义后,该标识符便是一个宏名。这时,在程序中出现的是宏名,在该程序被编译前,先将宏名用被定义的字符串替换,这称为宏替换,替换后才进行编译,宏替换是简单的替换。
说明:①实参如果是表达式容易出问题
#define S(r) r*r
area=S(a+b);第一步换为area=r*r;第二步换成 area=a+b*a+b;
当定义为#define S(r)((r)*(r))时area=((a+b)*(a+b))
②宏名和参数的括号间不能有空格
③宏替换之作替换不做计算,不做表达式求解
④宏的哑实结合不存在类型,也没有类型转换
⑤宏展开不占用运行时间,只占用编译时间,函数调用占运行时间(分配内存、保留现场、值传递、返回值)