自定义数据类型
1.struct
1)结构体的声明
声明结构体变量;结构体所占内存大小是其成员所占内存之和。
struct 结构体类型名{//结构体类型名可省略,匿名结构体
成员表;//可以有多个
成员函数;//可以有也可以没有
}结构变量量表 [={}];//同时定义多个变量“,”隔开,最后的“;”不能漏。可以在声明的同时初始化。
访问成员的一般形式是:
结构变量名 . 成员名
初始化
对结构体的成员逐个赋值
stu1.num = 18;
stu1.score = 90.5;
可以对结构体进行整体赋值
stu2 = (struct Student){"Tom", 15, 88.0};
结构体变量的初始化也可以与定义同时:
struct Student{ //声明结构体 Student
char name[20];
int num;
float score;
}stu = {"Mike", 15, 91}; //注意初始化值的类型和顺序要与结构体声明时成员的类型和顺序一致
可以部分初始化:
struct Student stu4 = {.name = "Lisa"};1
也可以按照任意的顺序使用指定初始化项目:
struct Student st = { .name = "Smith",
.score = 90.5,
.num = 18 };
2)、结构体变量的存储原理
1)结构体数据成员对齐的意义
……
2)结构体大小的计算方法和步骤
……
3)#pragma pack宏
……
另行了解
3)结构体数组
定义
struct Student{ //声明结构体 Student
char name[20];
int num;
float score;
}stu[5]; //定义一个结构结构数组stu,共有5个元素
初始化
定义结构数组的同时进行初始化
struct Student stu[2] = {{"Mike", 27, 91},{"Tom", 15, 88.0}};
整体赋值:
stu[2] = (struct Student){"Jack", 12, 85.0};
结构体变量的成员逐个赋值:
strcpy(stu[3].name, "Smith");
stu[3].num = 18;
stu[3].score = 90.5;
2.union
声明联合数据类型变量。多个成员共用一块内存。在编译时会选取成员中长度最长的来声明。所有的数据成员具有相同的起始地址。一个union只配置一个足够大的空间来容纳最大长度的数据成员。
union a { //声明了三个成员,但是长度不一(后面sizeof的结果不同机器结果不同,但double肯定是最长的),于是编译器会选取double的长的作为union a的长度
int a1; // sizeof(int) = 4
float a2; // sizeof(float) = 8
double a3; // sizeof(double) = 16
};
声明与struct相似,替换一下struct声明中的关键字就可了
3.enum
enum变量类型还可以给其中的常量符号赋值,如果不赋值则会从被赋初值的那个常量开始依次加1,如果都没有赋值,他们的值从0开始依次递增1.
声明
enum 枚举类型{枚举成员列表}; //其中的枚举成员列表是以逗号“,”相分隔
eg:enum Spectrum{red,balck,yellow,blue,white};
可以用“枚举类型”声明符号名称来表示int型常量。只要是能使用int型的地方就能够使用枚举类型。注意:C语言中的枚举的一些特性不适合C++;比如c中的枚举变量允许使用++运算符,但是c++中则不允许。
enum Spectrum{red,black,yellow,blue,white};
0 1 2 3 4
可以在枚举声明中,可以为枚举常量指定整数值:如
enum Spectrum{ red=10, black=20, yellow=30,blue=40, white=50 };
可在枚举类型成员列表中,声明多个成员的数值(整型常量值)相同, 如:
enum Spectrum{ red, black=22, yellow, blue = 22, white };
则: red = 0, black = 22, yellow = 23, blue = 22 white = 23.
匿名的
enum
枚举
enum {FALSE,TRUE}; //FALSE 0, TRUE 1
输出12个月的英文单词
#include<stdio.h>
#include <stdlib.h>
enum Months{jan=1,feb,mar,apr,may,jun,jul,aug,sep,oct,nov,dec};
int main(void)
{
enum Months m;
//flag用来标记输出的个数,若为4个,则输出一个换行符
int flag=0;
//指针数组,存放的是个字符串的入口地址
char *months[]={"January","February","March","April","May","June",
"July","August","September","October","November","December"};
for (m=jan;m<=dec;m++)
{
printf ("%-d月份:%-10s ",m,months[m-1]);
flag++;
if (flag%4==0)
{
putchar('\n');
}
}
system ("pause");
return 0;
}
4.typedef
用以给数据类型取名
1)与#define的区别
typedef有点像#define宏,其实际类型替代同义字。不同点是typedef在编译时被解释,因此让编译器来应付超越预处理器能力的文本替换。
声明一个指向字符变量的指针和一个字符变量
typedef char* pchar;
pchar pa,pb;
简化结构体
struct tagPOINT1 {
int x;
int y;
};
struct tagPOINT1 p1;
typedef struct tagPOINT {
int x;
int y;
}POINT;
POINT p1;//可以这样;
struct tagPOINT p2;//也可以这样;
5.extern
在其中一个c文件中定义一个全局变量key,然后在另一个要使用key这个变量的c文件中使用extern关键字声明一次,说明这个变量为外部变量,是在其他的c文件中定义的全局变量。
- extern修饰变量的声明。
- extern修饰函数声明。
- extern修饰符可用于指示C或者C++函数的调用规范。
(1)main.c文件
#include "common.h"
unsigned char key;
int p(void) {
printf("%d\n",i);
return 0;
}
(2)common.c文件
#include "common.h"
extern unsigned char key;
int main() {
p();
system("pause");
return 0;
}