两阶段总结

1、C语言开发环境

Linux系统作为学习C语言的开发环境

环境安装:

1、Ubuntu Linux.7z----------虚拟机系统

2、VMware:VMware  Workstation 16 Pro 激活密钥.txt ; VMware-workstation-full-16.1.0-17198959.exe------虚拟机软件

3、安装VMware虚拟机.pdf----安装文档

1、安装虚拟机软件

2、在虚拟机软件中启用ubuntu系统

Ubuntu Linux.7z--解压

在vmware软件,打开虚拟机,选中

C语言环境:

ubuntu系统---->终端(terminal)

2、C语言基础

1、程序

程序:解决完成特定功能(任务)的流程步骤

计算机程序:让计算机去实现解决问题的步骤执行

计算机语言:计算机能够识别任务的内容(指令)

机器语言:使用0和1表示指令功能

汇编语言(助记符语言):把机器指令用助记符进行表示

高级语言:类似自然语言的编写方式

C语言:高级语言,适合嵌入式开发

2、C语言程序的编写编译

Linux中编写C语言程序

vim工具:在终端上编写文本文件内容----可以使用vim来写程序代码

vim:只是编辑器,类似于 windows 记事本,只负责写文本内容(程序内容)

vim终端的文本编辑器:创建、显示、编辑文本编辑器

vim操作:

vim:打开vim编辑

vim  +  xxxx文件名:使用vim 打开  xxxx文件

如果文件名不存在,创建一个新文件(临时)

vim操作文件,所有的操作都依靠键盘输入(键盘输入是:文本内容还是命令)

vim是多模式编辑器:

命令模式(默认):键盘输入(输入的任何内容),都是命令

插入模式:键盘输入,都是操作文本内容

底行模式:操作vim编辑器

插入命令

命令

作用

a

在光标所在字符的位置之后插入

A

在光标所在行的行尾插入

i

在光标所在字符的位置之前插入

I

在光标所在行的行首插入

o

在光标所在行的下一行插入(新建行)

O

在光标所在行的上一行插入(新建行)

定位命令

命令

作用

gg

跳转到第一行的开头

GG 或 ]]

跳转到最后一行的开头

nG

跳转到第n行

:n

跳转到第n行

0

跳转到光标所在行行首

$

跳转到光标所在行行尾

:set nu

显示行号

:set nonu

不显示行号

b

跳转到前一个单词的第一个字符

w

跳转到下一个单词的第一个字符

复制粘贴删除命令

命令

作用

yy

复制光标当前行

nyy

复制从光标开始的n行

p

把复制或剪切的n行,粘贴到光标下一行(新建)

dd

剪切光标当前行

ndd

剪切从光标开始的n行(删除,剪切不进行粘贴)

x

删除光标所在位置的字符

nx

删除光标所在位置后n个字符

nX

删除光标所在位置前n个字符

dG

删除光标所在行开始到文件末尾

:n1,n2d

从n1行开始删除到n2行结束

u

恢复,撤销

保存退出命令

命令

作用

:w

保存当前文件

:w  文件名

把当前文件额外保存一份为文件名,备份(另存为)

:q

退出当前文件

:q!

强制退出

:x(!)

(强制)保存且退出,x == wq

:a

所有文件

搜索替换命令

命令

作用

/查找内容

从当前光标位置开始查找对应内容,n:查找下一个,N:查找上一个

:%s/old/new

全文替换指定字符串,%s:代表全文,把old 替换为 new

:n1,n2s/old/new

从n1行开始到n2行结束,把old替换为new

r

替换光标所在位置的字符,然后输入的字符就是替换的字符

R

从当前光标开始,使用输入的内容替换当前行的内容

编译:把C程序翻译为计算机能够认识的指令(机器程序)

命令:gcc

gcc  xxx文件名----->编译:进行对应的转换

生成一个编译好的(计算机能够识别,执行的程序):a.out

执行 可执行程序 :

./a.out

3、关键字与标识符

1、关键字

关键字:在规范C语言时,用于表示一定的特殊含义的字符,只要在C程序中使用,就代表了一定的操作和含义,约定的具有特定功能的单词或字符

int:整数类型

if:选择条件

for:循环

C语言程序中,我们所定义的名字不能和关键字重名(一样)

2、标识符

标识符:在当前程序中设定的一些字符符号表示,表示一定的意义,代表一个定义的作用(我们自己所定义的字符符号含义),自己命名的符号

标识符的表示:

由字母数字和下划线构成,且只能以 字母或 下划线开始

A-Z  ,  a-z , 0-9 ,  _

合法标识符:

abc,a1,a2,o_k

非法标识符:

%abc,a$b,1a

4、数据类型

在C语言程序中,数据值都有对应的数据类型

C语言是一种静态类型语言

基本类型:

1、整型

10、-10、1、-101

2、浮点型(实型)

1.2、3.1415、-1.2

3、字符型

'a'、'#'、'0'

1、进制与转换

对于计算机而言,只认识 0 和 1

十进制表示:每位数据值范围:0、1、2、3、4、5、6、7、8、9

满10进1

120

二进制表示:每位数据值范围:0、1,计算机中存储数据以二进制存储

满2进1

0b110

八进制表示:每位数据值范围:0、1、2、3、4、5、6、7

满8进1

0110

十六进制表示:每位数据值范围:0、1、2、3、4、5、6、7、8、9、A(10)、B(11)、C(12)、D(13)、E(14)、F(15)

满16进1

0x110

整数十进制转二进制:除以2取余数,把余数按照从低位到高位依次表示

15

    /    2-------------1

         7

    /    2-------------1

         3

    /    2-------------1

         1

    /    2-------------1

         0

15-------->(0000.....000) 1111

小数十进制转二进制:乘以2 取整 取到规定的位数

0.2====>

0.2

   2

0.4-----------0

   2

0.8-----------0

   2

0.6-----------1

   2

0.2-----------1

== 0011 0011 0011 ......

= 0011 0011 00

0.25====>

0.25

     2

0.5-----------0

   2

0.0-----------1

== 01

二进制转十进制:二进制每一位的权 乘以 当前位的值  (权:以2为底数,以位数为指数幂)的累加和

10101 ====>

1 * 2^0 +  0 * 2^1 + 1 * 2^2 + 0 * 2^3 + 1 * 2^4

= 1* 1 + 1 * 4 + 1 * 16 = 1 + 4 + 16 = 21

十六进制转十进制:十六进制每一位的权 乘以 当前位的值  (权:以16为底数,以位数为指数幂)的累加和

7A======>

A * 16^0 + 7 * 16^1 = 10 + 112 = 122

十进制转十六进制:除以16取余数,把余数按照从低位到高位依次表示

234

    /    16---------10(A)

         14

    /     16--------14(E)

   0

234=====>EA

二进制转十六进制/八进制:把四位/三位 二进制转为一个十六进制位/八进制位,如果高位不够补0进行转换

10101010111====>16进制

0 101  0101  0111===> 5  5  7

10101010111====>8进制

010 101 010 111====>2 5 2 7

十六进制/八进制转二进制:

2、数的存储:

计算机以二进制方式(0、1)存储数据,但是数据中存在 正 负之分

有符号数:把数据中,最高位作为符号位,用0表示正数,用1表示负数

无符号数:数据中,所有位都是数据位,没有符号位,所有无符号数都是正数

计算机中存储数据是以  补码  格式存储

原码:数据的二进制格式

10:0   .....0000...   1010

-10:1   .....0000...   1010

反码:

正数:反码 == 原码

负数:在原码的基础上每一位(除了符号位)取反(1变为0,0变为1)

10:0   .....0000...   1010

-10:1   .....1111...   0101

补码:

正数:补码 == 原码

负数:在反码的基础上 + 1

10:0   .....0000...   1010

-10:1   .....1111...   0110

位:bit

一个单独的0或1 二进制----1bit

字节:byte

八位二进制---------1Byte    1B = 8bit

千字节:KByte---KB

一千个字节---------1KB       1KB = 1000B

3、基本数据类型

1、整型

整数存储

二进制,补码形式存储

整型:根据在计算机中设定的大小

short (int):短整型------16位二进制(16bit),2B

int:整型-------------32位(32bit),4B

long (int):长整型-------在32位系统大小为 32位(32bit),4B ;在64位系统大小为 64位(64bit),8B

long long (int):超长整型----64位(64bit),8B

有符号数:

(signed):有符号数,最高位为 符号位

无符号数:

unsigned:无符号数,没有符号位

32位无符号整数:unsigned int

16位有符号整数:signed short int--------->short

2、浮点型(实型)

浮点型存储:

二进制,补码形式存储

数据部分 + 指数部分

浮点型:设定类型大小

float:单精度浮点型---32位(32bit),4B,精度:6/7

符号位:1bit

阶码:8bit

尾数:23bit

double:双精度浮点型-----64位(64bit),8B,精度:15/16

符号位:1bit

阶码:11bit

尾数:52bit

定义 一个32位浮点数:float

3、字符型

对于字符型数据,在计算机中存储,依旧使用二进制 0 和 1表示

对于每个字符统一用一种标准的二进制来表示

在C语言中,使用 ASCII码来表示(小整数)

ASCII码表

Bin

(二进制)

