C语言、Linux基础及C高级应用

一、C语言基础

1、程序

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

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

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

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

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

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

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

Linux中编写c语言程序

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

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

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

Vim操作:

      Vim:打开vim编辑

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

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

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

Vim是多模式编辑器 :

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

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

底行模式:操作vim编辑器

低行模式→esc、退格删除:回车(执行完成低行命令结束)→命令模式→输入插入命令I,a,o→插入模式

插入模式→键盘Esc按键→命令模式→shift + :→低行模式

插入命令:

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个字符

dG

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

:n1,n2d

从n1行开始删除n2行结束

u

恢复,撤销

保存退出命令:

:w

保存当前文件

:w 文件名

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

:q

退出当前文件

:q!

强制退出

:x(!)

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

:a

所有文件

搜索替换命令:

/查找内容

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

:%s/old/new

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

:n1,n2/old/new

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

r

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

R

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

3、关键字与标识符

1、关键字

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

2、标识符

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

标识符的表示:

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

      合法标识符:abc , a11 , a2 ,o_k

      非法标识符:%abc , a$b , 1a

4、数据类型     

基本数据类型
1、整型

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

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

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

       long(int):长整型------在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

       尾数:32bit

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

       符号位:1bit

       阶码:11bit

       尾数:52bit

定义一个32浮点数:folat

3、字符型

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

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

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

ASCII码表

字符存储

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

字符类型:

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

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

4、常量与变量

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

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

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

变量定义:

       存储类型  数据类型 变量名

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

       存储类型:

auto:默认类型

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

static:静态类型

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

extern:外部类型

5、输入输出

1、输出-打印

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

printf功能包含在 stdio.h中

所以要使用的话:#include<stdio.h>

格式:

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

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

2、输入-存储

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

使用scanf 必须包含对应的头文件  #include<stdio.h>

格式:

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

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

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

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

6、运算符

1、算数运算符

隐式类型转换:

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

强制类型转换:

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

语法格式:

        (要转换的类型)数据

2、关系运算符

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

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

3、逻辑运算符

4、位运算符

5、复合运算符

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

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

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

6、其他运算符

1、自增自减运算符
2、条件运算符(三元运算符)

运算符----   ?  :

条件表达式:

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

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

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

3、逗号运算符
4、sizeof运算符

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

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

7、选择结构

1、if...else选择结构

        1、单分支选择结构

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

        2、双分支选择结构

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

        3、多分支选择结构

2、switch...case选择结构

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

8、循环结构

1、while循环

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

{

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

}

2、do...while循环

do

{

循环体语句;

}

while (表达式);

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

3、for循环

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

{

循环体语句;

}

4、循环的嵌套

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

while()

{

循环体

for()

{

}

}

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

5、break与continue

1、break

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

while()

{

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

}

2、continue

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

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

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

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

11、数组

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

1、一维数组

1、一维数组的定义

定义:

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

类型:每个数据的类型

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

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

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

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

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};----虽然不写,但是有值的个数个元素

2、二维数组

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

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}};

二、Linux基础

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

1、什么是Linux

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

Linux操作系统:           

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

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

Linux是免费开源的内核程序

Linux操作系统:

      ubuntu、debian、deepin、red hat、centos

应用程序

2、Linux系统体系架构

1.内核

内核是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  @  linux machine  :            ~              $

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

shell命令格式:

             命令  +  选项  +  参数

command  [option]   [argument]

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

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

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

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

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

绝对路径和相对路径:

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

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

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

~:当前用户的家目录

.:当前工作路径

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

1-文件目录命令

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

      pwd没有选项和参数

cd:改变用户当前的工作路径

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

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

      mkdir 创建目录路径

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

rmdir:删除空目录

      rmdir要删除的目录路径

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

      ls:列出当前目录

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

      选项:

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

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

             -i:列出文件的inode号

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

2-文件命令

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

      cat 文件路径

      -E:在每行借宿末尾添加$

      -n:添加行号

head:查看前几行

      head 文件路径

      -n:显示前n行

tail:查看后几行

      -n:

touch:创建一个普通文件

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

      在对应路径创建文件

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

file:判断文件类型

      file 文件路径

diff:比较两个文件的不同

      diff  文件1  文件2

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

      cp   源文件路径  目标路径

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

选项:

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

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

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

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

      rm 文件路径

      -r:删除目录

2023.7.25

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  -cvf  归档文件名.tar   文件1   文件2

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

             tar  -xvf   归档文件名.tar

压缩与解压:

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

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

tar  -cvzf  压缩文件名.tar.gz  文件文件2  ….

解压:

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

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

压缩:

tar  -cvjf  压缩文件名.tar.bz2  文件文件2

解压:

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

使用zip算法进行压缩:

zip  压缩文件名.zip  文件名文件名2

使用unzip算法进行解压:

unzip  压缩文件名.zip

输出重定向

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

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

      输出到终端 > 文件

             输出到终端 >> 文件

  

4-用户管理

用户管理:

      修改用户密码:

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

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

sudo  passwd  用户名

              切换用户:

                            su 用户名

              退出当前登录用户:

                            exit

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

                            sudo  adduser 新用户名

                     新建用户无sudo权限

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

                            sudo  vim  etc/sudoers

                     在文件最后添加:

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

              删除用户:管理员删除

                     sudo  userdle  -r  用户名

用户组管理:

       创建用户组管理:

              sudo  groupadd  用户组名

       将用户添加到用户组:

              sudo  gpasswd  -a  用户名  用户组

