===========================
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++) { 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[]);
void itoa(int data, char str[]) { 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++); 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"); 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;
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"); 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;
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[]) {
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));
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; 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); change(&s);
print(s);
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 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 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); 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); change(s);
print(s);
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; };
int main(int argc, char *argv[]) { struct GPIO P;
P.PA0 = 1;
P.PA10 = 2;
return 0; }
|