Oct

(八进制)

Dec

(十进制)

Hex

(十六进制)

缩写/字符

解释

0000 0000

00

0

0x00

NUL(null)

空字符

0000 0001

01

1

0x01

SOH(start of headline)

标题开始

0000 0010

02

2

0x02

STX (start of text)

正文开始

0000 0011

03

3

0x03

ETX (end of text)

正文结束

0000 0100

04

4

0x04

EOT (end of transmission)

传输结束

0000 0101

05

5

0x05

ENQ (enquiry)

请求

0000 0110

06

6

0x06

ACK (acknowledge)

收到通知

0000 0111

07

7

0x07

BEL (bell)

响铃

0000 1000

010

8

0x08

BS (backspace)

退格

0000 1001

011

9

0x09

HT (horizontal tab)

水平制表符

0000 1010

012

10

0x0A

LF (NL line feed, new line)

换行键

0000 1011

013

11

0x0B

VT (vertical tab)

垂直制表符

0000 1100

014

12

0x0C

FF (NP form feed, new page)

换页键

0000 1101

015

13

0x0D

CR (carriage return)

回车键

0000 1110

016

14

0x0E

SO (shift out)

不用切换

0000 1111

017

15

0x0F

SI (shift in)

启用切换

0001 0000

020

16

0x10

DLE (data link escape)

数据链路转义

0001 0001

021

17

0x11

DC1 (device control 1)

设备控制1

0001 0010

022

18

0x12

DC2 (device control 2)

设备控制2

0001 0011

023

19

0x13

DC3 (device control 3)

设备控制3

0001 0100

024

20

0x14

DC4 (device control 4)

设备控制4

0001 0101

025

21

0x15

NAK (negative acknowledge)

拒绝接收

0001 0110

026

22

0x16

SYN (synchronous idle)

同步空闲

0001 0111

027

23

0x17

ETB (end of trans. block)

结束传输块

0001 1000

030

24

0x18

CAN (cancel)

取消

0001 1001

031

25

0x19

EM (end of medium)

媒介结束

0001 1010

032

26

0x1A

SUB (substitute)

代替

0001 1011

033

27

0x1B

ESC (escape)

换码(溢出)

0001 1100

034

28

0x1C

FS (file separator)

文件分隔符

0001 1101

035

29

0x1D

GS (group separator)

分组符

0001 1110

036

30

0x1E

RS (record separator)

记录分隔符

0001 1111

037

31

0x1F

US (unit separator)

单元分隔符

0010 0000

040

32

0x20

(space)

空格

0010 0001

041

33

0x21

!

叹号

0010 0010

042

34

0x22

"

双引号

0010 0011

043

35

0x23

#

井号

0010 0100

044

36

0x24

$

美元符

0010 0101

045

37

0x25

%

百分号

0010 0110

046

38

0x26

&

和号

0010 0111

047

39

0x27

'

闭单引号

0010 1000

050

40

0x28

(

开括号

0010 1001

051

41

0x29

)

闭括号

0010 1010

052

42

0x2A

*

星号

0010 1011

053

43

0x2B

+

加号

0010 1100

054

44

0x2C

,

逗号

0010 1101

055

45

0x2D

-

减号/破折号

0010 1110

056

46

0x2E

.

句号

0010 1111

057

47

0x2F

/

斜杠

0011 0000

060

48

0x30

0

字符0

0011 0001

061

49

0x31

1

字符1

0011 0010

062

50

0x32

2

字符2

0011 0011

063

51

0x33

3

字符3

0011 0100

064

52

0x34

4

字符4

0011 0101

065

53

0x35

5

字符5

0011 0110

066

54

0x36

6

字符6

0011 0111

067

55

0x37

7

字符7

0011 1000

070

56

0x38

8

字符8

0011 1001

071

57

0x39

9

字符9

0011 1010

072

58

0x3A

:

冒号

0011 1011

073

59

0x3B

;

分号

0011 1100

074

60

0x3C

<

小于

0011 1101

075

61

0x3D

=

等号

0011 1110

076

62

0x3E

>

大于

0011 1111

077

63

0x3F

?

问号

0100 0000

0100

64

0x40

@

电子邮件符号

0100 0001

0101

65

0x41

A

大写字母A

0100 0010

0102

66

0x42

B

大写字母B

0100 0011

0103

67

0x43

C

大写字母C

0100 0100

0104

68

0x44

D

大写字母D

0100 0101

0105

69

0x45

E

大写字母E

0100 0110

0106

70

0x46

F

大写字母F

0100 0111

0107

71

0x47

G

大写字母G

0100 1000

0110

72

0x48

H

大写字母H

0100 1001

0111

73

0x49

I

大写字母I

01001010

0112

74

0x4A

J

大写字母J

0100 1011

0113

75

0x4B

K

大写字母K

0100 1100

0114

76

0x4C

L

大写字母L

0100 1101

0115

77

0x4D

M

大写字母M

0100 1110

0116

78

0x4E

N

大写字母N

0100 1111

0117

79

0x4F

O

大写字母O

0101 0000

0120

80

0x50

P

大写字母P

0101 0001

0121

81

0x51

Q

大写字母Q

0101 0010

0122

82

0x52

R

大写字母R

0101 0011

0123

83

0x53

S

大写字母S

0101 0100

0124

84

0x54

T

大写字母T

0101 0101

0125

85

0x55

U

大写字母U

0101 0110

0126

86

0x56

V

大写字母V

0101 0111

0127

87

0x57

W

大写字母W

0101 1000

0130

88

0x58

X

大写字母X

0101 1001

0131

89

0x59

Y

大写字母Y

0101 1010

0132

90

0x5A

Z

大写字母Z

0101 1011

0133

91

0x5B

[

开方括号

0101 1100

0134

92

0x5C

\

反斜杠

0101 1101

0135

93

0x5D

]

闭方括号

0101 1110

0136

94

0x5E

^

脱字符

0101 1111

0137

95

0x5F

_

下划线

0110 0000

0140

96

0x60