查看用户对应的用户组:

       groups  用户名

将用户从用户组删除:

       sudo  gpasswd  -d  用户名  用户组

删除用户组:

       sudo  groupdle  用户组名

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配置文件

添加:

   /hom/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[restartstatus查看、stop关闭]

4.查看nfs共享的目录

      showmount  -e

5.客户端连接

      Windows:

             mount  -o  \服务端ip\home\ubuntu\nfsserver(绝对路径)  X

      断开:

             umount X:

      Linux:

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

2、tftp服务器

       tftp:文件上传下载服务器

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

tftp服务器:

1.安装tftp服务器

       sudo  apt  install  tftpd-hpa(tftp-hpa客户端)

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

sudo  vim  /etc/default/tftpd-hpa

内容:

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

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

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

TFTP_OPTIONS="--secure"----

3.启动tftp服务器

       sudo  service  tftp-hpa  startrestart/status

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

       sudo  apt  install  tftp-hpa

使用:

              tftp>put 文件名:上传文件

              tftp>get  文件名:下载文件

              tftp>q  :退出tftp客户端

4、shell脚本(shell编程)

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

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

执行shell脚本(文件):

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

             修改为包含执行权限

             chmod  权限  文件

             可执行文件路径+文件

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

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

             bash  文件名.sh

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

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

1.变量定义

定义:变量=值

引用变量:$变量

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

      ″ ″:会解析引用的变量

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

2.变量的输入

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

              read  变量1 变量2 变量3……

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

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

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

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

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

……

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

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

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

3.条件判断

       判断条件:test

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

              s1 = s2判断相等

              s1 != s2 :判断不相等

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

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

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

      a  -gt  b:判断是否大于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:判断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为返回值

三、C语言高级

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

1、指针

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

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

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

1.定义指针变量

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

指针变量的形式:

数据类型  *指针变量名;

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

2.使用指针

存储地址:

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

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

      指针变量 = &变量

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

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

用指针来访问变量:

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

      int  *p;

      p =&a;

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

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

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

指针变量的初始化:

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

      类型 *指针名 = 地址;

野指针:

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

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

空指针:

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

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

万能指针:

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

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

3.指针的运算

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

+(-):

指针 + (-)整数

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

eg:int *p;

      p+5 == >5*4

指针+(-)n  == 指针+n*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 数组名[20] = 字符串

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

输入字符串到数组中

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

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

     printf(″%s″,数组名)

常量字符串表示:

     ′abcde′------常量字符串

     在常量字符串中,在最后字符默认包括′\0′字符

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

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

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

32位机器:4B

64位机器:8B

5.指针与二维数组

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

二维数组:

      数据类型 数组名[][]

              行:有多少个一维数组

              列:一维数组的元素个数

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

       int a[3][4];

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

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

数组大小

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

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

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

a[0]:表示二维数组的元素0,第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  (*q)[4];//定义一个指针变量,指针变量存储

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

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;

多级指针:

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

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

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

……..

7.指针与函数

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

把地址作为参数传递

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

调用:

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

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

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

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

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

函数的类型表示:

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

函数指针表示:

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

函数地址:

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

函数指针=函数名

调用函数:

通过函数指针进行调用

函数指针名(实参);

2、构造类型

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

1.结构体

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

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

struct   结构体名字

{

     类型1 成员1

     类型2 成员2

     …..

}

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

定义结构体变量:

struct  结构名字   变量名;

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

结构体变量访问成员:

   结构体变量名.成员名;

结构体变量的初始化:

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

顺序对成员进行初始化:

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

指定成员初始化:

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

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

       结构体指针:

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

       访问方式:

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

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

结构体特殊的声明方式:

       struct  结构体名字

{

       类型1 成员1

       类型2 成员2

       ……

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

              struct

{

       类型1 成员1

       类型2 成员2

       ……

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

2.共用体(联合体)

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

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

声明共用体类型:

union 共用体名

{

   类型1 成员1

   类型2 成员2

   ……

}

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

3.枚举

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

声明枚举类型:

      enum  枚举名

{

       成员1

       成员2

       …..

};

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

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

定义枚举变量:

enum  枚举名变量;

变量名 = 成员;

3.字符串函数

a.拷贝(strcpy);b.比较(strcmp);c.计算长度(strlen)d.拼接(strcat)

4.动态内存

栈中变量,只要离开了变量的生命周期,变量就会由系统销毁释放

堆空间:有程序员在程序中,自己进行管理的空间,需要使用时进行申请,有自己进行释放销毁。空间的申请与释放都是由程序员在程序中指定,通过就叫做动态内存

申请空间:malloc(  )

释放空间:free(  )

5.关键字

const:

在定义变量时,使用const关键字修饰,变量不可修饰,作用类似于常量

      const  数据类型 变量名;

通常情况下const变量要进行初始化

const修饰指针变量时,有不同的用法:

a.指向类型 * const  指针变量名;

      表示指针不可修饰,但是指向地址中的内容可修饰

      指针变量不可改;*指针变量可修改

b. 指向类型  const  *  指针变量名;/const 指向类型 * 指针变量名;

      表示指针变量可以修饰,但是指向地址中的内容不修改

      指针变量可改;*指针变量名不可修改

c. const 指向类型 * const  指针变量名;

      指针变量不可改;*指针变量不可修改

static:

      修饰局部变量

      修饰全局变量

auto:

      自动类型,定义在栈中,有系统进行管理

register:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值