嵌入式学习--C语言Day10
递归函数
递推阶段:从原问题出发,按递归公式从未知到已知,最终到达递归终止条件
回归阶段:按递归的终止条件求出结果,逆向逐步带入递归公式,回到原问题求解
#include<stdio.h>
int fun( int n)
{
if (n == 1)
return 1;
return n*fun(n-1);
}
int main(int argc, char const *argv[])
{
int res = fun(5);
printf("%d\n",res);//120
return 0;
}
结构体
用户自定义的一种数据类型
struct 结构体名
{
数据类型 成员变量名1;
数据类型 成员变量名2;
数据类型 成员变量名3;
}结构体变量;
struct star
{
int id;
float height;
char in[33];
}lj;
结构体变量
定义结构体时,同时定义结构体变量
struct 结构体名
{
数据类型 成员变量名1;
数据类型 成员变量名2;
数据类型 成员变量名3;
}结构体变量名;
先定义结构体数据类型,再定义结构体变量;
struct 结构体名
{
数据类型 成员变量名1;
数据类型 成员变量名2;
数据类型 成员变量名3;
};
struct star lj; //全局
int main(int argc, char const *argv[])
{
struct star kl; //局部
return 0;
}
缺省结构体名
struct
{
数据类型 成员变量名1;
数据类型 成员变量名2;
数据类型 成员变量名3;
}结构体变量名;
赋值
直接赋值
struct star
{
int id;
float height;
char in[33];
};
struct star lj = {1,180,"leijun"}
单独赋值
#include<stdio.h>
#include<string.h>
struct star
{
int id;
float height;
char in[33];
};
struct star lj;
int main(int argc, char const *argv[])
{
lj.id = 1;
lj.height = 180;
strcpy(lj.in,"areyouok");
return 0;
}
点等赋值
struct star
{
int id;
float height;
char in[33];
};
struct star lj = {
.id = 2,
.height = 181,
.in = "wadawd"
};
访问
printf("%d %f %s",lj.id,lj.height,lj.in);
重命名
定义的同时进行重命名
typedef struct star //定义的同时进行重命名
{
int id;
float height;
char in[33];
}ST;
ST ll;
先定义,后重命名
struct star
{
int id;
float height;
char in[33];
};
typedef struct star ST; //先定义,后重命名
结构体数组
定义
定义结构体的同时定义结构体数组
struct mess
{
int id;
char usr[33];
char psd[33];
}inf[];
先定义结构体,后定义结构体数组
struct mess
{
int id;
char usr[33];
char psd[33];
};
struct mess inf;
初始化
定义时赋值
struct mess all[33]={
{1,"sadasd","zxczxc"},
{2,"asdasd","qw23"},
{3,"sadxzc","erhfgn"}
};
单独赋值
all[4].id = 4;
strcpy(all[4].usr,"wqeasga");
strcpy(all[4].psd,"wqeasga");
输入输出
#include<stdio.h>
struct student
{
int id;
char name[33];
float gra;
};
int main(int argc, char const *argv[])
{
struct student stu[3];
printf("学号 名字 成绩\n");
for (int i = 0; i < 3; i++)
scanf("%d %s %f",&stu[i].id,stu[i].name,&stu[i].gra);//输入
printf("学号 名字 成绩\n");
for (int j = 0; j < 3; j++)
{
if (stu[j].gra > 60)
printf("%d\t%s\t%f\n",stu[j].id,stu[j].name,stu[j].gra);//输出
}
return 0;
}
结构体指针
定义
struct 结构体名 *指针变量名
struct star
{
int id;
char name[33];
}st;
struct star s[3];
struct star *p = s;
struct star *q = &st;
赋值
struct star
{
int id;
char name[33];
}st;
struct star *q = &st;
q -> id = 1;
strcpy(q -> name,"sdas");
(*q).id = 2;
strcpy((*q).name,"asdasd");
结构体大小
在64位的操作系统中,默认的value值为8字节,找出结构体中数据类型最大的成员变量和value值对比,按小的数进行对齐
对齐时的地址偏移量是成员变量类型大小的整数倍
为什么要字节对齐?
1) 平台原因:不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。(提高程序的移植性)
2)性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。
3)内存原因:在设计结构体时,通过对齐规则尽可能优化结构体的空间大小至最小空间
typedef struct _a
{
char c1;
long i;
char c2;
double f;
}a;
typedef struct _b
{
char cl;
char c2;
long i;
double f;
}b;
typedef struct _c
{
char str;
short x;
int num;
}c;
int main(int argc, char const *argv[])
{
printf("%ld\n",sizeof(a)); //32
printf("%ld\n",sizeof(b)); //24
printf("%ld\n",sizeof(c)); //8
return 0;
}
共用体
union 共用体名
{
成员变量列表;
};
union star
{
int a;
char b;
}s;
int main()
{
s.a = 65;
printf("%d %c",s.a,s.b);//65 A
s.b = 'B';
printf("%d %c",s.a,s.b);//66 B
}
成员变量共用同一块地址空间
赋值以最后一次赋值为准
共用体的大小是成员变量中数据类型最大的
共用体验证大小端
union star
{
int a;
char b;
}s;
int main(int argc, char const *argv[])
{
s.a=0x12345678;
printf("%#x\n",s.b); //0x78
枚举
enum 枚举名
{
val1,val2...
};
未赋值时,值从0开始,顺序+1
存储类型
auto 修饰变量,一般省略时,会认为是auto类型
static 修饰变量和函数
存储在静态区
静态变量已初始化存储在.data区 未初始化变量存储在 .bss
修饰的变量,生命周期会被延长到整个程序(变量只初始化一次)
extrn 全局引用