0%

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;
}

位域

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;
}