`

开单引号

0110 0001

0141

97

0x61

a

小写字母a

0110 0010

0142

98

0x62

b

小写字母b

0110 0011

0143

99

0x63

c

小写字母c

0110 0100

0144

100

0x64

d

小写字母d

0110 0101

0145

101

0x65

e

小写字母e

0110 0110

0146

102

0x66

f

小写字母f

0110 0111

0147

103

0x67

g

小写字母g

0110 1000

0150

104

0x68

h

小写字母h

0110 1001

0151

105

0x69

i

小写字母i

0110 1010

0152

106

0x6A

j

小写字母j

0110 1011

0153

107

0x6B

k

小写字母k

0110 1100

0154

108

0x6C

l

小写字母l

0110 1101

0155

109

0x6D

m

小写字母m

0110 1110

0156

110

0x6E

n

小写字母n

0110 1111

0157

111

0x6F

o

小写字母o

0111 0000

0160

112

0x70

p

小写字母p

0111 0001

0161

113

0x71

q

小写字母q

0111 0010

0162

114

0x72

r

小写字母r

0111 0011

0163

115

0x73

s

小写字母s

0111 0100

0164

116

0x74

t

小写字母t

0111 0101

0165

117

0x75

u

小写字母u

0111 0110

0166

118

0x76

v

小写字母v

0111 0111

0167

119

0x77

w

小写字母w

0111 1000

0170

120

0x78

x

小写字母x

0111 1001

0171

121

0x79

y

小写字母y

0111 1010

0172

122

0x7A

z

小写字母z

0111 1011

0173

123

0x7B

{

开花括号

0111 1100

0174

124

0x7C

|

垂线

0111 1101

0175

125

0x7D

}

闭花括号

0111 1110

0176

126

0x7E

~

波浪号

0111 1111

0177

127

0x7F

DEL (delete)

删除

字符存储:

存储的字符对应的ASCII码,ASCII码就是整数,以二进制存储

字符类型:

char:字符类型--------8位(8bit),1B

字符类型可以当做整数进行操作:char 可以表示为 只有8位的整数

4、变量与常量

常量:在整个程序中都不会进行改变的数据

变量:在整个程序中可以进行变化的数据,在内存中存储数据后,空间中的数据值可以进行改变,变量在使用的使用需要有一个名字(能够找到对应的变量);变量是什么类型

对于变量而言,必须先有(定义),才能使用

变量定义:

存储类型     数据类型     变量名;

变量名:使用标识符来表示(相当于赋予了变量数据的含义)

存储类型:

auto:默认类型

通常可以省略,表示定义在栈区,由系统进行管理

static:静态类型

register:寄存器类型,存储到cpu中(通常等同于 auto)

extern:外部类型

变量初始化:

在定义变量时,为变量赋初始值

存储类型     数据类型     变量名 =  值;

5、输入输出

1、输出-打印

printf:由C语言标准所设计的输出功能,只要使用printf就可以实现输出打印(终端)

printf功能包含在 stdio.h中

所以要使用的话:#include

格式:

printf("要输出打印的内容   格式化字符1,格式化字符2 ", 输出列表);

格式化字符:作用就是占位 表示要打印对应的数据值,以% 表示

输出列表:格式化字符要打印的数据

格式化字符:%

格式字符

功能说明

d 或 i

以带符号的十进制形式输出整数(正数不显示+),i 是老式写法,现多用 d

u

以无符号的十进制形式输出整数

hd 或 ld 或 lld

分别以短整型 short、长整型 long、超长整型 long long 输出

o

以八进制无符号形式输出整数

X 或 x

以十六进制无符号形式输出整数,x 表示十六进制的a~f小写,X 则 A~F大写

f

以定点十进制小数形式输出浮点数

E 或 e

以指数形式输出十进制浮点数,e 表示 e 小写,E 表示 E 大写

G 或 g

根据数值自动采用 f 或 e 方式输出,区别在于会自动省去尾随的 0 或小数点

默认精度为 6

c

以字符形式输出,只输出一个字符

s

以字符串形式输出

p

输出指针的值或变量的地址值

格式化字符输出指定的位数:

%m.p格式字符:m 数据的宽度,p小数的精度

在输出中,如果要输出某些特殊字符,在字符编码上没有对应的字符表示,在C语言中,设计转义字符:把普通字符转义为特殊字符,特殊字符转义为普通字符

转义字符: \

回车换行:\n

反斜线字符:\\

\:续行符

字符

功能说明

ASCII

\a

响铃(BEL)

007

\b

退格(BS) ,将当前位置移到前一列

008

\f

换页(FF),将当前位置移到下页开头

012

\n

换行(LF) ,将当前位置移到下一行开头

010

\r

回车(CR) ,将当前位置移到本行开头

013

\t

水平制表(HT) (跳到下一个TAB位置)

009

\v

垂直制表(VT)

011

字符

功能说明

ASCII

\\

代表一个反斜线字符''\'

011

\’

代表一个单引号(撇号)字符

092

\”

代表一个双引号字符

039

\?

代表一个问号

034

\0

空字符(NUL)

0

\ddd

1到3位八进制数所代表的任意字符

000

\xhh

十六进制所代表的任意字符

三位八进制

2、输入-存储

scanf:输入功能,可以从键盘输入数据给变量

使用scanf 必须包含对应的头文件  #include

格式:

scanf("键盘输入匹配,格式化字符1,格式化字符2,",输入列表);

格式化字符:格式化字符位置匹配的内容输入到变量中

输入列表:列出要输入的变量

注意:如果是连续两个数值格式化字符,在键盘输入时需要隔开(空格、回车)

6、运算符

只要是使用运算符进行运算,都会有结果,且结果就在运算的位置

1、算数运算符

+:加法

-:减法

*:乘法

/:除法

%:取余数(整数运算)

进行运算时,如果是同种类型数据进行运算,则结果为对应的类型

隐式类型转换:

在进行各种运算操作,如果是不同的数据类型,会把不同的数据类型转换为相同的数据类型然后再进行运算(原则:精度低往精度高的类型转换),原数据不变

强制类型转换:

把数据的值取出,然后指定转换为某种类型,原数据不变

语法格式:

(要转换的类型)数据

2、关系运算符

<        小于

<=      小于等于

>        大于

>=      大于等于

==      等于

!=      不等于

关系运算符是进行比较运算,判断关系是否成立(比较左右两边的表达式是否满足关系),比较结果:成立为真(值:1),不成立为假(值:0)

注意:在进行运算时,如果有连续的多个运算符,单一运算符进行运算之后得到结果再与下一个运算符进行运算

注意:

浮点数a 和 b 判断相等

a - b > -精度  &&  a - b  < 精度

3、逻辑运算符

连接表达式,根据表达式的真 假,进行组合得到新的结果,结果也是 真(值:1)  假(值:0)

逻辑运算表示两个数据或表达式之间的逻辑关系,逻辑运算的结果也只有两个:真为1和假为0。

&& (与):

表达式1  &&  表达式2

如果表达式1为真,且表达式2为真,逻辑与 结果 为真(值:1),否则 逻辑与 结果为假(只要有一个表达式为假,结果为假)(值:0)------判断,表达式1 和表达式2 是否同时成立为真

截断原则:当表达式1 已经为 假(0),不会运算 表达式2

|| (或):

表达式1 ||  表达式2

如果表达式1和表达式2 都为 假,逻辑或 结果为 假(值:0),否则 逻辑或为真(只有有一个表达式为真,结果为真)(值:1)-----判断,表达式1和表达式2 是否同时都不成立为假(是否存在表达式为真)

截断原则:当表达式1 已经为 真(1),不会运算 表达式2

! (非):

!表达式

改变表达式的真假结果,如表达式为假,逻辑非 结果为 真(值:1),如表达式为真,逻辑非 结果为 假(值:0)

4、位运算符

位运算对数据中的对应的二进制位进行运算操作(不会涉及到符号位说法)

&(位与)

表达式/数1  &  表达式/数2

把数1的二进制 与 数2的二进制,对应的每一位进行与运算操作(两个数对应的位有0,为0,都为1,则为1,位运算规则为:1 & 1 = 1       0 & 1 = 0       1 & 0 = 0      0 & 0 = 0)

|(位或)

表达式/数1  |  表达式/数2

将两个运算量的各个相应位分别进行“或”运算操作(两个数对应的位,有1,为1,都为0,则为0,运算规则为:1 | 1 = 1       0 | 1 = 1       1 | 0 = 1       0 | 0 = 0)

^(位异或)

表达式/数1  ^  表达式/数2

将两个运算量的各个相应位分别进行“异或”运算(两个数对应的位,相同为0,不同为1,运算规则为:1 ^ 1 = 0       0 ^ 1 = 1       1 ^ 0 = 1       0 ^ 0 = 0)

~(位取反)

~数

将一个数据中所有位都取其相反值,即1变0,0变1,运算规则为:      ~1  -->  0         ~0   -->   1

<<(按位左移)

数据值 << 移动位数

将一个数据所有二进制位向左移若干位,左边(高位)移出的部分舍去,右边(低位)自动补零

>>(按位右移)

数据值 << 移动位数

将一个数据所有二进制位向右移若干位,右边(低位)移除的部分舍去,左边(高位)根据原最高位自动补值(原最高位为1:补1,元最高位为0,补0)

5、复合运算符

 复合运算符:可以使用 = (赋值运算符)和 其他的运算符(算数运算符,位运算符)结合使用

+=、-=、*=、/=、%=、|= 、&=、^=

变量  +=  表达式======> 变量 = 变量 + (表达式)

6、其他运算符

1、自增自减运算符

++ 、 --

变量++:先取变量的值,进行其他运算,然后变量 +1 ,使用变量时,使用+1之前的值

变量;

变量 += 1;

++变量:先把变量+1,然后取变量的值,进行其他运算

变量 += 1;

变量;

变量--

--变量

前缀:先自增自减后再参与表达式运算。

后缀:先参与表达式运算,后自增自减。

2、条件运算符(三元运算符)

运算符----   ?  :

条件表达式:

表达式1 ? 表达式2 :  表达式3

表达式1为真,执行表达式2,把表达式2的结果作为整个条件表达式的结果

为假,执行表达式3,把表达式3的结果作为整个表达式的结果

3、逗号运算符

逗号运算符

表达式1,表达式2,…,表达式n

依次运算操作每个表达式,把最后一个表达式运算作为整个逗号运算符的结果

4、sizeof运算符

sizeof(数值/类型):作用 计算数据 对应类型的大小,以字节表示

sizeof 运算符,计算类型、变量或表达式的空间大小(字节数)

sizeof(变量);

sizeof(表达式);

sizeof(类型);

7、运算符优先级

作业:

(1)输入两个数求和

(2)提取电话号码 在下列输入字符串中豪华单间出租,联系电话:13888888888

(3)求下列表达式的值  int  x=1,y=2,z=5;

x>0 && !(y==3) || z>5 --> 1&&!(y==3)|| z>5 --> 1&& 1|| z>5 -->1|| z>5 -->1

!(x+1>0) && y==0 ||z>0 --> !(1) && y==0|| z>0 -->0&& y==0 || z>0 --> 0 || z>0 --> 0||1-->1

x<0 || y==0 && z>0 -->0|| y==0 && z>0 --> 0&& z>0 -->0 &&0 -->0

x=y>z ? z>0? 5: y: 10; -->x=0 ? z>0? 5: y: 10; --> x=0?  1?5:y  :10; --> x=0? 5 :10;--> x=10 // 运算嵌套采用就近原则

(4)使用三目运算符,求x,y,z中的最大值

思考:

(1)输入一个整数,输出其二进制

(2)输入一个数,分解质因数

(3)输入一个数,判断是否为质数  只能被1和它本身整除的数

(5)使用三目运算符,判断输入的年是否为闰年

7、选择结构

根据实际的当前情况条件,选择性执行/选择性不执行某些功能内容

1、if...else选择结构

1、单分支选择结构

根据条件,如果满足条件 则 执行对应的功能操作代码,执行完后,然后继续往下执行;否则跳过对应的功能代码,继续往下执行

if(条件表达式)

{

语句块;

}-----{}满足if选择的范围语句块,如果语句块只有 一条 语句,则{}可省略

条件表达式:只计算表达式的结果为 真(非0) 或 假(0)

如果满足条件则执行语句块,否则跳过语句块

2、双分支选择结构

满足条件表达式,执行一段语句功能内容,不满足则执行另一段功能内容;之后继续往下执行

if(表达式)

语句块1;

else

语句块2;

如果满足表达式,则执行语句块1,否则执行else 语句块2

3、多分支选择结构

if(表达式1)

语句块1;

else if(表达式2)

语句块2;

else if(表达式3)

语句块3;

……

[else

语句块n;]

多种情况选择性执行一种,判断第一种是否满足,满足则执行,不满足则判断下一种是否满足,满足则执行,不满足则继续判断.....

注意:if选择,只看真假,经过各种运算得到 0 或者 非0 都可以

2、switch...case选择结构

switch选择结构,根据表达式的结果表示从多种情况进行选择,选择情况(表达式 == 情况)进行执行对应的语句块

switch (表达式)

{

case 常量表达式1:语句块1;break;//每个case 就是一个情况

case 常量表达式2:语句块2;break;

case 常量表达式n:语句块n;break;

default: 默认情况语句段n+1;[break];

}

注意:表达式和常量表达式 结果为 整型(因为要判断相等)

比较 switch 表达式   是否 等于  case 常量表达式 ,如果相等 则执行对应的语句块

default 表示 如果 switch 和case 比较所有都不相等,则执行default 默认语句块

当switch 表达式和 case 表达式 比较相等后则执行对应的语句块,同时所有的case 表达式都失效(则会从当前case 一直往后执行,直到swicth结束)

break:表示结束当前switch

8、循环结构

重复多次执行某个功能

1、while循环

表达式为真,则执行一次要重复的内容(循环体语句),再次判断表达式是否真,表达式位置,则再次执行一次要重复的内容,继续判断表达式,直到表达式为假,则跳出循环执行while的后面内容

while (表达式)-------条件,是否重复执行

{

循环体语句;------要重复执行的内容

}

表达式的初始条件值

条件表达式

循环中包含改变条件值

作业:

1、企业根据营业额发奖金,低于10万,按0.1%发放,高于10万低于20万,10万按0.1%发放,高于10万间按0.2%发放;高于20万低于30万,10万按0.1%发放,10-20万按0.2%发放,高于20万部分按0.3%;高于30万,按0.4%发放,请输入金额,计算发放奖金

2、一个整数,它加上100是完全平方数,在加上100的基础上再加上168又是另一个完全平方数,求这个数

3、统计所有的水仙花数

4、有一对兔子,从第三个月开始每一个月都会生下一对兔子,小兔子经过三个月,每个月也能生下一对兔子,如果兔子不死,则,每个月有多少对兔子(只用输出前40个月,第一个月1对,第二个月1对)

5、猴子第一天摘了n个桃子,第一天吃了一半+1个,第二天又吃了剩下的桃子的一半+1,之后每天都是吃了前一天剩下的一半+1,第9天吃了后只剩下1个,问第一天摘了多少

2、do...while循环

do...while循环:先直接执行一次循环体,条件表达式从第二次开始判断是否满足,执行

语法结构:

do

{

循环体语句;

}

while (表达式);

while与do...while 区别:while从第一次条件开始判断,do...while 跳过第一次条件判断,从第二次判断开始;do...while最少执行一次

3、for循环

语法格式:

for (表达式1;表达式2;表达式3)

{

循环体语句;

}

表达式1:在整个for循环之前执行一次,且只执行一次,通常用于在for循环初始化条件的值(可以不进行设置,相当于没有初始化,可能在其他之前位置设置)

表达式2:循环条件,每次执行循环体前,先判断条件是否成立(判断一次,执行一次循环体)(可以不设置,相当于 条件一直为真 1)

表达式3:每次在执行一次循环体后,就立即执行(先于下次的条件判断),通常用于设置改变条件(可以不设置,相当于在表达式3中无操作)

表达式可以省略,但是 ; 必须添加

4、循环的嵌套

在循环内部循环体语句可能包含另一个循环,叫做循环的嵌套

while()

{

循环体

for()

{

}

}

外层循环执行一次,内层循环执行完一遍

5、break与continue

1、break

break:break语句作用是结束当前这个循环,跳出当前循环

while()

{

break;-------从当前位置结束整个循环

}

2、continue

continue:提前结束循环中的本次循环,跳过本次循环体没有执行完的内容,直接进行下一次

while循环使用continue直接结束本次循环体内容,直接进行下一次条件判断

for循环使用continue直接结束本次循环体内容,但是由于for循环在结束一次循环后,会执行表达式3,所以continue结束时,跳到表达式3执行,进行下一次条件判断

作业:

1、一辆汽车以平均80公里的时速行驶了4个小时。编写并运行一个C语言程序,显示这辆汽车已行驶的距离(公里),每半小时一次,直到旅程结束。

2、输入 年月日:如2021-7-5 ,计算当前日期是这一年的第几天

3、打印9 * 9 乘法表

9、函数

函数:代码或代码块的集合,或特定功能代码的集合,把实现某种功能的代码单独实现形成一个整体,可以进行单独使用。就是一个独立的功能代码模块,在需要使用这个功能时,进行调用,就会去执行这个功能模块

库函数:由C语言标准实现的功能模块函数,编译器自带已经实现的函数

自定义函数:在程序中由于可能多次使用某个功能,自己实现这个功能模块函数,由用户对其进行定义,在其函数的定义中完成函数特定的功能,这样才能被其他函数调用

1、函数定义:

函数:包含两部分---函数头与函数体

函数头:

对函数的描述说明,表示某个函数----标记

3个部分:

返回值类型:函数功能结束,返回的结果是什么类型,表示有一个结果返回

函数名:标识符,表示这个功能的名字,之后就使用这个名字来标识使用这个功能函数

参数列表:在编写功能时不确定,需要在调用使用这个函数,传递的值

函数体:

功能模块的操作代码--功能的实现

定义:

返回值类型 函数名(参数列表)

{

函数体——函数实现特定功能的过程;

}

函数定义的四种格式:

1、无参无返回值

void:空类型,没有数据类型

void 不能定义变量

void  函数名()

{

函数体;

[return;]

}

没有返回值可以使用void修饰返回值类型

2、无参有返回值

返回值数据类型  函数名()

{

函数体;

return 表达式值;

}

有返回值在定义函数时就要给定返回值类型 如int float char

return:只要执行到return 语句,表示 函数功能到这里结束

return + 值:结束当前函数,同时把 值 返回,返回到调用位置(在调用位置得到函数的执行结果)

对于有返回值类型,在函数体中 必须包含 return + 值 语句

3、有参无返回值

void  函数名(参数列表):使用参数列表作为函数功能的输入,在编写函数功能时,存在不确定的一些数据值,使用参数列表来表示在定义函数功能时不确定;在使用时,根据参数列表情况,调用时传递参数列表实际的值

{

函数体;

}

参数列表格式:

数据类型1  变量名1,数据类型   变量名2,......

4、有参有返回值

返回值类型   函数名(参数类型1 参数名1,参数类型2 参数名2,...)

{

函数体;

return 值;

}

2、函数调用

在需要的位置使用这个函数功能,叫做函数调用,即:运行一次这段代码块

调用过程:

当调用时,跳转到对应函数位置进行执行函数功能,当函数执行完({}结束或return语句), 再跳转回调用位置,继续执行

1、无参无返回值调用

函数名()

调用无参函数,则没有参数列表,但小括号不能省略

2、无参有返回值调用

函数名()

调用有返回值函数,在调用位置就会得到函数返回结果

3、有参无返回值调用

函数名(参数的值1,参数值2,参数值3,......)

在调用时,参数值 需要和 函数定义的参数列表 一一对应

在调用时,会把参数值 赋值(传递)给  参数列表中的变量

注意:调用时,参数值 可能是变量,表示把变量的值传递给函数的参数列表,而不是把变量直接传递给参数列表

4、有参有返回值调用

函数名(参数值1,参数值2,参数值3,.....)

调用有返回值函数,在调用位置就会得到函数返回结果

定义有参函数时,给定的参数列表,在参数列表中的参数,叫做 形式参数(形参)

调用有参函数时,给定的参数值,叫做实际参数(实参)

3、函数的嵌套调用

在调用一个函数的过程中,被调用的函数又可以调用另一个函数

函数的定义是平行的、独立的,不允许嵌套定义

4、函数的声明

编译时提示函数是什么样子的函数(有无函数,函数有无返回值,有无形式参数列表)

如果在前面调用了函数,在后面位置才进行定义需要在调用前进行声明

函数声明 语法:

返回类型  函数名(形式参数列表);

写法:

返回类型 函数名(参数类型1,参数类型2,参数类型3....);

返回类型 函数名(参数类型1  参数名1,参数类型2  参数名2,参数类型3 参数名3....);

5、递归函数

函数中直接或间接调用自己这个函数,叫做函数的递归调用,当前函数也叫做递归函数

通常递归函数需要用结束条件,在函数内部加控制语句,只有当满足一定条件时,递归终止

10、全局变量与局部变量

1、局部变量

只要在函数内部定义的变量就叫做局部变量

函数的形式参数类似局部变量 ,与局部变量有相同的性质

性质:

生命周期:存储期限。变量的存储期限,在变量所在程序区块执行期间有效存储,区间结束或函数返回时,局部变量的值无法保留。

作用域:局部变量在定义所在的区域块内访问可达,离开区块不可访问。

程序块:用一对大括号{}括起来多条语句区域就是一个程序区块

2、全局变量

不在函数内定义的变量叫做全局变量

性质:

生命周期:存储期限。变量的存储期限,在整个程序运行期间都存在有效。

作用域:从变量被定义的点开始一直到所在文件的末尾都可以使用访问。

3、变量名的重名

在程序中,如果作用域相同则变量不能相同

在不同作用域时,允许定义相同的变量名,如果存在相同的变量则默认使用作用域小的变量进行操作

4、变量的默认值

当变量定义时,如果没有进行初始化时,变量的默认值:

局部变量:随机值

全局变量:默认初始化为0

5、static存储类型

static静态存储类型

static修饰局部变量:

延长生命周期为整个程序(程序结束变量的生命周期结束),但是作用域不变,只能在定义变量的作用域中使用(但作用域仍为局部)

当多次定义static 的局部变量时,只会定义第一次,之后都是跳过定义

static修饰全局变量:

设置为静态变量,只能在本文件内使用这个变量

static修饰的变量未初始化会自动初始化为0

练习:实现一个函数,计算指定范围内的质数

作业:

1、编写一个函数,输入多个字符,分别统计字母、空格、数字和其他字符的个数,打印分别的统计值

2、输入一个五位数,判断是否为回文数

3、实现函数输入x,y  打印 x和y 的公约数(公约数:就是都能整除的数,如  x = 9,y = 12,公约数为 3)

11、数组

数组:由多个数据组成一个数据集合,在集合中存在多个数据内容,数组是包含有多个数据值的数据结构,并且每个数据值具有相同的数据类型

数组元素:数组这个集合中的一个数据

1、一维数组

1、一维数组的定义

定义:

类型   数组名[数组长度];

类型:每个数据的类型

数组名:整个数据集合的名字

数组长度:数据集合中数据的个数

如:

int   a[4];

占用内存空间:类型 * 数组长度

以连续的内存空间创建数组,每个数组元素是相邻的

2、一维数组元素的访问

存取特定的数组元素,通过数组名在后边加上一个用方括号表示整数值(整数值:数组取下标、索引:从0开始的编号位置)

格式:

数组名[下标]

下标:下标值只能是整数或结果为整数的表达式,取值范围是 0   ~   数组长度 - 1

注意:如果下标 >= 数组长度 叫做越界,不能使用

3、一维数组的初始化

在定义一维数组时,可以对数组进行初始化,对数组进行初始化就是对数组的元素进行初始化

使用一个 {},在 花括号中,添加要对数组元素初始化的值

格式:

类型  数组名[元素个数] = {值1,值2,值3};

完全初始化:

类型  数组名[元素个数] = {值1,值2,值3 == 元素个数};

对数组中每个元素都进行初始化赋值,会按照值的顺序依次对数组元素进行初始化

float price[5] = {1,2,3,4,5};

部分初始化:

类型  数组名[元素个数] = {值1,值2,值3 < 元素个数};

按照顺序 依次初始化 数组中前几个值,未初始化 会有编译器初始化为0

float price[5] = {1,2,3}

指定初始化:

类型  数组名[元素个数] = {[下标] = 值1,[下标] = 值2,[下标] = 值3};

float price[5] = {[0] = 1,[4] = 2,[2] = 3};

在进行初始化时,由于会编写元素值,可以使用值的个数来表示元素个数,在定义的位置元素个数可以不写

类型  数组名[] = {值1,值2,值3};----虽然不写,但是有值的个数个元素

练习:在数组中输入10个数,找到数组中最大的元素以及存储的下标位置

2、二维数组

二维数组:一维数组的集合,集合中的数组元素是一维数组

例:二维数组有 5个一维数组元素,二维数组每个元素(一维数组)又包含8个数据

1、二维数组的定义

定义:

数据类型  数组名[常量表达式1][常量表达式2];

数据类型:一维数组的元素数据类型

常量表达式1:二维数组的元素个数(有几个一维数组)

常量表达式2:在二维数组中的一维数组的元素个数(一维数组中有几个元素数据)

当定义了二维数组,在内存中存储二维数组,是按照行顺序,即先存储第一行(二维数组第一个一维数组),在存储第二行(二维数组第二个一维数组)

2、二维数组的访问

数组名[二维数组下标]:二维数组中的某个一维数组

数组名[二维数组下标][一维数组下标]:二维数组中的一维数组的数据元素

3、二维数组初始化

把二维数组按顺序,从第零个一维数组依次进行初始化

数据类型  数组名[常量表达式1][常量表达式2] = {值1,值2,值3,....};

int a[2][4] = {1,2,3,4,5,6};

把二维数组,每个{}表示初始一个一维数组

数据类型  数组名[常量表达式1][常量表达式2] = {{值1,值2},{值3,.}...};

int a[2][4] = {{1,2},{5,6,7}};

对于二维数组初始化时可以不指定一维数组的个数

即:数据类型  数组名[][常量表达式2] = {};

int a[][3] = {1,2,3,4,5,6,7,8};-------有3个一维数组

1、Linux基础

shell命令、文件管理、服务器的配置(tftp、nfs)、shell脚本

1、什么是Linux

通常Linux就指代的是Linux内核:能够让计算机跑起来

Linux操作系统:

Linux内核 + 应用/系统软件  构成方便用户进行操作使用的系统

Linux内核 开源,支持多任务、多用户

Linux是免费开源的内核程序

Linux操作系统:

ubuntu

debian

deepin

red hat

centos

2、Linux系统体系架构

Linux内核

shell:命令解释器,通过shell提供内核的功能

文件系统

应用程序

1、内核

内核是linux系统中最底层,提供系统中核心功能并允许有序访问硬件资源

用于管理:

输入输出设备、进程的执行情况、文件系统的操作、内存管理

linux内核支持:

多任务、多用户

2、文件系统

文件系统就是用于组织和管理计算机存储设备上的大量文件

windows中使用NTFS文件系统格式

linux中格式多,目前通用EXT4文件系统格式

linux文件系统的逻辑结构(linux目录结构):

linux中 文件系统把文件组织为倒置的树,每一个文件夹(目录)当做树的分支

文件系统只有一个起始点叫做根: / ---根

Linux文件系统把一切所有内容都看做文件,Linux一切皆文件

Linux文件系统就是一个 树形的目录结构:

将 / 作为整个文件系统的起点,其他的所有目录都是从根开始

Linux文件系统存储文件:

/:根目录

/bin:存储系统中最常用的可执行程序

/boot:存储Linux系统启动文件

/dev:存储系统中的设备文件,包括硬盘、鼠标、键盘

/etc:存储系统配置文件,如passwd存储用户信息

/home:普通用户的家目录位置

/lib:存放共享库

/media:存储cd、软盘、usb临时读入的文件

/mnt:挂载的文件系统挂载点

/opt:作为可选程序和文件存放目录

/proc:当前执行的进程的文件存储目录

/root:超级用户的家目录

/sbin:作为扩展的,更多的二进制程序存储目录

/usr:标准库、第三方库存储目录

3、shell

shell叫做命令解释器,当执行程序时,把程序中的各种操作命令进行解释执行,通过命令解释器让内核执行对应操作,可以提供一种用户与操作系统交互的方式

shell命令

shell完成内核与用户之间的交互

shell命令:

向系统内核发出控制请求

shell解释器:命令解释器,将用户的命令解析为操作系统能够理解指令,实现用户与内核交互

shell命令的输入,在终端提示符,标识了命令的开始

终端提示符:

ubuntu@linuxmachine:~$

用户名分割符计算机名分隔符当前的工作路径用户权限

~:代表当前的用户的家(用户)目录

shell命令格式:

命令+选项+参数

command +[option]    +[argument]

command:命令,shell要解析的内容,要执行的内容

option:改变命令执行动作的类型,选项使用 - 表示,可以有多个选项

argument:命令作用(执行)的目标

有时,命令不一定要携带选项和参数,通常表示使用默认的选项和参数

man command:查询手册找打command使用说明帮助

绝对路径与相对路径:

路径:找到某个文件,所经过的目录就叫做路径

绝对路径:从根目录(/)开始所经过的目录,指文件在文件系统中的准确位置

相对路径:从当前的工作目录开始,找到文件所经过的目录,指文件在当前的相对位置

~:当前用户的家目录

.:当前工作路径

..:当前路径上一级路径

1、目录文件命令

pwd:用于查询显示用户当前的工作路径(用户在文件系统的位置路径)

pwd没有选项和参数

cd:改变用户当前的工作路径(改变工作目录)

cd新工作路径    切换当前的工作路径为新工作路径---新的路径必须要存在

cd------>cd ~

mkdir:创建目录文件,在指定路径下创建目录

mkdir创建目录路径

-p选项:如果父目录不存在则一起创建

rmdir:删除空目录

rmdir要删除的目录路径

ls:列出目录或文件的内容项

ls:列出当前工作目录的所有项内容

ls目录路径:查看对应目录所包含的项内容

选项:

-a:列出所有文件(包括隐藏文件)

-A:列出所有文件(包括隐藏文件,但是排除 . 和 ..)

-i:列出文件的inode号

-l:显示文件的详细信息(文件属性)

文件类型

文件权限

文件硬链接

文件所有者

文件所属组

文件大小

文件最后修改时间

文件名

-:普通文件

d:目录文件

p:管道文件

s:套接字文件

c:字符设备文件

b:块设备文件

l:符号链接文件

分为三组(每组三位):

       所属用户,

       所属组,

       其他用户

相同文件的数量

当前文件所属的用户(即按照第一组权限访问)

文件用户的组(即按照第二组权限访问)

当前文件的大小字节

最后修改文件的时间

目录权限:

r:能够查看目录中的文件-----ls

w:能够在目录创建、删除、修改文件

x:能够访问进入目录--cd

目录文件的硬连接数为子目录的个数

目录大小固定位4096

2、文件命令

cat:读取指定文件的内容(查看文件)

cat文件路径

-E:在每行结束末尾添加$

-n:添加行号

head:查看文件前几行

head文件路径

显示前10行

-n:显示n行

tail:查看文件最后几行

tail文件路径

touch:创建一个普通文件

touch文件路径1文件路径2 文件路径3

在对应路径(必须存在)下创建文件

如果文件名存在,则改变文件的最后修改时间

file:判断文件类型

file文件路径

diff:比较两个文件的不同

diff文件1文件2

cp:将文件拷贝到指定目录中

cp源文件路径目标路径

cp源文件路径目标路径/文件名

选项:

-r:拷贝目录(会把目录中的所有文件都拷贝)

mv:将源文件移动到指定目录中

mv源文件目标路径

mv源文件目标路径/目标文件名

rm:删除指定路径下的文件

rm文件路径

选项:

-r:删除目录

3、操作命令

链接文件:符号链接文件、硬链接文件

符号链接文件(软链接):创建一个快捷方式,操作符号链接文件就是操作员文件,但是删除符号链接对源文件无影响,删除源文件符号链接无法使用

ln-S源文件目标文件(符号链接文件--软链接文件)

硬链接文件:在文件系统中,创建一份与源文件完全一致的文件,创建的文件和源文件一致保持一致,但是删除其中一个文件对另一个文件无影响

ln源文件目标文件(硬链接文件)

修改文件权限(读、写、执行):执行命令的用户要求是对应要修改权限的文件的所有者,才能够修改(普通用户只有改修自己的所有文件的权限)

超级用户拥有改所有用户文件的权限

sudo:临时使用(获取)root用户身份(管理员权限)来执行指定命令

chmod权限文件

权限:

用数字表示,9位二进制权限(用八进制表示)

用字符表示:

u+[r、w、x] 表示用户部分添加对应权限

u-[r、w、x] 表示用户部分删除对应权限

g+[r、w、x] 表示用户组部分添加对应权限

g-[r、w、x] 表示用户组部分删除对应权限

o+[r、w、x] 表示其他用户部分添加对应权限

o-[r、w、x] 表示其他用户部分删除对应权限

在创建文件时默认权限:

普通文件:0664

目录文件:0775

改变文件的所属用户:只有管理员root才能修改

chown用户名文件

改变文件的所属用户组:只有管理员身份执行

chgrp用户组文件

linux压缩与解压:tar

压缩:先进行归档合并为一个文件,再进行压缩

解压:先进行解压操作,然后对归档文件进行释放

归档文件

创建归档文件:把多个文件打包成一个文件

tar-cvf归档文件名.tar文件1   文件2   文件3   文件4....

释放归档文件:把归档文件中打包的文件释放出来

tar-xvf归档文件名.tar

压缩与解压:

使用gzip算法对文件进行压缩与解压:-z

压缩:把多个文件先归档打包成一个文件然后使用gzip算法进行压缩

tar-cvzf压缩文件名.tar.gz文件1   文件2   文件3   文件4....

解压:

tar-xvzf压缩文件名.tar.gz

使用bzip2对文件进行压缩与解压:-j

压缩:

tar-cvjf压缩文件名.tar.bz2文件1   文件2   文件3   文件4....

解压:

tar-xvjf压缩文件名.tar.bz2

使用zip算法进行压缩

zip压缩文件名.zip  文件1   文件2   文件3   文件4....

使用zip算法进行解压

unzip压缩文件名.zip

输出重定向

>:指定输出到某个文件,会先清空对应位置的内容

>>:指定输出到某个文件,以追加方式输出到指定位置

输出到终端  >  文件

输出到终端  >>  文件

4、用户管理

用户管理:

修改用户密码:

passwd用户名-----只能修改当前用户的密码

提升为管理员身份修改用户密码

sudopasswd用户名

切换用户:

su用户名

退出当前登录用户:

exit

创建新用户:只有root用户才能新建

sudo adduser新用户名

新建用户无sudo权限

如果需要添加sudo权限,则在sudoers 添加 新用户名

sudo vim/etc/sudoers

在文件最后添加:

新用户名    ALL=(ALL:ALL) ALL

删除用户:管理员删除

sudouserdel-r用户名

创建用户组:

sudogroupadd用户组名

将用户添加到用户组

sudogpasswd-a用户名用户组

查看用户对应的用户组

groups用户名

将用户从用户组删除

sudogpasswd-d用户名用户组

删除用户组:

sudogroupdel用户组名

5、软件安装

1、直接执行二进制程序进行安装

2、软件包管理工具安装

解析 软件包,查找对应依赖环境,安装软件

debian linux 软件包机制-----解析.deb

red hat linux 软件包机制-----解析.rpm

a、本地离线安装(本地软件包管理)

dpkg:离线包管理

dpkg-i软件包名:安装软件

dpkg-r软件名

b、在线安装(在线软件包管理)

在线安装,在计算机中需要配置软件镜像源(软件从哪里下载)

/etc/apt/source.list  软件源地址列表

检查网络信息:

ping + ip地址或域名:查看是否与对应的ip地址或域名连通,测试网络连接是否正常

ifconfig:查询本机的网络信息(需要安装net-tools)

apt:在线包管理工具(apt-get)

apt就是用于获取、安装、编译、卸载、查询于一体的包管理工具,自动检查软件的依赖是否安装

apt软件管理使用:

sudo apt update:下载(获取)更新 软件源地址中的软件包列表

sudo apt install软件包名:下载安装对应的软件

sudo apt --reinstall install 软件包名:重新再次安装

sudo apt remove软件名:卸载对应的软件

sudo apt clean:清除下载的安装包

6、服务器安装与配置

1、nfs服务器

网络文件共享服务器:提供主机中目录用于共享,当客户端来连接这个服务器后,就可以使用我共享的目录

1、安装nfs服务器软件

服务器:nfs-kernel-server

sudo apt install nfs-kernel-server

2、修改nfs服务器的配置

因为服务器功能为共享 文件夹,所以要修改对应的共享文件夹目录

sudo vim /etc/exports-----nfs配置文件

添加:

/home/ubuntu/nfsserver       *(rw,sync,no_subtree_check)

/home/ubuntu/nfsserver:要共享的文件夹目录

*:允许哪些客户端的ip地址访问nfs服务器

rw:读写

sync:同步更新

no_subtree_check:不检查父目录权限

如果共享目录不存在,则创建对应目录,设置权限

mkdir目录路径

3、启动nfs服务器

设置服务器端口为监听状态(开启监听)

sudo service rpcbind start

启动nfs服务

sudo service nfs-kernel-server [start、restart、status、stop]

4、查看nfs共享的目录

showmount -e

5、客户端连接

linux:

mount  -t nfs 服务端ip:/home/ubuntu/nfsserver     /mnt 挂载位置

umount/mnt

windows:

连接:

mount \\服务端ip\home\ubuntu\nfsserver(绝对路径)  X:(挂载到windows哪个盘)

断开:(解除挂载)

umount X:

2、tftp服务器

tftp:文件上传下载服务器

tftp:tftp文件上传下载服务器功能,提供一个文件夹(目录),可以让其他的客户端从这个目录下载文件,或上传文件到这个目录

tftp服务器:

1、安装tftp服务器

sudo apt installtftpd-hpa

   tftp-hpa(客户端)

提供了服务端功能:上传、下载

2、配置tftp服务器提供的操作功能(修改配置文件)

sudo vim /etc/default/tftpd-hpa

文件内容:

TFTP_USERNAME="tftp"--------服务器程序名

TFTP_DIRECTORY="/srv/tftp"-------提供的可以进行上传下载的目录(只能把文件上传到这个目录和从这个目录下载文件)

TFTP_ADDRESS="0.0.0.0:69"------服务器的tftp程序的地址

TFTP_OPTIONS="-l -c -s"

3、启动tftp服务程序

sudo service tftpd-hpa start

restart

status

客户端进行上传文件到tftp服务器,从服务器下载文件

sudo apt install tftp-hpa

使用:

tftp服务端地址

tftp> put 文件名:上传文件

tftp>get 文件名:下载文件

tftp>q:退出tftp客户端

7、通配符

通配符

作用

例子

*(星号)

可以表示匹配任意的字符串

1*2.txt:表示可以匹配1开始以2.txt结束的所有名字:123456782.txt,1abc2.txt

?(问号)

匹配一个长度的字符(只一个字符)

file_?.txt:可以匹配 file_开始 中间只有一个字符,以.txt结束的名字:file_1.txt(可以),file_12.txt(不可以)

[匹配字符](方括号)

从方括号中取一个匹配字符进行匹配

file_[abc123].txt:只能匹配以file_开始,中间是[abc123]其中一个字符,以.txt结束的名字:file_a.txt(可以),file_5.txt(不可以)

[起始范围-结束范围](方括号)

从方括号中取一个对应范围内的字符进行匹配

file_[a-k].txt:只能匹配以file_开始,中间是a - k其中一个字符,以.txt结束的名字:

file_a.txt(可以),file_z.txt(不可以)

[^不匹配字符](方括号)

除了方括号中的字符,其他字符匹配一个

file_[^abc].txt:除了a、b、c字符其他字符可以进行匹配一个:file_1.txt(可以匹配),file_e.txt(可以),file_a.txt(不可以)

4、shell脚本(shell编程)

将shell命令按照一定的逻辑关系,顺序组织在一个文件中,组合成一系列完整的功能要求,执行文件,就可以其中shell命令按照对应的逻辑顺序执行

shell文件是以.sh作为后缀名

执行shell脚本(文件):

1、为shell脚本文件,添加可执行权限,按照可执行文件的方式执行

修改为包含可执行权限

chmod权限文件

可执行文件,怎么执行

可执行文件的路径+文件

/home/ubuntu/linuxC/day3/1.sh

./1.sh

2、使用对应的shell解释器来解析执行

在当前ubuntu安装使用的是bash shell解释器

bash文件名.sh

在shell文件中,通常先添加shell解释器的版本说明(使用哪种解释器)

#!/bin/bash:说明,使用哪种解释器来解析

shell语法:实现shell脚本的逻辑功能

1、变量定义

定义:

变量=值

引用变量:

$变量

在字符串中中可能会出现要使用变量名情况:

“”:会解析引用的变量

'':不会解析引用的变量

2、变量的输入

在shell脚本中,使用 read 表示 输入字符串 到变量中:

read变量1    变量2     变量3.....

shell脚本存在特殊变量,位置变量:

$1:获取执行shell脚本文件时,命令行传递的第一个参数

$2:获取执行shell脚本文件时,命令行传递的第二个参数

$3:获取执行shell脚本文件时,命令行传递的第三个参数

...

$9:获取执行shell脚本文件时,命令行传递的第九个参数

$@ /  $*:获取命令行传递的所有参数

$?:获取上一条命令执行的状态值,上一条命令执行成功$?的值为0,否则非0

3、条件判断

判断条件: test

字符串:s1,s2就表示字符串

s1 = s2 :判断相等

s1 != s2 :判断不等

-z s1 :判断字符串长度是否等于 0

-n s1 :判断字符串长度不为0

整数:a,b表示数字字符串

a -gt b :判断a 是否 大于 b

a -ge b :判断a 是否 大于等于 b

a -lt b : 判断a 是否 小于 b

a -le b :判断a 是否 小于等于 b

a -eq b :判断a 是否  等于 b

a- ne b :判断a 是否 不等于 b

文件测试:

-d filename:判断filename是否是一个目录

-e filename:判断filename文件是否存在

-f filename:判断filename文件是否是普通文件

-L filename:判断filename文件是否是符号链接文件

-s filename:判断filename文件存在且长度不为0

-r filename:判断文件存在且是否可读

-w filename:判断文件存在且是否可写

-x filename:判断文件存在且是否可执行

4、逻辑运算

条件1  -a 条件2 :逻辑与,多个条件都为真,结果为真

条件1  -o 条件2 :逻辑或,只要有一个条件为真,结果为真

!条件:得到条件取反

5、if选择结构

语法1:如果满足条件表达式,则执行命令,不满足就跳过

if  [   条件表达式  ]

then

命令

fi

语法2:如果满足条件表达式,则执行命令1,不满足则执行命令2

if  [  条件表达式 ]

then

命令1

else

命令2

fi

语法3:如果满足条件表达式1,则执行命令1,不满足则判断表达式2,满足则执行命令2,不满足则判断表达式3,满足则执行命令3,不满足则判断表达式4,.......直到最后一个条件为止

if  [  条件表达式1  ]

then

命令1

elif  [  表达式2 ]

then

命令2

elif  [ 表达式3 ]

then

命令3

....

elif  [ 表达式n ]

then

命令n

else

以上都不满足则执行

fi

6、循环

算数运算指令:expr

`expr  $1  +  $2`

while  [  条件表达式  ] ------ 当满足条件就执行一次

do

命令表

done

for  变量名   in    单词表-------如果变量名能够从单词表中取出一个值(单词),就执行一次循环

do

命令表

done

c语言for循环格式

for((循环初始语句;循环条件语句;条件改变语句))

do

命令表

done

函数:实现一个完整的功能步骤,需要时直接使用

函数定义:

函数名()

{

命令集合

}

函数调用:

函数名

函数参数:

如果函数定义需要参数 ,函数的()中不用写参数,使用位置变量$1,$2,$3.... 作为函数的参数,来传递参数值

函数调用时:

函数名参数值1   参数值2    参数值3,,,,,

函数返回值:

在函数中执行 echo 命令 输出显示,只要当调用时 有赋值,这时echo 为返回值

2、C语言高级

指针、构造类型、动态内存管理、多文件与关键字

1、指针

是直接访问内存的方式

内存地址:在内存空间中,对每一个字节都分配了一个唯一的编号,用于区别不同的位置。每个字节都有唯一的地址,用来和内存中的其他字节相区别

指针:在内存空间(定义变量)申请空间来存储地址,就叫做指针,也叫做指针变量

指针就是操作内存地址,使用内存地址

1、定义指针变量

指针变量:本质就是一个变量,存放的是一个内存地址

指针变量定义的形式:

指向数据类型     *  指针变量名;

指向数据类型:存储哪种类型数据的地址,指向哪种类型

指针变量:定义一个变量,用于存储地址,如果要存储哪种类型的地址,数据类型就是对应的类型

2、指针的使用

存储地址:

指针变量 = 地址(要求地址的空间能够使用)

变量的地址获取:通过 & 取地址运算符,得到变量的地址

指针变量 = &变量

指针变量访问内容:操作对应地址的数据,通过地址的方式访问数据

用变量名来表示代表变量中的值

用指针来访问变量:

*指针名   访问对应地址(指针存储的地址)的数据空间

int * p;

p = &a;

*p ; // ==== a  表示访问 p存储的地址(即a的地址),对应空间的空间

指针变量赋值地址:通过指针建立与对应内存空间联系

指针 取*:得到建立联系的内存空间的值

指针变量的初始化:

在定义指针变量时,进行赋值,就叫做初始化

类型 *  指针名 = 地址;

野指针:

指针记录的地址不明确(存储的地址不知道,或地址对应空间是否具有操作权限不确定),这种指针叫做野指针

野指针不需要直接进行 取 *

空指针:

指针记录的地址是NULL(地址:0x00),系统规定NULL地址不允许进行操作

只要操作就会报错

空指针通常表示,该指针当前不可用

万能指针:

void *  类型指针变量,可以存储任意类型的地址,也可以把指针赋值给其他的任意类型指针变量

void * 指针,指针存储地址,不能进行 取值操作(取 *),因为指向的类型未知不明确

3、指针的运算

指针 +  / -   整数,表示移动指针 指向 的位置

+:

指针 + 整数n

往地址增大方向,移动 n 个 指向(指针指向,指针存储哪种地址)的数据类型 大小

int * p;

p + 5 ==== >移动  5 * 4

指针 + n == 指针 + n * sizeof(指向类型)

-:

指针 - 整数

往地址减小方向,移动指针指向类型(指针存储哪种类型地址)的大小 * 整数大小

指针 - 整数 * sizeof(指向类型)

指针++:

先使用指针,然后 指针 = 指针 + 1

++指针:

先 指针 = 指针 + 1 ,然后再使用指针

指针--,--指针

指针 - 指针:

获取两个指针之间间隔多少个对应类型的数据

(指针 - 指针) / sizeof(指向类型)

4、指针与一维数组

一维数组是一段连续的空间存储多个数据元素,在数组中相邻的元素,间隔大小为每个元素类型的大小,即  &数组名[元素i] == &数组名[元素i-1] + 类型大小

指针能够进行运算,指针 + 1,移动一个数据类型的大小,即 指针 + 1 == 指针 + 指向类型大小

如果指针变量存储了数组中的元素地址,指针+1 ,就是数组中下一个元素的地址

指针与数组的操作方式:

可以通过指针访问整个数组

只要知道数组的起始地址(第零个元素的地址),就可以遍历整个数组

数组首地址:数组的起始地址,就是第零个元素的地址

int * p = &a[0];

*(p+n) == a[n]

在数组中,数组名 有个特殊作用。数组名就表示  数组的首地址

数组名,地址常量

int a[5];

a == &a[0]

数组首地址(数组名) + n:偏移n个数据元素大小

*(数组名 + n) == 数组名[n]

*(a + 3) == a[3]

基于数组名(常量地址),可以将数组名当做指针进行使用,除了不能赋值运算(a = a+1)

因为数组名可以表示数组首地址,而指针变量也可以存储数组首地址,在访问数组的操作时,指针变量和数组名作用一致,所以

数组名[n]:访问数组的n元素  ====  指针名[n]

int *p,a[5];

p = a;

p + n == a + n//等价

a[n] == *(p+n) == *(a+n) == p[n]

基于指针变量,可以将指针当做数组用,不能越界

字符串与字符数组

字符串:有多个字符组成一个连续且有序的字符序列

"abcdef"------字符串

C程序中,通过字符数组来存储字符串

字符数组通过访问数组中的元素,就是访问字符串(按照字符数组,每个元素单独访问)

如果需要整体访问字符数组中存储的字符串,要求在字符串结束的下一个字符位置存储'\0'

'\0'字符就表示 字符串的结束

字符数组存储字符串:

字符数组初始化存储字符串

char数组名[大小] = "字符串";

注意通常,在进行输入前把数组初始化全为'\0'

输入字符串到字符数组中

scanf("%s",数组名/首地址);

输出打印字符数组中的字符串

printf("%s",数组名);

常量字符串表示:

"acbde"-----常量字符串

在常量字符串中,在最后字符后默认包含'\0'字符

在程序中如果写出常量字符串,则常量字符串表示常量字符串的首地址(第零个字符地址)

如:“abccde”,得到就是字符串的首地址,地址常量

地址,指针类型,都是统一的大小,各个类型之间没有区别

32位机器:4B

64位机器:8B

练习:

1、在数组中有10个数,统计10个数的和(通过指针)

2、输入一个名字,计算是否存在 'x'字符(指针)

作业:

1、输入一个字符串,求字符串的长度

2、输入两个字符串到两个数组中,然后把两个字符串进行拼接

5、指针与二维数组

二维数组:二维数组中,每个元素是一个一维数组,在元素(一维数组)中,每个成员就是一个值

二维数组:

数据类型数组名[行][列]

行:有多少个一维数组

列:一维数组的元素个数

对于二维数组而言,数组名是整个二维数组的首地址,第零个元素的地址,二维数组的元素都是一维数组,即二维数组数组名表示其中元素,整个一维数组的地址。

int a[3][4];

a == &a[0];//a[0]是整个一维数组

由于a表示整个元素的地址(一维数组的地址),所以进行指针运算时,+1 ,加上 整个一维数组大小

a:&a[0],第零个一维数组的地址

a+1:&a[1],第一个一维数组的地址

a+2:&a[2],第二个一维数组的地址

a[0]:表示二维数组的元素零,第零个一维数组,a[0]是一维数组的数组名,在这个一维数组的首地址  

a[0] == &a[0][0]

a[0]+1 == &a[0][1]

a[1]:第一个一维数组,也是这个一维数组的数组名(首地址)

a[1] == &a[1][0]

a[1]+1 == &a[1][1]

注意:

a+1,表示移动二维数组的一个元素(一维数组)大小

a[0]+1,表示移动一维数组的一个元素(数据类型值)大小

数组指针:

是一个指针,指针用于存储整个数组的地址,指针的指向类型为数组

定义:

数组元素类型   (*  指针变量名)[大小];

int (*p)[4];//定义一个指针变量,指针变量存储 整个数组的地址(int [4])

数组指针和二维数组名是等价的,因为二维数组表示第零个元素(一维数组)的地址

int a[3][4];

int (*p)[4];

p = a;//&a[0]

p+1 == a+1 == &a[1]

*(p+1) == a[1]

*(p+1)+2 == &a[1][2]

*(*(p+1)+2) == a[1][2]

6、多级指针与指针数组

指针数组:

是一个数组,只是每个元素为指针类型

指向类型 * 指针数组名[元素个数];

int * p[5];

定义 包含 5个元素 每个元素为指针(int *)

int a;

p[2] = &a;

多级指针:

一级指针:存储变量的地址

二级指针:存储一级指针的地址:一级指针类型 * 指针名;

三级指针:存储二级指针的地址:二级指针类型 * 指针名;

......

指向类型   * 指针名;

int **p;

int * a[10];

p = a;

p+1 == a+1;

*(p+2) == a[2]

二级指针与指针数组名等价

作业:

1、定义一个字符二维数组,输入要存储‘#’号的个数,然后分别输入存储的位置,其他位置默认存储 ‘ ’空格字符

2、二维数组和数组指针

int a[2][3];

int (*p)[3] = a;

在以下每个表达式中,p = a,求表达式的含义

a[0]

a[0][2]

*p

**p

*a

**a

*p++

**(p+1)

*(p+1)+1

*(*(p+1)+1)

3、定义二维数组,输入数据,然后求每个元素中的最大值

4、字符串的替换,输入一个原字符串,然后输入要替换的起始位置,输入新字符串进行替换

7、指针与函数

指针作为函数的参数:可以表示变量的地址,或者是数组名/数组首地址,作用就是表示参数为地址

把地址作为参数进行传递

返回值类型  函数名 (指针参数1,指针参数2); 接受传递的是地址

调用:

函数名(地址,地址/指针);

如果是数组作为形式参数,会由编译器自动变为对应类型指针

int sumarray(int p[10],int length) p就是指针 int*

指针作为函数返回值:返回一个地址,把指针作为函数的结果返回

函数指针:指针存储是的函数的地址

函数的类型表示:

返回值类型(参数1,参数2,参数3,......);

int (int a,char b);-1

int (int a,int b);-2

int (int c,int d);-3

1和2是不同函数类型,2和3是相同函数类型

函数指针表示:

返回值类型(* 指针变量名)(参数1,参数2,参数3,......)

函数地址:

函数名就是用于表示函数的地址

函数指针 = 函数名;

调用函数:

通过函数指针进行调用

函数指针名(实参);

2、构造类型

由于基本数据类型不能满足需要,需要把多个的数据类型进行组合,共同表示新的复合数据,形成新的类型。构造新的数据类型的方式就叫做构造类型

1、结构体

使用多种数据类型作为成员,进行组合,构成的新的类型,就叫做结构体

声明结构体:结构体的类型表示

struct结构体名字

{

类型1 成员1;

类型2 成员2;

类型3 成员3;

....

};

在程序中添加一种新的类型,不占用内存空间,只是说明在程序中有一中新类型

定义结构体变量:

struct结构体名字  变量名;

对结构体变量的操作,就是对结构体变量的成员进行操作

结构体变量访问成员:

结构体变量名 . 成员名;

结构体变量初始化:

在定义结构体变量时,对其成员进行初始化

顺序对成员初始化:

struct结构体名变量名 = {成员1值,成员2值,成员3值,......};

指定成员初始化:

struct结构体名变量名 = { .成员名2 = 成员值,.成员名4 = 成员值,......};

结构体指针如何访问变量的成员:

结构体指针:

struct结构体名* 指针名 = 结构体地址;

访问方式:

指针->成员://访问结构体指针对应地址中的成员

(*指针).成员 == 指针->成员

结构体特殊的声明方式:

struct结构体名字

{

类型1 成员1;

类型2 成员2;

类型3 成员3;

....

}结构体变量名;--------在声明时同时定义结构体变量

struct

{

类型1 成员1;

类型2 成员2;

类型3 成员3;

....

}结构体变量名;--------在声明时同时定义结构体变量,但是之后不能使用这个声明进行定义变量

2、共用体(联合体)

使用多种数据类型作为成员,进行组合,但是使用同一段空间存储(多个成员共用一个空间),构成的新的类型,就叫做共用体

使用共用体的问题:同一时刻只能操作一个成员

声明共用体类型:

union 共用体名

{

类型1 成员1;

类型2 成员2;

类型3 成员3;

....

};

用法:共用体与结构体一致

3、枚举

枚举就是定义一种新类型时,这个类型能够取值的范围是确定的,通过这个定义的新类型把能欧取值的范围一一列举出来,这种类型就叫做枚举

声明枚举类型:

enum枚举名

{

成员1,

成员2,

成员3,

......

};

枚举类型中,每个成员就代表能够取的一个值

声明类型时,如果成员没有赋值,成员就等于上一个成员的值+1,如果成员1没有赋值则为0

定义枚举变量:

enum 枚举名变量名;

变量名 = 成员;

3、字符串函数

#include

   

//把src首地址的字符串,拷贝到dest首地址中

char *strcpy(char *dest, const char *src);

//把src首地址的字符串前n个,拷贝到dest首地址中

char *strncpy(char *dest, const char *src, size_t n);

//比较字符串s1 和 s2 是否相等,如果相等返回0,如果不等返回当前字符的差值

int strcmp(const char *s1, const char *s2);

//比较字符串s1 和 s2 的 前n 个字符 是否相等,如果相等返回0,如果不等返回当前字符的差值

int strncmp(const char *s1, const char *s2, size_t n);

//计算 s 字符串的字符个数(不算'\0'),返回值就是字符串的长度

size_t strlen(const char *s);

//把src字符串 拼接到 dest字符串后

char *strcat(char *dest, const char *src);

//把src字符串 前n个字符 拼接到 dest字符串后

char *strncat(char *dest, const char *src, size_t n);

4、动态内存

你可能感兴趣的:(linux)