C语言第十章:结构体、枚举、预处理指令

来源:互联网 发布:知乎 万历郑贵妃 编辑:程序博客网 时间:2024/06/16 07:03

1、 构造类型:根据已定义的一个或多个数据类型用构造的方法构造新的类型。
2、 结构体:由若干个相同或者不同的数据类型组成的结构体
为什么要有结构类型?
结构体可以把功能相同的数据组织起来,存在一起,用的时候方便,而且在调用函数时,若传递参数较多,传一个结构体相对而言简单一些,很多系统自带的函数必须用结构体。

什么是结构体?
“结构”是一种构造类型,它是由若干“成员”组成的。每一个成员可以是一个基本数据类型或
者又是一个构造类型
格式:struct 结构名{
成员列表
};//此处的分号不可以省略
十二、结构体变量及其定义方法
结构体定义的三种方法
1)、先定义结构体,=然后在定义结构体变量
struct Student{
int sno;
char name[21];
int age;
float score;
};
//注意:
a)、结构体定义完成哟后,计算机不会给结构体分配内存空间
b)、会在定义结构体变量后分配存储空间

//结构体变量定义格式:
struct 结构体 结构体变量名;
struct Student stu;//这句话表示定义一个Student结构体的变量,变量名是stu
*因为stu是Student类型 ,stu可以存放学生的 sno 、name、age、score ,也可以定义多个结构体变量

2)、定义结构体的同时,定义结构体变量

格式:struct Car{
int wheel;
float speed;
}car,car1;//结构体变量名

3)、使用匿名结构体定义结构体变量
struct {
int sno;
char name[21];
int age;
float score;
}结构体变量1,结构体变量2 。。;

char [20] =”asdas ” 使用sizeof的话是它的长度 20
使用strlen的话就会出现长度是字符的长度。 5

3、 三种初始化方式
struct Student stu;
stu.sno=201104;
4、 stu.age=22;
5、 //stu.name=”唐顺治”; //这是一种方法
6、 strcpy(stu.name, “唐枫”);
7、 stu.score=96.5f;
8、 printf(“学生的姓名 :%s 学号:%d,年龄:%d,成绩:%.2f\n”,stu.name,stu.sno,stu.age,stu.score);
9、
10、 struct Student stu1={2011,”张三”,23,56.77f};
11、
12、 //部分初始化
13、 struct Student stub2={.name=”李四”};
4、结构体变量存储原理
1、结构体对齐的含义:结构体的总长度
2、计算结构体在内存中占用的字节数的方法
1)、先找模数 是结构体中基本数据类型中占用字节数最大的那个。
2)、再计算结构体变量的各个成员占用的字节和(注意他的对齐方式)
计算方法:(避免有时间出现交换顺序就字节数不同的情况)

返回指针值的函数称为指针型函数 int *sum(int x, int y)
指向函数的指针变量称为“函数指针变量”。In t (*p)(int a, int b)

一、 结构体数组
1、 概念:数组的元素是结构体的类型。用来存放结构体相同的结构体变量。
2、 格式:
1)、定义的同时定义数组,struct 结构体{}数组名[长度]; struct Student{}stu[5];
2)、先定义结构体,后定义数组。Struct Student boy[5];
3、结构体数组的初始化
//2、定义的同时进行初始化
struct Student girl[2]={{“ss”,55},{“rr”,33}};
//3、先定义后初始化,整体赋值
struct Student ds[2];
ds[0]=(struct Student){“tsz”,44};
ds[1]=(struct Student){“tangfeng”,44};
//4、先定义结构体数组 ,后初始化
struct Student stu[2];
//1)使用strcpy函数
strcpy(stu[0].name,”tangshunzhi”);
//2、使用scanf
//scanf(“%s”,stu[0].name);
//stu[0].name=”weqw”;

二、 结构体指针
1、 结构体指针:指针变量指向一个结构体变量,结构体指针变量中得值所指向的时结构体的首地址 。
2、 结构体指针间接访问成员值
1)、一般形式:(*p).成员变量名
2) p->成员变量名 注意:p一定是一个结构体指针
三、结构体的嵌套
a、成员可以是基础数据类型也可以是一个结构
注意::结构体不可以嵌套自己的变量,但是可以嵌套自己的指针,结构体的定义可以嵌套其他结构体类型的变量。
1、 结构体的嵌套:结构体定义中,结构体的成员又是另外一个结构体变量。
2、 用结构体变量的成员值作为函数的参数,实质值传递
3、 用结构体变量(变量名)作为函数的参数,实质也是值传递

四、枚举类型(是一种基本数据类型)
1、C语言提供一种类型,这种类型得分变量的取值被限定在一定的范围之内。
2、格式:enum 枚举类型名{枚举值1,枚举值2.。。。。};
3、enum iColor{kIcolorWhite,kIcolorBlack,kIcolorTHJ}; //注意这种的命名方式。
4、枚举不可以嵌套定义
5、枚举变量的使用和定义
1)、先定义枚举类型,再定义枚举类型
2)、定义枚举类型的同时定义变量
//枚举变量的值:枚举类型完成以后,系统会自动的给每一个整型初值,默认初值从第一个元素开始值为0,以后每个元素的值在前一个的基础上值加1。

