C高级
  EkKYkcW6BgCZ 2023年11月02日 36 0

下午 + 第二天 + 第三天 结构体 堆区操作 make工程管理

  1. 第五天命令 gdb shell脚本以及shell编程



结构体


包含C语言中所有的简单的数据类型 以及复杂数据类型的一种复合数据类型


结构体的定义

Strcut---》用来声明这是一个结构体


Struct +结构体名

{

数据1;

数据2;

。。。。。。。

};


struct people

{

Char name[20];

Int age;

};---->结构体 内部有简单的数据类型int,有复杂的数据类型 数组

C只提供结构体的关键字struct,但是内部的数据类型全部由个人自己进行定义。



用户创建的结构体---》作为一个数据类型而存在。

C高级_共用体


结构体访问内部成员

结构体定义好只是一个数据类型,如果要访问内部的成员,需要用到结构体变量或者结构体指针。


结构体变量

C高级_共用体_02


C高级_结构体_03


C高级_结构体_04


C高级_shell脚本_05



Tyepdef重命名


Typedef int int_t;


C高级_共用体_06


C高级_shell脚本_07



结构体指针

通过结构体数据类型来定义结构体指针

C高级_结构体_08


操作指针的本质:直接操作指针,从而实现简介的操作某一片空间里面(地址标号)的内容。

C高级_结构体_09




结构体嵌套

结构体是一个复合的数据类型,内部的成员是简单的和复杂的数据类型,但是同时还可以包括结构体



Struct people

{

Char name[20];

Int age;

};


Struct student

{

Int score;

};



现在将这两个结构体进行嵌套

Struct people

{

Char name[20];

Int age;

Struct student s; //struct student *s;如果使用指针,一定会有一个学生类型的结构体变量

};



引用成员

结构体变量访问结构体变量

C高级_结构体_10


C高级_shell脚本_11


结构体变量访问结构体指针

C高级_结构体_12


指针访问变量

C高级_共用体_13


指针访问指针

C高级_shell脚本_14




字节对齐

计算结构体的大小


Struct people

{

Char name[29];

Int age;

Double height;

};---》48

在计算结构体大小的时候,先看结构体内部成员的数据类型有没有超过4个字节,如果没有,就按照最大的数据类型进行对齐,如果超过4字节,就按照4字节对齐。


Struct a

{

Char b;

Short c;

Char d;

Int e;

};--->12字节

C高级_共用体_15



初始化

C高级_结构体_16


在定义结构体变量的时候才能进行赋值,不能在定义结构体的时候赋值,因为结构体是个数据类型。


结构体数组

数组:同一类型元素的集合。

结构体数组:是一个数组,只不过数据的类型是结构体类型

Struct people

{

Char name[20];

Int age;

};

Struct people a,b,c;

Struct people Arr[3] = {{aa,1},{bb,1},{cc,1}};--->结构体数组

访问内部元素:arr[0].name;arr[0].age;



赋值

Scanf(%s,arr[0].name);

Scanf(%s,arr[1].name);

Scanf(%s,arr[2].name);


For(i=0;i<3;i++)

{

Scanf(%s,arr[i].name);

}

C高级_shell脚本_17


在对结构体内部的元素进行输入输出时,不管是通过结构体指针访问还是结构体变量,输入的时候只需要看内部元素的输入输出方式,因为结构体指针和变量只是提供了一种访问内部元素的方式。




定义一个结构体,内部元素有姓名,性别,年龄。然后定义一个具有五个元素的结构体数组。对年龄进行排序。然后输出全为男性的名字和全为女性的名字。



C高级_shell脚本_18


C高级_共用体_19



  1. 变量的数据类型---》去掉变量名


Int arr[5];--->int [5];--->int (*p)[5]; 数组指针永远指向一维数组

Int arr[2][5];--->int (*p)[5];



数组指针和一维数组


C高级_结构体_20


C高级_shell脚本_21


C高级_shell脚本_22



指针函数和函数指针

函数


返回值 函数名(形参)

{

结构;

}

返回值:

  1. 库函数,系统调用,接收程序执行的结果
  2. 判断函数调用是否成功
  3. Return 0;主函数结束



函数的本质:存在于内存上的一段二进制代码

函数名:二进制代码的入口地址



指针函数

是一个函数,返回值是一个指针类型

Char * strcat(char * s1,char * s2);


