1.嵌入式Linux操作系统
1.什么是嵌入式操作系统
嵌入式系统是以应用为中心,以计算机技术为基础,并且软硬件可裁剪,适用于对功能、可靠 性、成本、体积、功耗有严格要求的专用计算机系统。
2.嵌入式系统应用领域
智能家居领域,汽车电子领域等等
3.嵌入式系统分类
Linux ,μC/OS ,windows ,CE ,Vxworks, QNX
4.Linux历史
![](https://img-blog.csdnimg.cn/530cdccf7fa74ee1981bb5cd56dbcbce.png)
Linux操作系统的使用
1.什么是shell
shell:命令行解释器,用户和内核之间的桥梁
shell也是一个程序,提供给了我们一个界面,(终端)
2.shell版本
Bourne Shell:最早的Shell C Shell Ksh Z Shell Bourne-again shell(bash)
3.shell命令的格式
命令名称 [选项] [参数]
注意:
一条命令三要素之间必须要有空格隔开 若多个命令在一行书写,用分号(;)将各命令隔开
如果一条命令不能在一行写完,在行尾使用反斜杠()标明该条命令未结束
4.Linux命令
4.1 用户系统相关命令
4.1.1用户切换命令(su)
linux@ubuntu:~$ sudo -i #普通用户切换root用户
[sudo] password for linux:
root@ubuntu:~# su - linux
linux@ubuntu:~$
4.1.2 系统管理命令
ps: 显示当前系统中由该用户运行的进程列表
在windows查看进程
ctrl+alt+Del
ps -ef :查看所有进程及其PID(进程号),系统时间,命令详细目录,执行者
ps aux:除可显示-ef所有内容之外,还可显示CPU及内存占用率,进程状态
ps -w加宽以显示较多的信息
top:动态显示系统中运行的程序 (一般为每隔几秒刷 新一次) pstree 以树形格式显示进程
kill 输出特定的信号给指定PID(进程号)的进程
kill -l 列出所有可用的信号名称
clear:清除屏幕上的信息
uptime:显示系统已经运行了多长时间
关机
shutdown -h now 现在立刻关机
shutdown -h +30 30分钟之后关机
重启
reboot 重启
shutdown -r now 重启
4.1.3 磁盘相关命令
free: 查看当前系统内存的使用情况
df:查看文件系统的磁盘空间占用情况
du: 统计目录(或文件)所占磁盘空间的大小
du-sh
fdisk 查看磁盘分区情况及对磁盘进行分区管理
fdisk -l 显示文件系统的分区情况
<1>.使用fdisk必须拥有root权限
<2>.IDE磁盘hda,hdb......,SCSI硬盘是对应sda,sdb......hda1,第一个硬盘分区
4.2 文件,目录相关命令
cd,ls,mkdir,cat,cp,mv,rm,vim
4.2.1 vim 编辑器
vi的查找和替换
1. 查找(命令模式下)
/<要查找的字符> 向下查找要查找的字符
?<要查找的字符> 向上查找要查找的字符
2. 替换 (底行模式下)
4.2.2 chmod:改变文件的访问权限
方法一:
方法二:
4.2.3 chown:修改文件的所有者和组别
4.2.4 chgrp:改变文件的组所有权
4.2.5 cat 查看比较短的文档
linux@ubuntu:~/23072/C补习/day8$ cat 1.c
#include <stdio.h>
int a=10;
int main(void)
{
return 0;
}
4.2.6 more适合查看比较长的文档
按空格(space)向下走一页
按回车(Enter)向下走一行
按B向上走一页
按q退出
4.2.7 less是more的增强版
按空格(space)向下走一页
按回车(Enter)向下走一行
按B向上走一页
按q退出
支持上下箭头
4.2.8grep: 在指定文件中搜索特定的内容,并将含有这些内容的行标准输出
一般会和(|)管道配合起来使用
(|) 关联两个命令 将前一个命令的输出作为后一个命令输入
linux@ubuntu:~$ ls --help | more
4.2.9 常用的特殊符号
重定向符号 > 文件不存在,则新建,文件存在,覆盖原文件中的内容
追加重定向符号 >> 文件不存在则新建,文件存在,则追加在文件的末尾
反引号 ``
通配符
4.2.10 ln (创建链接文件)---->类似于windows快捷方式
硬链接
ln 源文件路径 硬链接文件 linux@ubuntu:~$ ln /home/linux/23072/LinuxC/day2/1.txt ying1.txt
软链接
ln -s 源文件路径 软链接文件 linux@ubuntu:~$ ln -s /home/linux/23072/LinuxC/day2/1.txt ruan1.txt
注意: .ln命令会保持每一处链接文件的同步性,也就是说,你不论改动哪一处,其他的文件也都会发生相同的变 化 .软链接它只会在选定的位置上生成一个文件的镜像,不会重复占用磁盘空间 硬链接它会在选定的位置上生成一个和源文件大小相同的文件。
4.2.11 find 在指定目录下搜索文件,它的使用权限是所有用户
#想在当前路径下查找所有的.c
linux@ubuntu:~$ find ./ -name "*.c"
linux@ubuntu:~$ find ./ -name 2*.c
5.用户相关命令
5.1压缩
5.1.1gzip![](https://img-blog.csdnimg.cn/ae66d3faaf38490b95d855bd37a15537.png)
5.1.2bzip2
5.1.3 tar: 对文件目录进行打包和解包
Examples:
tar -cf archive.tar foo bar # Create archive.tar from files foo and bar.
tar -tvf archive.tar # List all files in archive.tar verbosely.
tar -xf archive.tar # Extract all files from archive.tar.
-c, --create # create a new archive (创建包文件)
-f #指名包文件名
-x #解包
-v #显示打包的过程
-z #自动调用gzip,gunzip
-j #自动调用bzip2
先打包生成mynew.tar
linux@ubuntu:~$ tar -cvf mynew.tar 23031 23072 1.c 1.txt #打包生成mynew.tar
linux@ubuntu:~$ ls
1 mynew.tar staging_dir ying.tx
再进行压缩 gzip
linux@ubuntu:~$ gzip mynew.tar
linux@ubuntu:~$ ls
1 1.txt mynew.tar.gz
先解压
linux@ubuntu:~$ ls
1 1.txt a.out mynew.tar.gz
linux@ubuntu:~$ gzip -d mynew.tar.gz
linux@ubuntu:~$ ls
1 1.txt a.out mynew.tar
解包
linux@ubuntu:~$ tar -xvf mynew.tar
5.2 打包和压缩
linux@ubuntu:~/23072/LinuxC$ ls
1.txt day1 day2 day3
linux@ubuntu:~/23072/LinuxC$ tar -cvzf mynew.tar.gz day1 day3 1.txt
day1/
day1/demo1.c
day1/demo1
day3/
day3/k.c
day3/j.c
day3/c.c
1.txt
linux@ubuntu:~/23072/LinuxC$ ls
1.txt day1 day2 day3 mynew.tar.gz
5.3 解压+解包
linux@ubuntu:~/23072/LinuxC$ ls
day2 mynew.tar.gz
linux@ubuntu:~/23072/LinuxC$ tar -xvzf mynew.tar.gz
day1/
day1/demo1.c
day1/demo1
day3/
day3/k.c
day3/j.c
day3/c.c
1.txt
linux@ubuntu:~/23072/LinuxC$ ls
1.txt day1 day2 day3 mynew.tar.gz
5.4 文件比较命令diff
linux@ubuntu:~/23072/LinuxC/day3$ diff a.c c.c #两个文件第5行不一样
5c5
< printf("helloworld\n");
---
> printf("helloxian\n");
5.5 Linux环境变量
5.5.1 临时修改变量的值 PATH
5.5.2 永久修改变量的值 PATH
6.Linux网络配置管理
6.1 测试虚拟机是否有网 (ping)
6.2如何设置虚拟机的网络
6.3 查看ip地址
6.4 设置固定IP地址
6.5 网络基础知识介绍
6.5.1.IP地址
IP地址:在网络中,IP地址是主机的唯一标识,由网络地址+主机地址
32位的二进制 ------->点分十进制("192.168.xx.xxx")
6.5.2子网掩码
什么是子网掩码
网络地址部分全为1,主机地址部分全为0 (c类子网掩码 255.255.255.0)
子网掩码作用
判别主机发送的数据包是向外网发送,还是向内网发送
网关
DNS服务器 (域名解析服务器)
6.5.3 管理命令
创建用户adduser, 修改密码 passwd,添加组 groupadd,修改用户的属性 usermod,
删除用户 (deluser),删除组 (groupdel)
6.6windows和Linux文件共享
7.shell编程
1.shell执行过程
1.1创建一个.sh文件
linux@ubuntu:~/23072/LinuxC/day3$ touch 1.sh #1.创建.sh文件
1.2 修改文件的权限
linux@ubuntu:~/23072/LinuxC/day3$ chmod +x 1.sh #2.修改文件的权限
linux@ubuntu:~/23072/LinuxC/day3$ ls -l
total 0
-rwxrwxr-x 1 linux linux 0 7月 31 19:01 1.sh
1.3 执行
linux@ubuntu:~/23072/LinuxC/day3$ ./1.sh
2 注释
![](https://img-blog.csdnimg.cn/4c71c1217257457fae98072db8e0dc4b.png)
3变量
3.1用户自定义变量
3.1.1 命名规范:
<1>.由数字,字母,下划线组成,首字母不能为数字
<2>.不能为关键字和保留字
<3>.尽量见名知意,尽量大写
3.1.2访问shell变量
位置参数即命令行参数
由系统提供的参数为位置参数
3.1.3 预定义变量
$# 包含命令行参数的个数
$@ 包含所有命令行参数:"$1 $2 ...$9"
$* 包含所有命令行参数:"$1,$2.....$9"
$$: 包含正在执行进程的ID号
$? 包含前一个命令退出的状态
3.1.4 环境变量
![](https://img-blog.csdnimg.cn/a3afcf516bdd47e78020a22257e095f6.png)
4.shell程序和语句
4.1 说明性语句
4.2 功能性语句 ![](https://img-blog.csdnimg.cn/7777315f52be46978180846487b09c2b.png)
4.3 算术运算命令 expr
4.4 test命令
4.4.1测试字符串
s1 = s2 测试两个字符串的内容是否完全一样
s1!= s2 测试两个字符串的内容是否有差异
-z s1 测试s1字符串的长度是否为0
-n s1 测试s1字符串的长度是否不为0
4.2.2.测试整数
a -eq b 测试a与b相等 (equal)
a -ne b 测试a与b不相等
a -gt b 测试a是否大于b (great)
a -ge b 测试a是否大于等于b
a -lt b 测试a是否小于b
a -le b 测试a是否小于等于b
4.2.3文件属性
-d name 测试name是否为一个目录
-f name 测试name是否为普通文件
-L name 测试name是否为符号链接
-r name 测试name是否存在且可读
-w name 测试name是否存在且可写
-x name 测试name是否存在且为可执行
-s name 测试name是否存在,且长度不为0
f1 -nt f2 测试文件f1是否比文件f2更新
f1 -ot f2 测试文件f1是否比文件f2更旧
4.5 结构性语句
4.5.1 顺序
read 输入
read -p "请输入一个整数
" NUM1
4.5.2 echo 输出
echo "NUM1=$NUM" #默认换行
echo -n "NUM1=$NUM" #表示不换行
4.6 选择
4.6.1单分支
if [条件为真]
then
语句
fi
4.6.2 双分支
if [条件为真]
then
语句1
else
语句2
fi
4.6.3 多分支
if [条件1为真]
then
语句1
elif [条件2为真]
then
语句2
elif [条件3为真]
then
语句3
.....
else
语句n+1
fi
case 字符串变量 in
# 1|3|5|7
模式1|模式11|模式12)
语句1
;; #---->break
模式2)
语句2
;;
模式3)
语句3
;;
....
模式n)
语句n
;;
*)
语句n+1
;;
esac
4.7 循环
4.7.1 for
带列表的for
不带列表的for
类似于C的for
![](https://img-blog.csdnimg.cn/ccb1bb4400e04f87a27ae6b365827323.png)
4.7.2while
while [条件为真]
do
语句
done
4.7.3 break :跳出循環
4.7.4 continue: 结束本次循环,继续下一次循环
4.8 函数
4.8.1函数的定义
函数名()
{
函数体
}
function 函数名()
{
函数体
}
4.8.2函数的调用
方式一
value_name=`function_name arg1 arg2`
变量名=`函数名 参数1 参数2`
函数的所有标准输出都传递给了主程序的变量
function_name arg1 arg2
函数名 参数1 参数2
echo $? #$?上一个命令退出的状态
![](https://img-blog.csdnimg.cn/d231f84e76fa429eb363fa2cc8dc8be1.png)
#!/bin/bash
#遍历$HOME下file-dir dir-dir
for dir in $HOME/file-dir $HOME/dir-dir
do
if [ -d $dir ] #判断该文件夹是否存在
then #文件夹存在
read -p "是否删除该目录" op
case $op in
Y|y|yes|Yes)
rm -r $dir
mkdir $dir
;;
N|n|NO|no|No)
exit
;;
esac
else #文件不存在
mkdir $dir
fi
done
fileCount=0
dirCount=0
read -p "请输入路径名
" dirname
flist=`ls $dirname` #显示文件夹中的文件和目录
#遍历该文件夹中的内容
for file in $flist
do
if [ -d $dirname/$file ] #尽量使用绝对路径,否则只能复制当前路径下
then
cp -r $dirname/$file $HOME/dir-dir #复制文件夹
dirCount=`expr $dirCount + 1elif [ -f $dirname/$file ]
then
cp $dirname/$file $HOME/file-dir #复制文件
fileCount=`expr $fileCount + 1`
fi
done
echo "文件的个数为$fileCount"
echo "目录的个数为$dirCount"
8.结构体
1.如何创建结构体数据类型
//定义结构体语句
struct 结构体名字
{
属性1;
属性2;
属性3;
.......
};
//(学生)集合属性:
1.姓名 char name[SIZE]; //字符数组和字符串是标配
2.身高 int height; //基本数据
3.三门成绩 float scores[3];//数组
//定义一个学生的结构体
struct student
{
char name[20];
int height;
float scores[3];
};
//表示你定义一个结构体数据类型,该数据类型名字叫struct student
#include <stdio.h>
//定义一个学生的结构体数据类型
struct student
{
char name[20];
int height;
float scores[3];
};
//定义一个结构体数据类型,该名字叫struct student
int main(void)
{
return 0;
}
#include <stdio.h>
#define N 20
#define M 3
//定义一个学生的数据类型
struct student
{
char name[N];
int height;
float scores[M];
};
//定义一个学生的数据类型: struct student
//给结构体数据类型取了别名
typedef struct student Stu; //给struct student 取了个别名叫Stu
//该句话是前两句话的简化
typedef struct student
{
char name[N];
int height;
float scores[M];
}Stu;
2.如何创建结构体变量
#include <stdio.h>
//定义一个学生的结构体数据类型
struct student
{
char name[20];
int height;
float scores[3];
};
//定义一个结构体数据类型,该名字叫struct student
int main(void)
{
//类型名 变量名;
//定义一个结构体变量并进行初始化
struct student s1={"lisi",183,{90,89,78}};
return 0;
}
3.如何访问变量的值
4.如何操作结构体的指针
//定义一个指向int的指针
int * pi=NULL; //sizeof(pi)=8 pi+1 sizeof(int)
//定义一个指向结构体(struct student)的指针
struct student * ps=NULL; //sizeof(ps)=8 ps+1 (struct student)
9.内存管理
10.在堆区分配空间和释放空间
1.分配空间
#include <stdlib.h>
//参数:你要分配空间的大小
//返回值:void * void (表示空) void * (任何数据类型的地址)
//分配成功返回空间的首地址,失败则返回NULL
//malloc分配的空间未进行清空
void *malloc(size_t size);
2.释放空间
#include <stdlib.h>
//参数1:释放空间的首地址
void free(void *ptr);
11.结构体和堆区空间关联起来
1.在堆区创建5个存结构体的空间
#include <stdio.h>
#include <stdlib.h>
#define N 20
#define M 3
#define SIZE 5
//该句话是前两句话的简化
typedef struct student
{
char name[N];
int height;
float scores[M];
}Stu;
int main(void)
{
Stu * ps=NULL;
//1.分配空间
//再堆区创建5个存结构体的空间
ps=(Stu *)malloc(sizeof(Stu)*SIZE);
//2.出错判断
if(NULL==ps)
{
perror("malloc error");
return -1;
}
//3.释放
free(ps);
ps=NULL;
return 0;
}
2.编写一子函数,对ps指向的空间进行输入和输出
11.自定义头文件
1.自定义头文件的要求.h
2.如何引入自定义头文件![](https://img-blog.csdnimg.cn/06e4c22732aa4d7bab3eddfeddf978e4.png)
3.“” 和<>的区别
“”和<>的区别
“”: 编译器从用户的工作路径开始搜索头文件
<>: 编译器从标准库路径开始搜索头文件
4.条件编译
1.作用:避免头文件被重复引入
2.语法
//stu.c
#ifndef _STU_H
#define _STU_H
//<1>.引入库头文件
//<2>.宏定义
//<3>.结构体类型的定义
//<4>.枚举类型的定义
//<5>.函数声明
//<1>.引入库头文件
#include <stdlib.h>
//<2>.宏定义
#define N 20
#define M 3
#define SIZE 5
//<3>.结构体类型的定义
//该句话是前两句话的简化
typedef struct student
{
char name[N];
int height;
float scores[M];
}Stu;
//<4>.枚举类型的定义
//<5>.函数声明
void output(Stu * ps,int n);
void menu(void);
void input(Stu * ps,int n);
Stu *calpmaxheight(Stu *ps,int n);
void sortHeight(Stu * ps,int n);
#endif
12.gcc工作原理
vim--->命令模式---->gt 切换多个文件切换
1.分阶段执行
1.预处理
gcc -E main.c -o main.i
2.编译
gcc -S main.i -o main.s
3.汇编
gcc -c main.s -o main.o
4.链接
2.将四阶段合为一步
linux@ubuntu:~/23072/LinuxC/day5$ gcc stu.c -o stu
13.Make工程管理器 (多文件编译)
1.make工作原理
2.Makefile
3.Makefile中假目标
1.执行假目标
2.假目标出现的问题![](https://img-blog.csdnimg.cn/1025c7ca03304e0ea581e75780f52f99.png)
3.如何解决和假目标同名的问题![](https://img-blog.csdnimg.cn/1c43bed5314e4f8691d4cf25c9cf7a59.png)
4.Makefile变量
1.自动变量
$@ 目标文件
$^ 所有的依赖文件
2.预定义变量
3.自定义变量
5.Makefile中变量的展开方式
1.递归展示方式
![](https://img-blog.csdnimg.cn/f1d007e9e2a14c28b6ea1fc977c1dcad.png)
2.简单展开方式
14.函数指针
1.如何定义函数指针
//定义一个指向int的指针
int * pi; (int)
//定义一个指向int的指針的指針
int ** ppi; (int *)
//定义一个指向char的指针
char * pc; (char)
//定义一个指向数组的指针,该数组是一个长度为5的int的数组
int (*parr) [5]; (int [5]) int arr[5]
int (*parr) [5]
//定义一个指向结构体的指针,该结构体的类型(Stu)
Stu * ps; (Stu)
//定义一个指向函数的指针,该函数参数为两个int,返回值為一个int的函数
函数的类型: 返回值类型 (参数列表)
int (int,int) int add(int,int)
int (*pfun) (int,int)
2.定义一个长度为4的数组,该数组中的每个元素是个函数的指针
/*int a;
int arr[4];
int * par;
int * parr[4]*/
//int brr[3][4]; 定义一个长度为3的数组,该数组中的每个元素int [4]
//定义一个函数的指针 int (int,int)
int (* pfun) (int,int)=NULL; //----> int (*)(int,int)
//定义一个长度为4的数组,该数组中的每个元素是个函数的指针
int ( *pfunArr[4] ) (int,int )={add,sub,mul,div};
//pfunArr[0]-->add pfunArr[1]->sub pfunArr[2]-->mul pfunArr[3]--div
3.函数参数可以是函数指针
#include <stdio.h>
int add(int num1,int num2)
{
return num1+num2;
}
int sub(int num1,int num2)
{
return num1-num2;
}
int mul(int num1,int num2)
{
return num1*num2;
}
int div(int num1,int num2)
{
return num1/num2;
}
//定义一个函数
//参数1:一个函数指针 函数类型(int (int ,int )) 参数2 int ,参数3 int
//返回值:int
int pfunaction(int (*pfun)(int,int),int num1,int num2);
int pfunaction(int (*pfun)(int,int),int num1,int num2)
{
return pfun(num1,num2);
}
int main(void)
{
printf("add:%d\n",pfunaction(add,12,3)); //对后面两个数进行求和
printf("sub:%d\n",pfunaction(sub,12,3)); //对后面两个数进行求差
printf("mul:%d\n",pfunaction(mul,12,3)); //对后面两个数进行求积
printf("div:%d\n",pfunaction(div,12,3)); //对后面两个数进行求商
return 0;
}
4.函数指针也可以取别名 (typedef )
int (*pfun) (int,int);
int ( *pfunArr[4] ) (int,int )={add,sub,mul,div};
int pfunaction(int (*pfun)(int,int),int num1,int num2)
{
return pfun(num1,num2);
}
//给函数指针取了别名
typedef int (*PFUN) (int,int ); //给函数指针取了别名 int (*) (int,int) ---->PFUN
类型名
int (*pfun) (int,int);
PFUN pfun; 类型名 指针变量名;
int ( *pfunArr[4] ) (int,int )={add,sub,mul,div};
PFUN pfunArr[4]={add,sub,mul,div};
int pfunaction(int (*pfun)(int,int),int num1,int num2)
{
return pfun(num1,num2);
}
int pfunaction(PFUN pfun,int num1,int num2)
{
return pfun(num1,num2);
}
15.存储类型
1.register 寄存器
2.auto (默认)
存储类型 类型名 变量名
3.extern 外部的
1.变量
//show1.c
#include <stdio.h>
int a=10; //全局变量
void show1(void)
{
a+=10;
printf("show1 a=%d\n",a);
2.extern修饰全局变量
//show2.c
#include <stdio.h>
extern int a; //使用外部变量a
void show2(void)
{
a+=20;
printf("show2 a=%d\n",a);
}
3.extern修饰函数
#include <stdio.h>
//extern修饰函数:使用外部的函数
extern void show1(void);
extern void show2(void);
int main(void)
{
show1();
show2();
}
4.static 静态的
1.static修饰全局变量 (隐藏)
2.static修饰函数 (隐藏)
![](https://img-blog.csdnimg.cn/c1cfa4c6eeb84911823c07c853c8352d.png)
16.共用体
17.大小端
//测试计算机是大端序还是小端序
#include <stdio.h>
union un
{
int a;
char c;
};
int main(void)
{
union un u1;
u1.a=0x12345678;
if(u1.c==0x78)
{
printf("小端序\n");
}else
{
printf("大端序\n");
}
return 0;
}
18.枚举:(语义化)定义常量的一种方式
//1.定义一个枚举的数据类型
enum timeDate
{
MONDAY=1,TUESDAY,WEDSDAY,THURSDAY,FRIDAY //默认是从开始的整数
};
//定义一个枚举数据类型,该数据类型的名字叫enum timeDate
//2.定义枚举的变量
enum timeDate d1;
d1的值可以是MONDAY,TUESDAY,WEDSDAY,THURSDAY,FRIDAY 任意一个
#include <stdio.h>
//定义一个枚举数据类型
enum timeDate
{
MONDAY=1,TUESDAY,WEDSDAY,THURSDAY,FRIDAY //默认从0开始,后面依次加1
};
int main(void)
{
//定义一个枚举数据变量
int date=0;
enum timeDate d1;
while(1){
printf("请输入时间\n");
scanf("%d",&date);
d1=date;
switch(d1)
{
case MONDAY:
printf("我是周一\n");
break;
case TUESDAY:
printf("我是周二\n");
break;
case WEDSDAY:
printf("我是周三\n");
break;
case THURSDAY:
printf("我是周四\n");
break;
case FRIDAY:
printf("我是周五\n");
break;
default:
printf("我是周末\n");
}
}
}
19.字节对齐:分配空间时候一次性分配多少个字节
1.基本类型:自然对齐方式![](https://img-blog.csdnimg.cn/4457e1aa917d4d048528bdc7fba5f334.png)
2.结构体的对齐方式:成员当中最大的那个![](https://img-blog.csdnimg.cn/85ab6a8eeec143cc8c21749e1d803c88.png)
20.位域(位段)
#include <stdio.h>
#define N 20
typedef struct mydate
{
unsigned int year:11; //int的11位:
unsigned int month:4;
unsigned int day:5;
}Date; //缺点:不能通过scanf()输入
typedef struct student
{
char name[N];
int height;
Date birday;
}Stu;
int main(void)
{
Stu s1={"zhangsan",183,{2000,9,9}};
printf("%10s %5d ",s1.name,s1.height);
printf("%04d/%02d/%02d\n",s1.birday.year,s1.birday.month,s1.birday.day);
printf("sizeof(Date)===%ld\n",sizeof(Date));
return 0;
}
21.递归
1.一个数的阶乘![](https://img-blog.csdnimg.cn/445111d0236d4b1bb0d88669a74edc93.png)
#include <stdio.h>
int jiecheng(int n)
{
if(n==1)
return 1;
else
return n*jiecheng(n-1);
}
int main(void)
{
int n=0;
printf("请计算某个数的阶乘\n");
scanf("%d",&n);
printf("%d\n",jiecheng(n));
}