什么 情况下使用枚举:
当程序中需要给某一个变量值,限定取值范围的时候,可以使用枚举

五、typedef 使用方法
//1、基本数据类型
typedef int MALATANG;//MALATANG就是int

//2、用在数组,给数组起别名typedef  int ARRAY[5];//int a[5];  数组长度是5ARRAY a1={2,3,5,6,7};//就是长度为5的数组for(int i=0;i<5;i++){    printf("%d\t",a1[i]);}//3、给结构体起别名struct Person{    char *name;    int age;};struct Person p1={"aad",18};//给struct Person 起个别名  Ptypedef struct Person  P;//第二种起别名的方法typedef struct Car{    int wheels;    int speed;    }MYCAR;//表示给结构体起个别名MYCAR car1={1,23};//给匿名的结构体起个别名MYCARtypedef struct{    int hh;}IPHONE;//4、给枚举起别名//ISEX就是一个别名typedef enum Sex{kSexMan,kSexWomen} ISEX;typedef enum Sex S;S s1;s1=kSexMan;printf("%d\n",s1);//5、给函数指针//指向函数的指针int (*p)(int x,int y);//给函数的中的指针起别名typedef  int (*FUN)(int x,int y);// FUN就是一个别名FUN f1;f1=sum;int result=f1(3,4);

printf(“sum=%d\n”,result);

六、预处理指令
1、概念:以“#”号开头的预处理命令,如:#include #define这些预处理命令一般都放在源文件的前面但是也可以放在别的地方。
2、预处理的分类:文件包含、条件编译、宏定义
3、作用:编译之前完成它自己的工作
七、宏的概念及无参宏定义方法
1、宏:C语言中我们自定义的特殊标示符,习惯大写
2、宏的分类:有参宏和无参宏
3、宏的定义:#define 标示符 宏名
注意:预处理指令经常写在函数之前。
宏不是一个语句,它是一个预处理指令所以不需要分号。
4、宏替换:源程序在编译之前,由预处理程序对我们写得源程序进行处理,会把源程序所有出现宏名的地方一律使用宏的字符串去替换。

5、终止宏的话使用  #undef

6、宏使用的注意:
1)、宏是有作用域的
2)、字符串中出现宏名,是不会给替换的
3)、使用#undef可以终止宏
4)、宏可以嵌套

            5)、使用起别名    #define INT 1   INT ;            6)、注意括号的使用

八、有参宏的定义和使用
1、有参宏 有参宏 #define SUM(a ) a+a
SUM(3)//不仅仅要a+a 替换,而且还要把实参3代入到字符串中使用返回值。

3、 有参宏的注意事项:
1)、宏的形参之间可以出现空格,但是宏名和形参之间不能出现空格。
2)、在带参宏定义中,形式参数不分配内存单元.
3)、有宏参数时,最好用括号括起来
4)可以用宏来定义多个语句
十、typedef和#define的区别?
Define只是简单的替换,在编译之前
Typedef 在编译的时间进行替换相同的类型,它不是简单的替换,而是对类型说明符重新命名,被命名的标示符具有类型定义说明的功能。

预处理功能:如宏定义、文件包含、条件编译

第四节:条件编译
注意:条件编译后面的条件表达式中不能识别变量,它里面只能识别常量和宏定义

第一种形式的格式为:

if 常量表达式

程序段1

else

程序段2

endif

如常量表达式的值为真(非0),则对程序段1 进行编译,否则对程序段2进行编译。因此可以使程序在不同条件下,完成不同的功能。

第一种形式的格式为:

ifdef

标识符
程序段1

else

程序段2

endif

它的功能是,如果标识符已被 #define命令定义过则对程序段1进行编译;否则对程序段2进行编译。如果没有程序段2(它为空),本格式中的#else可以没有。

第三种形式的格式为:

ifndef 标识符

程序段1

else

程序段2

endif

第二种形式的区别是将“ifdef”改为“ifndef”。它的功能是,如果标识符未被#define命令定义过则对程序段1进行编译,否则对程序段2进行编译。这与第二种形式的功能正相反。


1、【掌握】static 与 extern对局部变量的作用
static 和 extern都是用来修饰变量(局部的static实际也是全局的)
static修饰的变量 只有你的包含那个变量定义的源代码文件可以访问(内部的变量)
extern定义的变量的哪个源文件都可以访问 只要声明了就可以(外部变量)

1、static对局部变量的作用
1、延长局部变量的生命周期,从程序启动到程序退出,但是它并没有改变变量的作用域
2、定义变量的代码在整个程序运行期间仅仅会执行一次

2、Static对全局变量的作用:
声明一个内部变量
由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以
避免在其它源文件中引起错误。

3、extern作用
完整定义一个外部变量
完整声明一个外部变量

0 0