函数指针

是一个指针,指向一个函数

int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);


在判断指针类型的时候,需要知道指针的指向类型----》先找出函数的数据类型,然后加*,起名

Char * strcat(char * s1,char * s2);

Int strcmp(char *s1,char *s2);---->int (*p)(char *,char *) = strcmp/&strcmp;


  1. strcat的数据类型---》char * (char *,char *)//去掉函数名和形参名
  2. 加*取名---》char * (*p)(char *,char *) = strcat//将函数名看作入口地址 p = strcat
  3. Char * (*p)(char *,char *) = &strcat//将函数的空间看作一个整体 p = &strcat




函数指针数组

是一个数组,数组元素是指针,指针是指向函数的。


Char * strcat(char *s1,char * s2)

Int strcmp(char *s1,char * s2)

当代码中出现函数指针数组的时候,需要两个或者两个以上的函数的数据类型相同。


Int add(int a,int b)

{

Return a+b;

}

Int div(int a,int b)

{

Return a/b;

}

Int mul(int a,int b)

{

Return a-b;

}


三个函数的类型都相同:int (*p)(int ,int ) = add;int (*p)(int ,int ) = &add;

Int (*q)(int,int ) = divInt (*q)(int,int ) = ÷

Int (*z)(int,int) = mul;Int (*z)(int,int) = &mul;


Int (*arr[3])(int,int) = {add,div,mul};

Int (*arr[3])(int,int) = {&add,&div,&mul};

Arr[3]是函数指针数组

C高级_共用体_23




共用体

共用同一片内存空间

Union a

{

Int a;

Char b;

Short c;

};


C高级_结构体_24


共用同一片空间,先找最大的数据,那么共用体的大小就是最大的数据类型的大小。

共用体每个元素的地址都相同

C高级_共用体_25



大小端

C高级_结构体_26


C高级_shell脚本_27


堆区

C高级_共用体_28


#include <stdlib.h>

void *malloc(size_t size);

在堆区申请空间


参数:申请的空间大小

返回值:成功返回空间首地址,失败返回NULL


因为malloc的返回值是void *,所以在申请空间成功之后,根据所申请到的空间进行强制类型转换

Int * p= (int *)malloc(sizeof(int)*5);


#include <string.h>

void *memset(void *s, int c, size_t n);

作用:清空空间(任何空间)

参数1:空间的首地址

参数2:用来清空空间的字符

参数3:清空空间的大小


Memset(p,0,sizeof(int)*5);


void free(void *ptr);

清空空间

参数:空间的首地址



void *realloc(void *ptr, size_t size);

参数1:空间的首地址

参数2:扩容的大小

返回值:扩容后的空间首地址

如果malloc之后的放不下,那么重新开辟空间进行存放,空间的首地址会改变,原本malloc的内容会被复制


如果放得下,那么就在malloc空间之后进行开辟,空间首地址不变

C高级_结构体_29




定义学生结构体,姓名,年龄,三门课的成绩,平均成绩。

  1. 使用malloc开辟空间(3)
  2. 输出姓名最大的人的信息
  3. 计算三门的平均成绩,并输出平均成绩85以上的人
  4. 输出年龄最大的人的地址


封装实现(自定义函数)

将封装的函数,使用函数指针数组实现




C高级_共用体_30





枚举


枚举内部的元素相当于给数字起别名。


#define M 4--->宏定义

Typedef int int_t;



enum A

{

malloc_ok,

Input_ok,

Output_ok,

};

C高级_shell脚本_31


枚举变量可以是字符,可以是数字,但是具体的结果要看格式控制符,并且枚举的大小永远是4字节。不能将浮点型作为枚举的变量。字符(字符串)都是数字的别名。



递归函数

在子函数的内部,自己调用本身的子函数


一个函数具有的功能,需要不断地进行更新,那么就可以写成递归函数(所要实现的功能复合一定的规律)


1+2+。。。。。+100


书写递归

  1. 从什么地方开始
  2. 从什么地方结束
  3. 从开始到结束怎样变化


Int digui(int sum)

{

If(1 == sum)

{

Return 1;

}


}


Main()

{

Digui(100);

}



For(i=0;i<100;i++)

C高级_结构体_32


make工程管理

Make相当于使用一个命令,但是需要相对应的规则才能够运行make

C高级_共用体_33


