linux操作指令
一、linux体系结构
1.linux操作系统的组件
linux内核:
提供了系统的核心功能并且允许进程以有序的顺序访问硬件;
管理进程、输入、输出设备、文件系统和内存管理;
支持 “多用户 、 多任务”;
shell(命令行解释器):
用于用户和操作系统交互
类型:
bash
文件系统:
实用程序
图形界面:浏览器 office…
命令行应用程序:ls gcc gdb
二、linux软件包(apt)
1.两种软件包管理机制
Deb包:
Rpm包:主要用于RedHat
2.软件包管理器
apt:
能够检查和修复软件包依赖;
能够通过网络直接获取软件包;
3.ubuntu的软件包:
二进制的deb包:
源码包:.dsc
4.软件包管理工具
apt:
dpkg:
不能检查依赖
也不能在线通过网络获取软件包
5.apt工作原理
1)软件源
vi /etc/apt/sources.list //得到软件源地址 但不知道软件源中有哪些软件
2)索引文件(sudo apt-get update)
/var/lib/apt/lists
3)下载的软件包文件位置(/var/cache/apt/archives)
6.apt命令
apt-get update //更新软件包索引列表
apt-get install xchat //下载安装软件包(自动检查索引并下载安装)
apt-get remove --purge 软件包(xchat) //完全卸载软件包
apt-cache policy xchat //查询软件包的安装状态
apt-cache depends xchat //查询依赖包
7、dpkg
1.dpkg工具使用
sudo dpkg -i xchat_2.8.8-20_amd64.deb //安装软件
sudo dpkg -L xchat //列出安装的软件包清单
sudo dpkg -P xchat //完全卸载软件
三、shell命令
1、shell命令
1.shell
命令行解释器
bash:
2.关机/重启命令
sudo shutdown -h now //马上关机
sudo shutdown -r now //马上重启
3.shell命令提示符
hqyj@ubuntu:~/230701$
hqyj:用户名
ubuntu:主机名
~:用户的工作目录
$:一普通用户执行命令
4.shell命令的组成
命令名称 [options] [arguments]
eg:
ls
ls -l
la -l -a ./
5.shell命令
1)history
语法:
history [行号]
eg:
hsitory 10 //显示最新10行历史命令
HISTSIZE:环境变量 记录命令历史记录的容量
HISTSIZE=2000 //赋值
echo $HISTSIZE //打印变量的值
6.通配符
功能:批量操作文件
1)* 匹配任意长度的字符串
eg:
touch file1.txt file2.txt file3.txt
rm *.txt //将所有.txt文件删除
2)? 只匹配一个长度的字符
eg:
touch file_1.txt file_2.txt file_3.txt file_11.txt
rm file_?.txt //删除file_1.txt file_2.txt file_3.txt
3)[...] 匹配指定的一个字符
eg:
touch file1.txt file2.txt file3.txt file4.txt
rm file[124].txt //删除 file1.txt file2.txt file4.txt
4)[-] 匹配指定范围内的一个字符
eg:
touch file1.txt file2.txt file3.txt file4.txt file5.txt
rm file[1-4].txt //将file1.txt file2.txt file3.txt file4.txt 删除
5)[^...] 除了指定的字符,其他均可匹配
eg:
touch file1.txt file2.txt file3.txt file4.txt file5.txt
rm file[^12].txt //删除file3.txt file4.txt file5.txt
1.进程命令
ps aux //显示所有进程的详细信息 eg: ps aux | grep a.out
top //动态显示进程信息
pstree
/proc //查看进程信息
kill -l //查看系统的信号列表
kill 信号 pid //给进程发送信号 eg:kill -9 5658
2.linux下的文件系统
1)磁盘文件系统:真实的文件系统,例如:磁盘 、DVD、USB存储器,类型:ext3 ext4 FAT16 FAT32....
2)网络文件系统:是可以远程访问的文件系统,这种文件系统在服务器端仍是本地的磁盘文件系统,客户机通过网络远程访问数据。类型:NFS Samba
3)专有/虚拟文件系统:不驻留在磁盘上的文件系统 常见格式有:TMPFS(临时文件系统)、PROCFS(Process File System,进程文件系统)和LOOPBACKFS(Loopback File System,回送文件系统)
3.linux链接类型
1)硬链接
是利用Linux中为每个文件分配的物理编号——inode建立链接。因此,硬链接不能跨越文件系统。
2)软链接(符号链接)
是利用文件的路径名建立链接。通常建立软链接使用绝对路径而不是相对路径,以最大限度增加可移植性。
注意:
1)如果是修改硬链接的目标文件名,链接依然有效;如果修改软链接的目标文件名,则链接将断开;
2)对一个已存在的链接文件执行移动或删除操作,有可能导致链接的断开。假如删除目标文件后,重新创建一个同名文件,软链接将恢复,硬链接不再有效,因为文件的inode已经改变。
3)ln命令
功能:创建文件的链接文件
语法:ln [-s] target link_name
eg:
ln -s /home/hqyj/230701/day4/while.c mylink //创建软链接
4.文件的归档和压缩
1)压缩工具
gzip:gunzip .gz
eg:
gzip hello.c //hello.c.gz
gunzip hello.c.gz
bzip2:bunzip2 .bz2
zip:unzip .zip
2)归档工具
tar [ -t | -x | -u | -c | -v | -f | -j | -z ] tarfile filelist
eg:
tar -cf mytar.tar a.out mylink while.c //将a.out mylink while.c进行归档成mytar.tar
tar -tf mytar.tar //显示归档文件中的内容
gzip mytar.tar //mytar.tar.gz
tar -czf mytar.tar.gz a.out mylink test while.c //先归档,然后使用gzip压缩
tar -xvf mytar.tar.gz //解压
zip -r test.zip test //zip压缩
unzip test.zip //解压
5.ifconfig
查看系统的ip地址
ifconfig ens33 192.168.2.180 //配置系统的ip地址
6.DHCP:动态主机配置协议
动态分配ip地址
1)ip获取过程
第一步:linux主机寻找网络中的DHCP服务器
第二步:DHCP服务器提供可用的ip
第三步:linux主机接收租借
第四步:DHCP服务器确认租约ip
7.ping
检测网络中的两台主机是否联通
eg:
ping www.baidu.com
2、shell脚本
1.本质(重点)
shell命令的有序集合
2.编译型语言和解释性语言
1)编译型语言:
a.需要先编译再执行
b.对编译器有要求,不同平台需要不同的编译器进行编译;
c.若程序编译出现错误,则不会生成可执行文件
d.运行速度比较快
2)解释型语言
a.程序不需要编译器编译,直接解释
b.若程序出现错误,会接着继续向下解释
c.运算速度慢
3.编程
1)创建shell脚本文件
touch test.sh
2)修改权限
sudo chmod 777 test.sh
3)执行
./test.sh
4.shell变量
Shell中无数据类型,将任何赋给变量的值都解释为一串字符;
1)语法形式:
Variable=value
eg:
count=1
DATE=`date`
2)四种变量
a.用户自定义变量
注意: =左右两边不能有空格
b.位置变量,即命令行参数 (见示例:test2.sh)
$0 与键入的命令行一样,包含脚本文件名
$1,$2,……$9 分别包含第一个到第九个命令行参数
$# 包含命令行参数的个数
$@ 包含所有命令行参数:“$1,$2,……$9”
$? 包含前一个命令的退出状态
$* 包含所有命令行参数:“$1,$2,……$9”
$$ 包含正在执行进程的ID号
c.预定义变量
d.环境变量(系统已经定义好的一些变量)
HOME:用户的主目录
PATH:shell的搜索路径
5.shell语句
1)说明性语句(注释)
以#开头,不会被解释执行
#!/bin/bash 特殊,指定shell类型
2)功能性语句
read var var1 var2
eg:
read a b c
3、shell特殊字符(管道和输入/输出重定义/命令置换符)
1.通配符
2.管道(|)
功能:
将第一个命令的结果作为第二个命令的输入,一次类推
语法:
cmd1 | cmd2 | cmd3 ....
eg:
pwd | ls //pwd的结果作为ls的输出
ls ./ | wc -w //统计 ls . 结果中的单词数
ps aux | grep a.out //从ps aux的结果中搜索a.out字符串
./a.out & //让程序在后台运行
3.输入/输出重定向
输入/输出重定向是改变Shell命令或程序默认的标准输入/输出目标,重新定向到新的目标。
>file 输出重定向,即将本来的标准输出输出到终端,重定向之后输出到file文件 file不存在则创建,存在则会清空 eg: ls > 1.txt ls的结果重定向到1.txt文件
>>file 输出重定向 追加模式,即文件内容不会被清空,将新内容追加到源文件内容之后 eg: pwd >> 1.txt pwd的结果追加到1.txt原内容之后
<file 输入重定向 改变了输入的默认目标为file eg: wc -w < 1.txt //wc -w默认读标准输入,重定向之后输入目标为1.txt
&>file:将正确和错误的信息都会重定向到file eg: ls / test &> error.txt 正确和错误信息都重定向到error.txt
2>file:将错误信息和正确的信息分开处理 eg:ls / test 2>error.txt >right.txt 错误信息重定向到error.txt 正确的信息重定向到right.txt
&>> 和 2>> :追加模式
4.命令置换符
功能:得到命令的结果
语法:
cmd1 `cmd2` //将cmd2的结果作为cmd1的参数
eg:
ls `pwd` //将pwd的结果作为ls的参数
ps aux的作用:
ps aux
是一个常用的 Linux 命令,主要用于查看系统中当前运行的进程信息。
具体作用如下:
-
列出进程:
ps aux
会列出系统中所有的进程,包括正在运行的和已经结束的。 -
显示详细信息:该命令提供了丰富的进程详细信息,包括进程ID(PID)、父进程ID(PPID)、CPU 使用率、内存使用量、进程状态、启动时间等。
-
查看进程资源占用情况:通过
ps aux
可以查看每个进程使用的系统资源情况,例如 CPU 占用率、内存占用量等,有助于排查系统负载过大或者某个进程资源占用过高的问题。 -
监控进程:
ps aux
结合其他命令,例如grep
,可以用于对特定进程进行监控和筛选,定位到特定进程的相关信息。
需要注意的是,ps aux
命令输出的信息非常详细,可能会比较冗长。如果只需要查看当前用户的进程,可以使用 ps u
命令;如果只需要查看正在运行的进程(不包括已结束的),可以使用 ps aux | grep -v "defunct"
命令。
4、功能语句
1.read
2.expr 算数运算命令
SUM=`expr 12 + 4 \* 5`
echo $SUM
3.test 测试语句
测试对象:字符串 整数 文件属性
eg1:
5、shell控制语句(分支 循环)
1.条件语句
1)if_then_fi语句
语法结构:
if 表达式
then 命令表(可以是一条 也可以是多条)
fi
eg:
A=10
B=20
if test $A -lt $B
then
echo "A<B"
fi
2)if_then_else_fi语句
语法结构:
if 表达式
then 命令表1
else 命令表2
fi
执行过程:
if后表达式为真,则执行命令表1,否则,执行命令表2
eg:
A=10
B=20
if test $A -lt $B
then
echo "A < B"
else
echo "A >= B"
fi
3)case_esac语句
语法结构:
case 字符串变量 in
模式1)
命令1
;;
模式2|模式3)
命令2
;;
....
模式n)
命令n
;;
esac
执行过程:
比较 字符串变量的值与哪个模式相等就执行哪个模式对应的命令,否则执行*对应的命令
2.循环语句
1)for_do_done语句
形式:
for 变量 in 单词表
do
命令表
done
eg:
for I 1 2 3 4 5 6 7 8 9 10
do
echo $I
done
2)while_do_done语句
形式:
while 表达式
do
命令表
done
eg:
SUM=0
I=0
while [ $I -le 100 ]
do
SUM=`expr $SUM + $I`
I=`expr $I + 1`
done
echo $SUM
6、shell函数
1.函数定义
funtion_name() //方式一
{
}
function funtion_name() //方式二
{
}
2.函数调用
方式一:
value_name=`function_name [arg1 arg2 … ]` #所有标准输入都传递给主程序的变量
方式二:
function_name [arg1 arg2 … ] #获取函数的返回状态
echo $?
示例:(见 fun.sh 和 fun1.sh)
7、工程化管理文件
camera.c
server.c
main.c
client.c
eg:
8、tftp实验
1.下载tftp客户端和服务器
sudo apt-get install tftp-hpa tftpd-hpa
2.创建tftp服务器的目录
mkdir /home/hqyj/tftpboot
3.配置服务器的配置文件
sudo vi /etc/default/tftpd-hpa,如下:
TFTP_USERNAME="hqyj"
TFTP_DIRECTORY="/home/hqyj/tftpboot" /*tftp服务器的目录*/
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="-l -c -s"
4.启动tftp服务器
sudo service tftpd-hpa restart
四、基本的linux系统命令
1.
ls: 列出文件名
cat: 显示文本文件 eg:cat file.c 查看file.c文件的内容
less/more:分屏显示文件
rm: 删除文件
cp: 复制文件 eg:cp source.c dest.c
mv: 移动文件 eg:mv test.c test1.c eg1:mv test.c ./test
mkdir: 创建目录 eg:mkdir day4 eg1:mkdir -p day4/test
rmdir: 删除目录
2.
cd: 转换目录
grep: 查找字符串 //eg: grep hqyj /etc/passwd 在passwd文件中查找hqyj用户 eg1:ps aux | grep a.out
head: 显示文件开头 //eg: head -10 file_name 显示前10行
tail: 显示文件结尾 //eg: tail -10 file_name 显示倒数10行
sort: 按次序显示文件
uniq: 去掉文件中相邻重复的行 eg:sort while.c | uniq 先将文件while.c排序,然后将结果中相邻重复的行去掉
diff: 比较两个文件 eg: diff while.c while1.c 得到两个文件不同的地方
file: 查看文件类型 eg:file a.out 查看文件类型
3.
echo: 显示文本
eg:
echo "hello world" //原样输出 结果:打印"hello world"
echo $HISTSIZE 打印HISTSIZE变量的值
echo '$HISTSIZE' //严格的原样输出 结果:$HISTSIZE
echo hello world //结果:hello world 只保留一个空格
date: 显示时间和日期
eg:
date 显示时间
sudo date -s "2023/07/27 13:30"
gzip: 压缩文件
gunzip: 解压缩文件
bzip2: 压缩文件
tar: 归档和展开文件
whereis: 查找命令 eg:whereis ls 得到ls的位置
which: 查找实用程序 eg:which gcc 得到gcc的位置
4.
passwd: 修改密码
passwd :修改当前用户的密码
sudo passwd root : 修改root用户的密码
sudo passwd other: 修改其他用户的密码
su:临时切换用户身份
eg:
su -c ls //临时切换身份为root,以root身份执行ls,执行完马上切换到当前用户(hqyj)
su -m //临时切换身份为root,但是环境变量还是之前用户的(hqyj) exit退出 export:查看环境变量
su - //临时切换身份为root,环境变量也切换
ps: 列出进程 //ps -ef ps aux
df: 检查文件系统空间占用情况 //eg: df -T -h //查看文件系统空间占用清理
du: 显示磁盘空间的使用情况 //eg: du -h -s /etc 查看/etc目录空间使用情况
kill: 杀死进程 // kill -9 PID
chmod : 改变文件或目录的访问权限 //chmod 权限 file_name eg:sudo chmod 0777 a.out
chown: 改变文件或目录的属主 //chown root:root file_name eg:sudo chown zhangs:test 1.txt 修改1.txt的属主
chgrp: 改变文件或目录所属的组 // chgrp root file_name eg:sudo chgrp test a.out 修改a.out的所属组为test
info: 获得帮助
五、用户管理命令
1./etc/passwd 用户的清单
hqyj:x:1000:1000:hqyj,,,:/home/hqyj:/bin/bash
用户名:密码:UID:GID:用户信息:用户工作目录:登录shell
2./etc/group组清单
hqyj:x:1000:
组名:密码:GID:
3.adduser/useradd命令
sudo adduser test //添加test用户
4.deluser
sudo deluser test //删除test用户
5.usermod 修改用户属性
usermod [-u uid [-o]] [-g group] [-G gropup,…]
[-d home [-m]] [-s shell] [-c comment]
[-l new_name] [-f inactive][-e expire]
[-p passwd] [-L|-U] name
修改用户名:
sudo usermod -d /home/zhangs -m -l zhangs test //将test改名为zhangs
六、gcc编译器
1.编译流程
预处理:gcc -E hello.c -o hello.i 处理所有# 头文件展开、宏替换、保留满足条件的代码
编译: gcc -S hello.i -o hello.s(汇编文件)
汇编: gcc -c hello.s -o hello.o
链接: gcc *.o -o hello
七、gdb调试器
1.编译程序(-g)
gcc -g hello.c
2.进入gdb调试
gdb a.out
3.调试
(gdb)b 50 在程序的50行打断点
(gdb)r 程序开始运行,运行到50行停止运行,然后就继续单步调试
(gdb)n/s(进入到函数内部) 单步调试
(gdb)p n 查看变量n的值
(gdb)q 退出
八、make工程管理器
1.特点
Make工程管理器也就是个“自动编译管理器”,这里的“自动”是指它能够根据文件时间戳自动发现更新过的文件而减少编译的工作量,同时,它通过读入Makefile文件的内容来执行大量的编译工作。
make只编译更新过的文件,不会完全编译。
2.makefile(Makefile)文件
目标(二进制文件/目标文件*.o):依赖(源文件/目标文件)
命令(例如:gcc 源文件/目标文件)
eg:
hello:hello.o
<TAB> gcc hello.o -o hello
hello.o:hello.c
<TAB> gcc -c hello.c -o hello.o
eg1:vi Makefile
a.out:fun1.o fun2.o main.o
gcc fun1.o fun2.o main.o
fun1.o:fun1.c
gcc -c fun1.c -o fun1.o
fun2.o:fun2.c
gcc -c fun2.c -o fun2.o
main.o:main.c
gcc -c main.c -o main.o
3.变量
1)作用:
代替一个字符串
2)定义形式
递归: VAR=val
简单形式:VAR := val
3)变量值的获取
$(VAR)
eg2:
#定义变量
OBJS = fun1.o fun2.o main.o
CC = gcc
CFLAGS = -c -o
a.out:$(OBJS)
$(CC) fun1.o fun2.o main.o
fun1.o:fun1.c
$(CC) $(CFLAGS) fun1.o fun1.c
fun2.o:fun2.c
$(CC) $(CFLAGS) fun2.o fun2.c
main.o:main.c
$(CC) $(CFLAGS) main.o main.c
clean: #伪目标
rm *.o a.out
4)给变量添加值(+=)
eg:
OBJS = main.c fun1.o
OBJS += fun2.o #将fun2.o给)OBJS变量
5)预定义变量
编译器定义的一些变量,并且有默认值
CC:默认值cc
CXX:默认值g++
RM:默认值rm -r
6)自动变量
$* 不包含扩展名的目标文件名称
$+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件
$< 第一个依赖文件的名称
$? 所有时间戳比目标文件晚的的依赖文件,并以空格分开
$@ 目标文件的完整名称
$^ 所有不重复的目标依赖文件,以空格分开
$% 如果目标是归档成员,则该变量表示目标的归档成员名称
eg:
OBJS = fun1.o main.o
OBJS += fun2.o #变量添加值
CC = gcc
CFLAGS = -Wall -c -o
all:$(OBJS)
$(CC) $^ -o $@ # $^:所有依赖文件 $@:目标文件名
fun1.o:fun1.c
$(CC) $(CFLAGS) $@ $<
fun2.o:fun2.c
$(CC) $(CFLAGS) $@ $^
main.o:main.c
$(CC) $(CFLAGS) $@ $^
clean: #伪目标
$(RM) *.o a.out
3.make选项
-C dir读入指定目录下的Makefile eg: make -C dir 指定dir目录下的makefile
-f file读入当前目录下的file文件作为Makefile eg:make -f makefile_debug 指定makefile_debug为makefile文件
-i忽略所有的命令执行错误
-I dir指定被包含的Makefile所在目录
-n只打印要执行的命令,但不执行这些命令
-p显示make变量数据库和隐含规则
-s在执行命令时不显示命令
-w如果make在执行过程中改变目录,打印当前目录名
八、变量存储类型
1.分类
类型 作用域 生命周期 链接性 声明方式
auto 模块内 定义开始,模块结束 空 模块内
register 模块内 定义开始,模块结束 空 模块内,使用register修饰
全局变量 文件 定义开始,程序结束 外部 全局位置
static全局变量 文件 定义开始,程序结束 内部 全局位置,static修饰
static局部变量 模块内 定义开始,程序结束 空 模块内,使用static修饰
2.static关键字
static修饰局部变量:延长局部变量的生命周期
static修饰全局变量:修改了全局变量的作用域,只能在本文件中使用
static修饰函数:限制了函数的作用域,只能在本文件中调用
3.extern关键字
修饰全局变量,表示变量是外部的全局变量
eg:
vi fun.c
int a = 123;
void fun()
{
}
vi main.c
extern int a; //a是fun.c中的全局变量
int main()
{
return 0;
}
gcc main.c fun.c
九、条件编译
编译器根据条件是否为真决定是否编译对应的代码
一.根据宏是否定义,形式:
#ifdef 宏
...... //宏定义则执行
#else
..... //宏未定义则执行
#endif
eg:
int exc(int a, int b)
{
a = a ^ b ;
b = a ^ b;
a = a ^ b;
#ifdef DEBUG
printf("a=%d b=%d\n",a,b);
#endif
return 0;
}
void fun()
{
#ifdef DEBUG
printf("fun....\n");
#endif
}
int main()
{
int m = 10;
int n = 20;
exc(m,n);
fun();
return 0;
}
二.根据宏的值进行条件编译
1.形式
#if 值
.....
#else
....
#endif
eg:
int exc(int a, int b)
{
#if 1
a = a ^ b ;
b = a ^ b;
a = a ^ b;
#else
int tmp = a;
a = b;
b = tmp;
#endif
return 0;
}
十、函数宏
1.形式
#define MIN(a,b) ((a) < (b) ? (a) : (b))
int main()
{
printf("%d\n",MIN(20,10));
return 0;
}
十一、C高级
一.数组
1.概念
存储类型 数据类型 数组名[元素个数];
eg:
int a[10];
2.特点
在内存中连续存储
数组名是数组首元素的地址
数组名是地址常量,不能做左值 eg:a++;
数组占内存空间大小=sizeof(数组名);
3.字符数组
char ch[10] = {'a','b','c',123,10};
char ch[] = "hello world"; //ch[0]='a'; right
char *p = "hello world"; // *p = 'a'; error 常量区的内容不能被修改
4.strlen/strcmp/strcat/strcpy
二.二维数组
数据类型 数组名[行][列];
eg:
int a[3][4]; //有3个元素的一维数组,每个元素又是一个有4个元素的一维数组
a[0][0]
a[0][1]
a[0] a[0][2]
a[0][3]
a a[1]
a[2]
结论:
a <=> &a[0]
a[0] <=> &a[0][0] a[1] <=> &a[1][0]
a[i][j] <=> *(a[i]+j) <=> *(*(a+i)+j)
三.一级指针
1.语法
数据类型 *指针变量名 = 地址值;
eg:
int i = 123;
int *p = &i;
i = 321;
*p = 321;
2.* &
3.运算
+
-
++
--
四.多级指针
1.概念
指向指针变量的指针
2.二级指针
数据类型 **指针变量名 = 一级指针变量的地址值;
eg:
char *p = "hello world";
char **q = &p;
printf("%s %c %c %c\n",*q, **q,*p,p[0]);
五.指针数组
1.本质
是数组,数组中元素是指针
2.语法形式
数据类型 *数组名[元素个数];
eg:
char *ch[] = {"hello","world","how"};
printf("%s %s %s\n",ch[0],ch[1],ch[2]);
printf("%c\n",*(ch[1]));
3.特点
同数组
4.指针数组名相当于二级指针
六.数组指针(行指针)
1.本质
是指针,指针指向的是数组
2. 形式
数据类型 (*指针变量名)[元素个数];
eg:
int a[3][4];
int (*p)[4] = a;
3.二维数组数组名相当于行指针
七.函数
1.函数的定义
返回值类型 函数名(形参列表)
{
//语句块
return [表达式];
}
2.函数声明
返回值类型 函数名(形参列表);
1)位置:
全局位置
*.h文件
3.函数调用
函数名(实参列表);
注意:
形参和实参个数要一致
类型要一致
4.函数传参
值传参:
地址传参:
全局变量:
八.指针函数
本质:是函数,函数的返回值为指针
语法形式:
数据类型 *函数名(形参列表)
{
}
九.函数指针
本质:是指针,指向指向的是函数
语法形式:
数据类型 (*指针变量名)(参数列表);
eg:
int add(int a, int b)
{
}
int (*p)(int,int) = add;
十.函数指针数组
本质:数组,数组中元素是函数指针
形式:
数据类型 (*数组名[元素个数])(形参列表);
eg:
int add(int a, int b)
{
}
int sub(int a, int b)
{
}
int mul(int a, int b)
{
}
int (*a[3])(int,int) = {add,sub,mul};
十一.结构体和共用体
1.结构体
struct [结构体名]{
//数据成员
};
eg:
struct student{
int id;
char name[20];
char sex;
int age;
float score;
};
struct student stu = {1,"xiaoming",'m',18,99.5};
printf("%d\n",sizeof(struct student));
stu.id = 2;
struct student *p = &stu;
p->id = 3;
struct student *ptr = (struct student *)malloc(sizeof(struct student));
ptr->id = 1;
ptr.age = 18;
...
free(ptr);
struct student stu[3];//结构体数组
a[0].id = 1;
a[1] = a[0];
struct student *a[4] = {&stu[0],&stu[1],&stu[2]};
2.共用体
1)语法形式
union 共用体名{
//数据成员
};
十二.void *指针
不确定类型的指针,指向任意类型的变量
使用之前必须强转成确定类型的指针;
十三.const修饰指针
1.const int *p;
2.int * const p;
3.const int * const p;
十四.typedef (与define的区别)
typedef struct{
}s_t;
typedef int size_t;
typdef int * INT_T;
#define INT int *
INT_T p,q; //int *p,*q;
INT p,q;//int *p,q;