03c_12day

03c_12day

===========================
2022-7-29
===========================

一.温故知新

    存储类的关键字
    extern : 修饰外部的,可以使用在变量或者函数
        
    static : 修饰静态的,可以使用在变量或者函数

    关键字在笔试题中的考法

    容易混淆的声明
        常量指针		const int *p; int const *p;
        指针常量		int * const p;

        指针数组		int *arr[3];
            命令行参数 : 
            可以在执行可执行程序时在可执行文件名后加入
            参数
        数组指针		int (*p)[3];

        指针函数		int *func(int , int);
        函数指针		int (*p)(int, int);
        函数指针数组	

        typedef


    函数的递归
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>

void func(void);
int main(void);

void func(void)
{
	printf("Hello World!\n");
	main();
}

int main(void)
{
	func();

	return 0;
}
/*
    函数的递归
        
*/
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>

int func(int num);

int func(int num)
{
	if(num == 1)//递归函数的退出条件
		return 1;
	return num + func(num - 1);
}

int main(int argc, char *argv[])
{
	int num = 0;//用于接收返回值的变量
	num = func(3);
	printf("num = %d\n", num);

	return 0;
}
/*
    函数的递归
    斐波那契数列
    1 1 2 3 5 8 13 21 34 ....
    一个数列从第3项开始,每一项都等于前两项的和
*/
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>

int func(int num);

int func(int num)
{
	if(num == 0 || num == 1)
		return 1;
	return func(num - 1) + func(num - 2);	
}