Makefile里面方的就是make所执行的规则


目标:依赖

[TAB]命令表


目标:所希望生成的文件

依赖:生成目标所依赖的源文件

命令表:以来怎么样变为目标


命令表

预处理 gcc -E 1.c -o 1.i 头文件展开,去掉注释,发生宏替换

编译

汇编

链接




一般将前三步合在一起,称作单独编译不链接

gcc -c 1.c -o 1.o



以1.c为例


.c文件一般作为依赖

1.o:1.c

Gcc -c 1.c -o 1.o

.o文件也可以作为依赖

1:1.o

Gcc 1.o -o 1


.c文件没有依赖,可执行文件没有目标



假目标

没有依赖,相当于是一个命令


.PHONY:---》声明clean是假目标

Clean:

Rm 1.o

Rm 1



自定义头文件

Test.h


#include <test.h>--->去 /user/include 寻找复合名字的头文件

#include test.h在用户当前工作路径下寻找头文件


“”包裹的头文件一般是用户自定义头文件




#ifndef _TEST_H_

#define _TEST_H_ ----->防止头文件重复包含


//需要用的库函数

//宏定义

//枚举

//结构体/共用体

//函数声明


#endif

C高级_shell脚本_34

C高级_共用体_35


将可执行文件的目标,依赖和命令表写在makefile的最上面



Make管理文件,根据文件的更新时间进行管理,执行最新的文件




多文件编译

  1. 自定义头文件
  2. 拆分子函数---》创建一个.c文件,将子函数全部写到.c内部,然后加上自定义头文件
  3. 书写makefile

C高级_shell脚本_36


C高级_共用体_37


C高级_共用体_38




系统预定义变量

CC 系统预定义的编译器 gcc

CFLAGS 预定义的编译选项 -c

$@ 文件的完整名字 (单独的.o目标,只能写在命令表中)

$^ 非重复的依赖文件 (所有的.o)

$< 第一个依赖文件的名称 (单独的.c依赖,只能写在命令表当中)



1.c 2.c


App:1.o 2.o

Gcc $^ -o $@

1.o:1.c

Gcc -c $< -o $@

2.o:2.c

Gcc -c $< -o $@


C高级_shell脚本_39


采用系统预定义的变量来代替缩写的目标.o和依赖.c

C高级_共用体_40



自定义变量

自己定义的变量的名字

C高级_共用体_41


A B是自定义的变量名,如果要使用App,或者所有的.o文件,需要加上$




结构体


Int double

结构体是自定义的数据类型


可以通过结构体数据类型定义结构体变量和结构体指针


Struct lion

{

Char name[20];

Struct tager ta; /*ta

};

Struct lion l;//*l


结构体数组

一片连续的空间,内部数据是结构体类型


Typedef Struct student

{

Char name[20];

Int age;

}STU;


STU s[5];


S[0]~s[4]


For(i=0;i<5;i++)

{

Scanf(%s,s[i].name);

}




Malloc


Int * p=(int *)Malloc(sizeof(int));


STU *p = (STU *)Malloc(sizeof(STU));



Int mymalloc(STU ** st)

{

*st= (STU *)Malloc(sizeof(STU));

If(*st == NULL)

}



一级指针和二级指针


Int a = 20;

Int *p = &a;

Int *q = p;

对于一级指针,操作指针p,并不会引起指针q的指向发生改变


Int a = 20;

Int *p = &a;

Int **q = &p;

对于二级指针,操作指针q,会引起p的指向发生改变


Make

Makefile--->脚本


目标:依赖

命令表



多文件编译





系统预定义变量和自定义变量

CC

CFLAGS

$@

$^

$<


OBJS = main.o malloc.o

OBJ = App


Export OBJS OBJ


App:main.o malloc.o


${OBJ}:${OBJS}

${CC} ${OBJS} -o ${OBJ}






makefile嵌套

C高级_结构体_42


C高级_共用体_43




网络基础

IP 子网掩码 网关 DNS服务器

IP

IP:主机的唯一标识

点分十进制--》192.168.1.1


IP的分类和组成

A:一个网络地址+三个主机地址

网络地址最高位为0 0000 0000 ~0111 1111--》0~127

0.0.0.0~127.255.255.255


0.0.0.0:源地址 没有明确的Ip,都会被0.0.0.0接受

127开头的地址 本地环回地址

255结尾的地址 组播和广播地址

B: 两个网络地址+两个主机地址

第一个网络地址的最高位是10 10000000~10111111---》128~191


C:三个网络地址+一个主机地址 11000000~11011111--》192~223


D:第一个地址是1110

E:第一个是11110



子网掩码

  1. 分割IP
  2. 通信


子网掩码


C类IP:默认子网掩码 :网络地址全为1,主机地址全0

255.255.255.0


A:192.168.2.1--->255.255.255.0

B:192.168.2.3--->255.255.255.0


判断能否进行通信:

先用主机的IP和子网掩码进行与操作(位操作)

A:192.168.2.0

B:192.168.2.0

  1. B在同一个网段,可以通信


A:192.168.2.1--->255.255.255.0

B:192.168.3.3--->255.255.0.0


A:192.168.2.0

B:192.168.0.0


  1. ->B发消息B的子网掩码和A进行与操作:192.168.0.0,和B在同一个网段,可以发送消息
  2. -A发消息

A的子网掩码和B进行与操作:192.168.3.0,和A不在同一个网段,发送消息显示主机不可达

进行ping命令,ping不通

C高级_共用体_44



网关

Gateway


网关的作用:不同网段的主机如果需要通信,就需要借助网关(网间连接器)

默认的网关192.168.x.1---》x是主机所在的网段

C高级_shell脚本_45



DNS服务器

域名解析服务器


域名相当于是网址


在计算机中存在域名服务表,这个中将IP地址和域名进行对应,输入baidu.baidu.cn

Baidu.com都会跳转到www.baidu.com,然后将这个域名进行解析。


一个IP可以对应多个域名,一个域名只有一个对应的IP



SHELL

外壳,保护,跟外界交互的桥梁

C高级_shell脚本_46


这个是命令行提示符,需要在这里输入命令

执行命令之后,系统会给出相应的操作---》交互

Shell是什么?


C高级_shell脚本_47


Shell在系统当中叫命令行解释器,在/bin里面有所有的命令。


解释?

将在命令行提示符输入的字符串,去/bin目录下找同名的字符串,如果找到,那么就进行对应的操作,如果没有 command not found(去/bin找文件,而不是翻译成01二进制)


Bash?

Bash是一个进程,打开一个终端就会有一个bash产生

查看当前所有运行的进程

C高级_shell脚本_48



C高级_结构体_49



内核:linux是内核,乌班图才是linux操作系统,以一个操作系统的组成需要 :内核+实用程序+文件系统。

内核管理

磁盘管理

网络管理

进程管理

硬件管理


内核进行管理的时候一定有对应的设备,这些设备或者应用程序就是系统开发公司进行开发的,和内核相互匹配,构成一个完整的操作系统



SHELL命令

名称选项参数


选项参数可省,名称不可省



  1. 用户命令

Sudo su root

Su root

Su-


添加用户

C高级_shell脚本_50


判断用户有没有添加成功需要看 /etc/passwd,如果当中存在,说明用户存在






Cat

在终端上查看当前文件的内容

Head/tail + 文件名 查看文件头/尾 十行的内容

More/less

More和cat相似 less之后会显示当前文件的内容,不会显示命令行提示符



Grep 查找(查找已知文件内部的内容)


Grep+ 参数+需要查找的内容 + 路径/文件名

参数

-n:显示所查找的内容

-v:显示除了所查找的内容之外的所有内容

-c:显示查找内容的行数

-R:查找内容的行数,并标红

C高级_shell脚本_51


C高级_共用体_52


Grep只适合查找已知文件内部的内容






Find 查找(查找文件具体的名字)

C高级_共用体_53


如果文件不存在,会显示,并且还会显示所查找路径下的所有内容


Find和grep一般合在一起使用

C高级_共用体_54


C高级_结构体_55


根据文件的名称进行查找


Find + 路径 + -name + 文件名---》显示路径下所有查找的同名文件

查找命令具体的用法: man 1 命令名称







Chmod

更改文件的权限/文件夹的权限


Chmod + 权限 + 文件名

C高级_共用体_56


1+3+3+3

1:文件的属性

b:块设备文件

c:字符设备文件

d:目录文件

-:普通文件

l:链接文件

s:套接字文件

p:管道文件


第一个3:用户组的权限rwx ---》111

第二个3:用户的权限rwx--》111

第三个3:其他用户组的权限r-x--》101


111文件夹的权限:775

C高级_共用体_57


一个文件夹最大的权限是d rwx rwx rwx--->777,但是新建一个文件夹的权限是775,因为有文件掩码的存在,用最大权限-文件掩码 = 新文件夹的权限


新建一个文件的权限是664,因为文件夹的最大权限是777-文件掩码,得出来的文件夹的权限,给奇数位减1,偶数位不变,得到的就是文件的权限。

C高级_结构体_58


文件掩码存在的意义:不让初始的文件夹权限过大



文件夹的权限一般给775,文件的权限一般给664


C高级_结构体_59


绿色文件不仅是可执行文件,权限最高的文件也是绿色,命令也是绿色


数字标记法

Chmod + 权限 + 文件名 权限:000~777,但是文件的权限要给奇数位减1,所以是666


字符标记法

用户:u

用户组:g

其他用户组:o

所有:a


Chmod u+x 1.c --->给用户增加可执行的权限

Chmod a-r 1.c ---> 给所有用户都取消可读的权限



Tar

C:打包

X:解包

V:可视化

F:指明打包的文件名

J:调用打包工具为bzip2

Z:调用打包工具居委gzip


Tar -cvf 1.tar 1.c 打包

Tar -xvf 1.tar -C 路径 解包到指定路径



Tar -cvzf 1.tar.gz 1.c 打包并用gzip压缩

Tar -xvzf 1.tar.gz -C 路径 用gzip解压缩


Tar -cvjf 1.tar.bz2 1.c 打包并用bzip2压缩

Tar -xvjf 1.tar.bz2 -C 路径 用bzip2解压缩


Ln

创建软硬连接

软连接 ln -s 源文件(绝对路径/相对路径) 目标文件

C高级_shell脚本_60


硬链接 ln 源文件(绝对路径/相对路径) 目标文件


C高级_共用体_61




C高级_结构体_62


C高级_结构体_63


软连接文件相当于一条指向源文件的路径,inode不一样,是两个文件

硬链接文件相当于给源文件起了别的名字,但是都属于同一个文件,因为源文件和硬链接文件的inode一样。





环境变量env



在命令行提示符输入env,会出现当前的环境变量类似于makefile里面的CC=gcc

C高级_共用体_64


取某一个变量具体的值,但是要加上echo,echo(命令)相当于C语言里面的printf(库函数)(输出)


更改环境变量

C高级_shell脚本_65


./是指明可执行文件所处的位置

C高级_结构体_66


如果不加./,那么就会去PATH所添加的路径当中寻找一个叫a.out的可执行文件


此时就是用a.out来执行代码,需要更改PATH

更改PATH

  1. 临时修改( 绝对路径修改)Export PATH=/home/linux/23091:${PATH}--->${PATH}
    临时修改实在某一个终端上进行的,取消临时修改只需要关闭修改过的终端
  2. 永久修改

修改配置文件

拉到最后一行,添加临时修改PATH的命令

再修改的终端上查看PATH,不会显示修改后的结果,但是重新打开终端之后,PATH会变成修改过的PATH


取消永久修改

Vi ~/.bashrc ,然后删除添加的临时修改的语句


软转义和硬转义

对于env来讲(PWD)


软转义:输出特定字符内部的内容${PWD}--->两个意义相同,都输出/honme/linux

硬转义:输出特定的字符${PWD} echo $PWD---->${PWD}/$PWD

C高级_shell脚本_67



对于带有特殊含义的字符


硬转义:需要给输出的字符加上单引号,输出的内容就是单引号引起来的内容(不管所写的字符有没有特殊含义,都会原样输出单引号内部的内容)

软转义:加上双引号或者什么都不加,对于字符,会输出字符所代表的特殊含义

对于普通的字符串

软转义(不带引号)

C高级_共用体_68


软转义(带双引号)

C高级_shell脚本_69







硬转义

C高级_shell脚本_70


对于硬转义,单引号里面是什么,就输出什么



特殊字符

通配符

*:匹配任意符合要求的长度

C高级_结构体_71


?:匹配符合要求的一个长度

C高级_结构体_72


[abc]:匹配中括号内部符合要求的一个长度

C高级_共用体_73


[^abc]:匹配除了符合要求之外的其他文件(一个长度)

C高级_共用体_74




管道

|


Command 1 | command 2 | ......| command n


将管道前的一个命令的输出,当作后一个命令的输入


Sudo apt-get install cowsay/fortune-zh

C高级_共用体_75


C高级_结构体_76


Fortune-zh是将古诗输出到终端上,但是现在需要将它输出到牛里面。

先将古诗输出,然后作为输入给牛,就需要用到管道




在.c文件内部去查找printf语句


  1. 找.c文件 find ./ -name *.c
  2. 查找printf语句 grep -n printf
  3. 两个命令通过管道结合

C高级_shell脚本_77


不出现结果的原因:

管道是将前一个的输出,当作后一个的输入,但是grep不需要输入,需要的是参数


Xargs----》将前一个的输出格式化成一行,当作参数传递给后一个命令

Find ./ -name student.c 这个得到的是一个具体的文件名字,然后通过 | 传递给grep的时候,这个文件被当做输入了,输入具有不确定性,但是grep需要一个具体的文件名,所以将find找到的结果,通过xargs转换成参数,然后通过管道传递给grep



命令置换

``命令置换的符号

Command1 `command2`


将后一个的输出当作前一个的参数

C高级_结构体_78


加上管道和命令置换,如果要查找*.c文件,需要去掉-name


命令置换和管道的区别

C高级_shell脚本_79


Ls是将当前目录下的文件显示在终端上,加上管道将这些内容全部当作输入给wc -l,也就是说wc -l统计ls展示出来的结果里面的行数,将ls显示出来的文件,每一个文件名当作了单独的一行然后进行统计,统计出来21行(这个命令相当于给wc了21个字符串去统计行数)

C高级_shell脚本_80


Wc -l实现统计文件的行数,ls显示当前路径下的内容,通过命令置换将ls的结果当作参数一个一个给wc -l,让wc -l去统计ls显示出来的每一个文件的行数(将每一个文件都给wc统计一遍)






重定向

标准输入:stdin

标准输出:stdout


输入重定向:<

输出重定向:>


一般不使用输入重定向


为什么需要使用输出重定向?

将文件的内容可以快速的输入到另一个文件当中



>:目标文件不存在会创建,如果源文件不存在并且目标文件有内容,会清空目标文件(覆盖)

C高级_shell脚本_81













>>:追加模式,每一次重定向之后都会追加到目标文件原文本的后面。如果源文件不存在,使用>>,并不会清空目标文件原本的内容

C高级_结构体_82


C高级_共用体_83



  1. :将信息重定向到目标文件,不会出现内容,目标文件不存在会创建。如果源文件不存在,目标文件会存放错误信息

C高级_shell脚本_84

2>>:以追加的方式保存错误信息,正确信息不会覆盖错误信息

C高级_shell脚本_85



&>:保存正确和错误信息,会覆盖

C高级_共用体_86


&>>:保存正确和错误信息,会追加

C高级_shell脚本_87




SHELL脚本

bash解释器

解释shell命令,如果不指定解释器,那么shell脚本无法运行

shell脚本的写法

  1. 先创建一个后缀名为.sh的文件
  2. 声明解释器,书写代码
  3. 更改文件的权限为可执行
  4. 运行

C高级_共用体_88


.sh文件第一行只能书写#! /bin/bash


SHELL的基本语法

由shell命令和字符串组成


自定义变量

Shell是一个弱类型,没有数据类型的区分

C高级_shell脚本_89


取变量的值

${变量名} $变量名

位置变量

C高级_shell脚本_90


C高级_shell脚本_91




系统预定义变量

$#

$@

$*

$?

C高级_结构体_92


$@,$*:去掉可执行文件之后,剩余的内容

$#:去掉可执行文件之后,剩余的内容的个数

$?:上一行代码的瑞出状态,正常退出0


环境变量

Env查看环境变量

$取环境变量的值

修改方式:export PATH=路径:${PATH}




SHELL语句和程序

Shell语句:由shell命令组成的

shell程序:由shell语句组成


Shell语句的分类

说明性语句

注释 #+注释语句

#! /bin/bash ---》交代解释器的位置



功能性语句

read 相当于C语言的scanf

echo 相当于C语言的printf

C高级_共用体_93




算数命令


+ - \* / %


`Expr $a + $b`

Expr是算数命令,只要用到算数命令,就需要加expr

C高级_shell脚本_94


会输出 expr 10 + 20,因为echo要输出一个结果,那么就需要一个参数,将后一个当作参数给前一个命令,需要用到命令置换

C高级_结构体_95


C高级_共用体_96


Expr 数据1 算术运算符 数据2

四者之间都要用一个空格间隔开

如果要将整体进行赋值,需要加上命令置换,等号两边不能加空格


测试命令

以n1 和n2为例

测试命令的写法有两种

&&与命令表

||或命令表

Test n1 n2

[ n1 n2 ] --->数据和中括号之间必须要用空格间隔


测试整形

大于:n1 gt n2

大于等于:n1 ge n2

等于:n1 eq n2

小于:n1 lt n2

小于等于:n1 le n2

不等于:n1 ne n2


测试字符串

等于:n1 = n2

不等于:n1 != n2

字符串长度是否为零

字符串长度是否不为零


测试文件

普通文件: -f n1

目录文件:-d n1

链接文件:-L n1

测试可读:-r n1

测试可写:-w n1

测试可执行

测试存在并且长度不为零

测试n1是否比n2新 n1 -nt n2

测试n1是否比n2旧 n1 -ot n2


逻辑语句

与:and

或:or


Test n1 and n2

Test n1 or n2


[ n1 -a n2 ]

[ n1 -o n2 ]


结构性语句

结构特性语句和测试命令一般同时使用


1.

If 命令

then

命令表

Elif 命令

Then

命令表

。。。

Else

Then

命令表

fi

C高级_shell脚本_97


C高级_shell脚本_98



输入一个字符串,判断字符串是否存在,如果存在,判断是普通文件还是目录文件,如果是普通文件,先给这个普通文件的所有用户加上可执行的权限,并且输入一句话。如果是目录文件,在该目录下创建一个名为test.txt的文本文件,并输入一句话

C高级_shell脚本_99


文件名一定是一个字符串,判断文件是否存在,用-n

判断文件是否存在并且长度不为零

一个字符串可能是文件名,也可能是普通的字符串,首先要判断字符串是否存在,然后在字符串存在的基础上,判断这个字符串到底是文件名还是文件夹名





Case

Case 变量 in

模式)

命令表

模式)

命令表

模式)

命令表

模式)

命令表

.........

Esac

C高级_结构体_100


C高级_shell脚本_101


C高级_共用体_102


C高级_共用体_103


C高级_结构体_104


一个测试条件,只不过测试内部的条件要成立

C高级_共用体_105


两个测试,但是两个测试的条件都要成立

C高级_结构体_106


Case的参数只能是整数,并且经过算术运算之后,会自动取整



For

for 格式 in 格式表

do

命令表

Done

C高级_shell脚本_107


C高级_shell脚本_108


C高级_shell脚本_109


C高级_共用体_110


Seq的方式,可以给i的起始位置和结束位置来进行输入(read)

C高级_共用体_111


换成位置变量也可以,因为$a $b是从键盘获取值,而$1 $2是从命令行提示符传递的参数

C高级_结构体_112


C高级_共用体_113



While

while 命令

Do

命令表

Done

C高级_shell脚本_114


C高级_共用体_115


当while的测试命令为真,或者直接写true,那么while就是一个死循环。

找水仙花数

C高级_共用体_116


C高级_结构体_117


SHELL函数

SHELL函数也是函数,但是SHELL是一个弱类型,没有数据类型的区分,所以SHELL

函数没有形参


add()

{

Echo aaaa

Echo bbbb

}


如何获取shell函数的值?

  1. 命令置换Value=`add 参数1 参数2 ......参数n`

C高级_共用体_118


位置变量也是输入,只不过实在运行脚本的同时取给函数一个固定的值

C高级_shell脚本_119


Read输入,实在脚本运行途中,给函数固定的值

C高级_共用体_120


C高级_shell脚本_121


C高级_shell脚本_122


  1. 直接调用

Add 参数1 参数2......参数n

C高级_shell脚本_123


命令置换和直接调用输出时候的区别


命令置换将输出格式化成一行,当作参数传递给前一个,所以函数的调用结果显示的是一行,而直接调用显示的是三行

C高级_结构体_124



C高级_共用体_125


C高级_结构体_126




























【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
EkKYkcW6BgCZ
作者其他文章 更多

2023-11-02

2023-11-02