int main(int argc, char *argv[])
{
	int i = 0;

	for(i = 0 ; i < 20; i++)//求斐波那契数列的前20项
	{
		printf("[%d] %d\n", i, func(i));
	}

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <stdio.h>
#include <stdlib.h>

void itoa(int data, char str[]);
//在内核驱动的课程中需要手写itoa函数,只需要考虑正数即可
void itoa(int data, char str[])//12
{
	int i = 0;

	if(data < 10)//判断转换的数据是否只有个位
	{
		str[0] = data + '0';
		str[1] = '\0';
		return ;
	}
	itoa(data / 10, str);//递归调用
	for(i = 0; str[i] != '\0'; i++);//寻找'\0'的位置
	str[i] = data % 10 + '0';
	str[i + 1] = '\0';
}

int main(int argc, char *argv[])
{
	int num = 0;
	char arr[10] = {0};

	scanf("%d", &num);
	
	itoa(num, arr);

	printf("arr = %s\n", arr);

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
	char str[32] = {0};

	sprintf(str, "%d-%f-%c-%s\n", 9527, 3.14, 'A', "Hello");

	printf("str = %s\n", str);

	return 0;
}

C语言中复合型的数据类型 : 结构体 共用体 枚举

结构体 : 可以定义出不同类型的成员,存储不同类型的数据

    当在定义结构体类型时需要使用C语言的关键字 : struct
    如果想要定义结构体类型的变量\数组\指针,
    那么需要先定义结构体
1.结构体类型的定义
    struct tag	//struct是关键字,在关键字之后写tag标签
    {			//tag标签的命名需要见名生义
        内部写的是结构体成员的定义;
    };			//注意结构体定义结束之后需要有 ; 结尾
-----------------------------------
    注意:
    1.struct关键字之后可以加标签,也可以不加标签
    加标签 : 不光可以在结构体定义之后加变量名,定义全局变量
            也可以在函数内部通过 struct 标签 变量名;的方式
            定义局部变量
    不加标签 : 只能在定义结构体之后加变量名,定义全局变量
            不能在别的函数中定义局部变量(因为没有标签)
    2.定义结构体时,可以定义在函数之外,也可以定义在函数之内
    函数之外 : 凡是在结构体定义之下的函数
                都可以使用这个结构体
    函数之内 : 该结构体类型只能是在该函数内使用
    3.当定义结构体时不要给结构体的成员进行初始化
-----------------------------------
2.定义结构体类型的变量
    数据类型	变量名	;
    int			i		;
    float		f		;
    char		c		;
    struct stu	s		;
3.访问成员
    不能直接的给结构体的成员赋值,
    需要使用结构体类型的变量访问成员,进行赋值
    需要使用分量运算符 : . ->
    如果是结构体类型的变量访问成员,需要使用
        变量名.成员 的方式访问
    如果是结构体类型的指针访问成员,需要使用
        指针名->成员 的方式访问
4.结构体类型变量的初始化
    数据类型	变量名	=	{数值,数值};
    struct stu	s		=	{10086, "yidong", 79};
5.结构体类型变量的使用
    相同类型的结构体类型的变量,可以直接赋值
    不同类型的结构体类型的变量,即使结构体成员相同,
        也不能赋值
6.通过sizeof计算结构体的大小
    结构体的大小相当于结构体成员大小的总和
    也会考虑字节对齐的问题
    (默认情况下会以结构体中最大的数据类型作为对齐的标准)
    (主要是为了方便内存的管理)
7.结构体类型的指针
    数据类型		指针名	;
    int *			p		;
    char *			p		;
    struct stu *	p		;
*/
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
#include <stdio.h>
#include <stdlib.h>

struct stu//定义了学生的结构体
{
	int id;
	char name[32];
	int math;
};

int main(int argc, char *argv[])
{

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct stu//定义了学生的结构体
{
	int id;
	char name[32];
	int math;
};

int main(int argc, char *argv[])
{
	struct stu s;//定义了结构体类型的变量

	s.id = 10086;
	sprintf(s.name, "yidong");
	//strcpy(s.name, "yidong");
	//s.name = "yidong";
	s.math = 79;

	printf("s.id = %d\n", s.id);
	printf("s.name = %s\n", s.name);
	printf("s.math = %d\n", s.math);

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct stu//定义了学生的结构体
{
	int id;
	char name[32];
	int math;
}S;//S是struct stu结构体类型的变量,并且是全局变量

void func(void)
{
	S.id = 10010;
	strcpy(S.name, "liantong");
	S.math = 59;
	printf("S.id = %d\n", S.id);
	printf("S.name = %s\n", S.name);
	printf("S.math = %d\n", S.math);
}

int main(int argc, char *argv[])
{
	struct stu s;//定义了结构体类型的变量

	s.id = 10086;
	sprintf(s.name, "yidong");
	//strcpy(s.name, "yidong");
	//s.name = "yidong";
	s.math = 79;

	printf("s.id = %d\n", s.id);
	printf("s.name = %s\n", s.name);
	printf("s.math = %d\n", s.math);

	func();

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct
{
	int id = 9527;
	char name[32];
	int math;
}S;//S是结构体类型的变量,并且是全局变量

void func(void)
{
	S.id = 10010;
	strcpy(S.name, "liantong");
	S.math = 59;
	printf("S.id = %d\n", S.id);
	printf("S.name = %s\n", S.name);
	printf("S.math = %d\n", S.math);
}

int main(int argc, char *argv[])
{
	//struct s;//定义了结构体类型的变量

	//s.id = 10086;
	//sprintf(s.name, "yidong");
	//strcpy(s.name, "yidong");
	//s.name = "yidong";
	//s.math = 79;

//	printf("s.id = %d\n", s.id);
//	printf("s.name = %s\n", s.name);
//	printf("s.math = %d\n", s.math);

	func();

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct stu
{
	int id;
	char name[32];
	int math;
};

int main(int argc, char *argv[])
{
	struct stu s;//定义了结构体类型的变量

	s.id = 10086;
	sprintf(s.name, "yidong");
	s.math = 79;

	printf("s.id = %d\n", s.id);
	printf("s.name = %s\n", s.name);
	printf("s.math = %d\n", s.math);

	scanf("%d", &s.id);
	scanf("%s", s.name);
	scanf("%d", &s.math);

	printf("s.id = %d\n", s.id);
	printf("s.name = %s\n", s.name);
	printf("s.math = %d\n", s.math);

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct stu
{
	int id;
	char name[32];
	int math;
};

struct stu1
{
	int id;
	char name[32];
	int math;
};

int main(int argc, char *argv[])
{
	struct stu s = {10086, "yidong", 79};
	struct stu1 new;

	memcpy(&new, &s, sizeof(s));

/*
	new.id = s.id;
	strcpy(new.name, s.name);
	new.math = s.math;
*/
	printf("new.id = %d\n", new.id);
	printf("new.name = %s\n", new.name);
	printf("new.math = %d\n", new.math);

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct stu
{
	int id;
	char name[28];
	int math;
};

int main(int argc, char *argv[])
{
	struct stu s = {10086, "yidong", 79};

	printf("sizeof(s) = %ld\n", sizeof(s));
	printf("sizeof(struct stu) = %ld\n",sizeof(struct stu));

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct stu
{
	char c;
	//int i;
	long l;
	short s;
};

int main(int argc, char *argv[])
{
	struct stu s;

	printf("sizeof(s) = %ld\n", sizeof(s));
	printf("sizeof(struct stu) = %ld\n",sizeof(struct stu));

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct stu
{
	char c;
	short s;
	int i;
};

int main(int argc, char *argv[])
{
	struct stu s;
	
	printf("&s.c = %p\n", &s.c);
	printf("&s.s = %p\n", &s.s);
	printf("&s.i = %p\n", &s.i);

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct JY
{
	char name[20];
	char sex;
	int wuli;
	int zhili;
	int minjie;
};

void print(struct JY s);
void change(struct JY *p);

void print(struct JY s)
{
	printf("姓名 : %s\n", s.name);
	printf("性别 : %c\n", s.sex);
	printf("武力 : %d\n", s.wuli);
	printf("智力 : %d\n", s.zhili);
	printf("敏捷 : %d\n", s.minjie);
}

void change(struct JY *p)
{
	scanf("%s", p->name);
	getchar();
	scanf("%c", &p->sex);
	scanf("%d", &p->wuli);
	scanf("%d", &p->zhili);
	scanf("%d", &p->minjie);
}

int main(int argc, char *argv[])
{
	struct JY s = {"yangguo", 'M', 99, 90, 80};

	print(s);//通过print函数打印玩家信息
	
	change(&s);//通过change函数改变玩家信息

	print(s);//通过print函数打印玩家信息

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct JY
{
	char name[20];
	char sex;
	int wuli;
	int zhili;
	int minjie;
};

int main(int argc, char *argv[])
{
	//struct JY *p;//定义了结构体类型的指针
	//指针没有实际的指向,不能这样使用
	
	struct JY s;
	struct JY *p = &s;
	
	strcpy(p->name, "guojing");
	p->sex = 'M';
	p->wuli = 100;
	p->zhili = 59;
	p->minjie = 70;

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
	管理系统
//学生 老师 图书 火车票 菜单 旅馆 殡仪馆
	增 删 改 查
	打印数据
	增加成员
	删除成员
	修改成员
	查找成员
	成员排序
	数据存储
	读取数据

struct cir
{
	int x;
	int y;
	int r;
	int color;
};
*/
struct JY//
{
	char name[20];
	char sex;
	int wuli;
	int zhili;
	int minjie;
};

void print(struct JY *s);
void change(struct JY *p);

void print(struct JY *s)
{
	int i = 0;

	for(i = 0; i < 3; i++)
	{
		printf("姓名 : %s\n", s[i].name);//(s+i)->name
		printf("性别 : %c\n", s[i].sex);
		printf("武力 : %d\n", s[i].wuli);
		printf("智力 : %d\n", s[i].zhili);
		printf("敏捷 : %d\n", s[i].minjie);
		printf("========================\n");
	}
}

void change(struct JY *p)
{
	int i = 0;

	for(i = 0; i < 3; i++)
	{
		scanf("%s", p[i].name);
		getchar();
		scanf("%c", &p[i].sex);
		scanf("%d", &p[i].wuli);
		scanf("%d", &p[i].zhili);
		scanf("%d", &p[i].minjie);
	}
}

int main(int argc, char *argv[])
{
	struct JY s[3] = {{"yangguo", 'M', 99, 90, 80},
					{"guojing", 'M', 95, 59, 70},
					{"zhangwuji", 'M', 98, 95, 90}};

	print(s);//通过print函数打印玩家信息
	
	change(s);//通过change函数改变玩家信息

	print(s);//通过print函数打印玩家信息

	return 0;
}

共用体(联合)

    union是C语言中的关键字
1.共用体的含义
    共用体的成员共用同一块儿存储空间
    (使用一块儿存储空间管理不同的数据类型)
2.共用体的定义
    union tag				//tag是标签
    {
        共用体成员的定义;
    };						//最后需要加 ; 结尾
3.和结构体不同的地方
    1>结构体中每个成员都会占用独立的存储空间
    共用体中每个成员都会占用相同的存储空间
    2>结构体的大小是每个成员大小的和的基础上加入字节对齐
    共用体的大小以共用体成员中最大的成员大小为准
4.大端格式和小端格式
    在硬件的平台中是分为大端格式和小端格式的
    X86/英特尔架构		小端格式
    高字节的数据存放在高地址上,低字节的数据存放在低地址上
    (高对高,低对低)
    例子 : 在小端格式上存储一个十六进制的数据0x12345678
    地址		数据
    0x1000		0x78
    0x1001		0x56
    0x1002		0x34
    0x1003		0x12
    ARM架构->ARM系列大端格式(现在既支持大端也支持小端)
    高字节的数据存放在低地址上,低字节的数据存放在高地址上
    (高对低,低对高)
    例子 : 在大端格式上存储一个十六进制的数据0x12345678
    地址		数据
    0x1000		0x12
    0x1001		0x34
    0x1002		0x56
    0x1003		0x78
可以使用共用体测试当前的机器是大端格式还是小端格式
=========================
笔试题
1.什么是大端格式?什么是小端格式?
2.设计一个程序测试当前的机器是大端格式还是小端格式
=========================
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <stdio.h>
#include <stdlib.h>

struct S
{
	char c;
	short s;
	int i;
	long l;
	float f;
	double d;
};

union U
{
	char c;
	short s;
	int i;
	long l;
	float f;
	double d;
};

int main(int argc, char *argv[])
{
	struct S s;
	union U u;

	printf("sizeof(struct S) = %ld\n", sizeof(struct S));
	printf("sizeof(union U) = %ld\n", sizeof(union U));

	printf("&s = %p\n", &s);
	printf("&s.c = %p\n", &s.c);
	printf("&s.s = %p\n", &s.s);
	printf("&s.i = %p\n", &s.i);
	printf("&s.l = %p\n", &s.l);
	printf("&s.f = %p\n", &s.f);

	printf("&u = %p\n", &u);
	printf("&u.c = %p\n", &u.c);
	printf("&u.s = %p\n", &u.s);
	printf("&u.i = %p\n", &u.i);
	printf("&u.l = %p\n", &u.l);
	printf("&u.f = %p\n", &u.f);
	printf("&u.d = %p\n", &u.d);

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>
#include <stdlib.h>

union U
{
	int i;
	char c[4];
};

int main(int argc, char *argv[])
{
	union U u;

	u.i = 13;
	
	printf("u.i = %d\n", u.i);
	printf("u.c[0] = %d-%p\n", u.c[0], &u.c[0]);
	printf("u.c[1] = %d-%p\n", u.c[1], &u.c[1]);
	printf("u.c[2] = %d-%p\n", u.c[2], &u.c[2]);
	printf("u.c[3] = %d-%p\n", u.c[3], &u.c[3]);

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <stdlib.h>

union score
{
	int i;
	float f;
};

struct stu
{
	int id;
	char name[20];
	union score math;	
};

int main(int argc, char *argv[])
{
	struct stu s;
	int flag = 0;

	printf("请输入学生的ID : ");
	scanf("%d", &s.id);
	printf("请输入学生姓名 : ");
	scanf("%s", s.name);
	printf("请输入学生的成绩 : \n");
	printf("(1.整型	2.浮点型)\n");
	printf("> ");
	scanf("%d", &flag);
	switch(flag)
	{
		case 1 : scanf("%d", &s.math.i); break;
		case 2 : scanf("%f", &s.math.f); break;
	}

	printf("ID : %d\n", s.id);
	printf("姓名 : %s\n", s.name);
	switch(flag)
	{
		case 1 : printf("分数 : %d\n", s.math.i); break;
		case 2 : printf("分数 : %.1f\n", s.math.f); break;
	}

	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <stdio.h>
#include <stdlib.h>
//需要在无符号的环境中进行使用位域
struct S//位域/位段/位字段(在底层内核驱动时会使用的内容)
{
	unsigned int x : 1;
	unsigned int y : 2;
	unsigned int z : 1;
};

union U
{
	char c;
	struct S s;
};

int main(int argc, char *argv[])
{
	union U u;

	u.c = 13;

	printf("u.s.x = %d\n", u.s.x);
	printf("u.s.y = %d\n", u.s.y);
	printf("u.s.z = %d\n", u.s.z);

	return 0;
}

位域

resources/位域.png


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <stdio.h>
#include <stdlib.h>

struct GPIO
{
	unsigned char PA0 : 2;
	unsigned char PA1 : 2;
	unsigned char PA2 : 2;
	unsigned char PA3 : 2;
	unsigned char PA4 : 2;
	unsigned char PA5 : 2;
	unsigned char PA6 : 2;
	unsigned char PA7 : 2;
	unsigned char PA8 : 2;
	unsigned char PA9 : 2;
	unsigned char PA10: 2;
	unsigned char PA11: 2;
	unsigned char PA12: 2;
	unsigned char PA13: 2;
	unsigned char PA14: 2;
	unsigned char PA15: 2;
};
/*
	输入功能	0->00
	输出功能	1->01
	复用功能	2->10
	模拟功能	3->11
*/
int main(int argc, char *argv[])
{
	struct GPIO P;

	P.PA0 = 1;

	P.PA10 = 2;

	return 0;
}