linux基础:c语言基础补习

 

 

C基础

一:linux基础 3

1Linux常用命令 4

2Vim编辑器 6

二:C基础 6

1、计算机的组成 6

2、计算机的数据表示 8

3C补习内容 8

4LinuxC的开发流程 8

5、程序的入口:main()函数 9

6、变量 9

7、基本数据类型(32位操作系统) 9

三:C基础(2 12

1. 常数如何描述 12

1〉作业:计算一个整数的二进制中1的个数(整数可为正为负) 14

4. 内存值如何查看 16

1〉作业:编写一个猜数字的软件 16

5.控制语句 17

1if要点 17

2〉作业:判断一年是否为闰年? 17

3switch语句 18

四:C基础(3 19

一〉技术点: 19

1. 溢出越界 19

2. ++ii++ 19

3. atoi() 20

4.十进制转十六进制: 20

二〉C语句 20

1.分支语句 20

1gotolongjmp 20

2switch语句 21

3Scanf-------从键盘获取数据 21

2.数据类型: 22

1enum----枚举 22

2void 22

351c------sbit 22

4char: 22

5〉字符串常量 22

3.内存: 23

1〉常量 23

2〉变量 23

3Static 23

4Const 23

六:C基础(5 23

1、二维数组 23

2、 字符数组 25

3、跟字符串相关的函数 26

1strlen 26

2strcpy 26

3strcat 26

4strcmp 26

1strcpy()-- 27

2> strcat()--- 27

3strlen()- 28

3> Strcmp 29

4Int型数组中的次大值 29

5〉打印ab对称图形 30

6〉二维字符数组排序 31

7〉寻找字符串中出现次数最多的字符 32

8〉字符串转换为int-----------已知int为正 33

9int(有正有负)转换为char 34

10〉查找特定字符 35

七:C基础(6 35

一〉一维数组: 35

二〉二维数组 36

三〉一维字符数组: 36

四〉二维字符数组: 36

五〉什么是指针 38

1.指针的定义 38

2、什么是指针变量 38

3、指针的初始化 39

4、指针的访问 39

5*C语言中的三种用法 40

6、指针的运算 40

1算术运算 40

2关系运算 40

7.指针与一维数组 41

六〉作业 42

八:C基础(七) 44

一〉计算机内存分布: 44

二〉二级指针 44

1.指针与二维数组 45

2.指针数组: 46

3.字符指针 47

三〉函数 48

四〉gdb调试工具 49

五〉static 50

六〉作业: 50

九:C基础(8 51

一〉结构体 51

1. 定义: 51

2、字节对齐 52

3、共同体 52

4、大小端 53

5Const 53

4、指针函数: 54

 

一:linux基础

 

什么是嵌入式:软件控制的硬件

嵌入式---一个定制的计算机

   所以:硬件和软件需要根据设备要实现的功能专门去设计

   也就是说嵌入式系统所需要的操作系统是可以被修改的

   linux系统是一个开源软件--可以免费得到源代码并且可以自由修改

 

学习软件:

1VNC   (同屏) server   viewr

2、飞秋

3VM(虚拟机)   虚拟的一台电脑,可以在这台虚拟的电脑上运行linux操作系统           

4ubuntu

 

  LinuxOS                       windows

  ubuntu                           windowxp

  redhat                             window7

  红旗                                 window10

 

 ubuntu每半年更新一次    04   10

 每两年更新一个长期版本(稳定)LST   

 

 Linux是一个开源的、多用户的、多任务的操作系统,要求必须以用户和密码去登录

 

shell:命令行解释器     用户和内核进行沟通的桥梁

   shell其实就是程序,程序提供给我们一个界面(终端),这个界面可以让我们输入命令 (shell命令)

    

 

1Linux常用命令

ctrl+alt+t:打开一个终端

命令行提示符-------》   用户名@计算机名:当前路径$

$:代表当前登录的用户是一个普通用户

#:超级用户,root用户,权限最高

su - 用户名:切换到该用户

ctrl+d:从超级用户切换回普通用户

pwd:查看当前路径

sudo:增加权限

绝对路径:从根目录开始的路径

相对路径:具体看参照物

windows的文件系统犹如一片森林,各自独立

Linux的文件系统犹如一颗倒置的树,所有的目录都在跟目录之下

ls:查看当前目录下的内容

ls 目录路径:查看该目录下的内容

ls -a:查看当前路径下的所有内容(包括隐藏文件   以.开头的文件叫隐藏文件)

ls -l :以长格的形式显示当前目录下内容的详细信息

 

drwxrwxrwx  6 linux linux    4096 Jun  9 20:14 A9Server

d:文件类型

linux下文件分为7种:

-     --------->普通文件

d   ---------->文件夹

p   ----------->管道文件

l    ----------->链接文件

b  ------------>块设备文件

c   ------------>字符设备文件

s   ------------->套接字文件

 

cd:切换目录路径

cd .. :退回上一级目录

cd ../..:退回上一级目录的上一级目录

cd -:返回上一次的目录路径

cd .:返回当前目录

cd ~(cd):快速返回家目录

 

ctrl+shift+'+':放大字体

ctrl + '-':缩小字体

安装中文:ibus-setup

ctrl+空格:语言切换

clear(ctrl+l):清屏

touch 文件名:创建一个文件(文件名可以多跟)

rm 文件名:删除一个文件

mkdir 文件夹名:创建一个文件夹

mkdir -p :连续创建多级目录

rmdir 文件夹名:删除一个文件夹(只能删除空文件夹)

rm -rf 文件夹名:删除一个文件夹

 

cp 被复制的文件名 目标路径:

cp -r 被复制的文件夹名  目标路径

cp -i  被复制的文件名 目标路径:提示是否被覆盖

 

mv 被移动的文件  目标路径:

mv 1.c 2.c   ------>2.c不存在则把1.c改名为2.c   存在则先改名然后覆盖

mv day1 day2 ----->day2不存在改名,存在移动

 

cat 文件名:查看该文件的内容(一般适用于比较短的

more 文件名:查看该文件的内容(一般适用于比较长的

按回车:一行一行的向下查看

q退出

 

sudo reboot:重启

sudo shutdown -h now:立即关机

sudo shutdown -h 20:20分钟后关机

chmod 777 文件名:把该文件的权限全都打开

Tab:自动补全

向上的箭头:上一次的命令

ctrl+c:结束当前进程

 

2Vim编辑器

vim 文件名:如果文件时存在的就直接打开,如果不存在新建该文件再打开

vim的三种模式:命令行模式、插入模式、底行模式

刚打开一个文件是命令行模式,命令行模式---》插入模式(按i)  插入模式---》命令行模式(esc) 命令行模式---》底行模式(shift+:

命令行模式:

i:从光标所在地方的前面开始插入

I:从光标所在的行首开始插入

a:从光标的下一个字符的前面开始插入

A:从光标所在行的行末开始插入

o:从光标所在的下一行(新建的行)开始插入

O:从光标所在的上一行(新建的行)开始插入

插入模式:在插入模式下才可以编辑文本

底行模式:(以:开始)

w    保存

q     退出

wq    保存并退出    :x      ZZ(命令行模式下)

wq!    强制保存退出

wq  文件名  以新名字保存的备份文件

set nu   设置行号

set nonu  取消行号

set hlsearch   设置高亮

range %s/str1/str2/g   range范围内所有的str1都替换成str2

/str  (命令行模式)    查找str

nyy:n代表行数(命令行模式下进行复制粘贴)

p:粘贴

ndd:剪切

u:撤销

=gg  (命令行模式下)自动调整格式

 

gcc编译器,gcc 2.c会默认生成可执行文件a.out,执行 :./a.out

gcc 2.c -o 2将可执行文件a.out改名为2,执行:./2

 

3.6 文本内容的删除操作;

x 一个字符;
#x 删除几个字符,#表示数字,比如3x;
dw 删除一个单词;
#dw 删除几个单词,#用数字表示,比如3dw表示删除三个单词;
dd 删除一行;
#dd 删除多个行,#代表数字,比如3dd 表示删除光标行及光标的下两行;
d$ 删除光标到行尾的内容;

J 清除光标所处的行与上一行之间的空格,把光标行和上一行接在一起;

 

二:C基础

1、计算机的组成

硬件

CPU:运算器、控制器控制从内存获取数据,与内存交换数据很快、寄存器

存储器:

内部:ROM(只读存储器) RAM(随机存储器,断电后数据易丢失)

外部:硬盘、U

输入设备:键盘、鼠标、麦克风

输出设备:显示器、音响、打印机

软件

系统软件:windows  linux   UNIX

应用软件: wps  qq

 

一台没有任何软件的计算机称为“裸机”。

 

储存1T是指硬盘的总容量为1TB太字节Terabyte),计算机存储容量单位,也常用TB来表示。1TB=1024GB==2^40字节

 

2、计算机的数据表示

数值数据    非数值数据

数值数据:二进制   十进制   八进制(0作为前缀,0~7)    十六进制(以0x作为前缀,0~f(F)

 

十进制转其他进制:除2/8/16倒取余

非数值数据:a'\n' '5'

 

3C补习内容

1)数据类型

基本数据类型:int   float   char

复合数据类型:数组、指针、函数、结构体

2)运算符

3)结构性语句

顺序语句

选择语句

循环语句

4)算法

求最大值    冒泡排序

4LinuxC的开发流程

输入一个数,求这个数是奇数还是偶数

1)分析建模

num

num%2==0---->偶数

num%2==1---->奇数

2)画流程图

a.输入一个数num

b.如果num%2==0,输出该数是偶数

c.如果num%2==1,输出该数是奇数

3)翻译成C代码

4)编译

5)运行

 

5、程序的入口:main()函数

int main()

{

return 0;

}

 

6、变量

在程序运行过程中其值可以改变的量

 

7、基本数据类型(32位操作系统)

int 4个字节)  [signed]int-2^31 ~ 2^31-1   unsigned int:0 ~ 2^32-1

short  2个字节)[signed]short:-2^15 ~ 2^15-1   unsigned short:0 ~ 2^16-1

long    4个字节)

long long   8个字节)

 

float:4个字节

double8个字节

 

char:1个字节  [signed]char:-128~127   unsigned char :0~255

看成是一个字节的int

列子:int a=’\101’;//0101;//0x41;//65

Float 1.4;//1.4=14*10-1

(浮点数存储:左边为符号   中间整数存储   右边指数存储)

指数存储占低8位,符号位占高八位

8、标识符的定义(变量名、数组名、函数名)

a.由数字、字母、下划线组成

b.首字母不能是数字

c.不能与关键字重名

d.尽量见名知意

 

9、关键字

关键字:32个   由系统定义的   全都是小写

      数据类型(用于定义变量或类型):char double float  int long  short struct union void enum(枚举型) longlong   signed  unsigned

      控制语句:break case continue default do  else for  goto if switch while  return

     存储类型:auto register  extern static  const

  其他类型:         

      sizeof:求所占内存大小(单位是字节)

      typedef:给已有类型取别名

      volatile:防止编译器优化的

关于volatile的意义,根据标准C的定义、volatile的目的是,避免进行默认的优化处理.比如说对于编译器优化的功能,如果从编译器看来,有些多余的代码的话,编译器就会启动优化程序,并删除一些代码,但是这在嵌入式系统中很有可能是关键性的处理,必须不能保证被编译器删掉,所以提供了Volitile来声明,告诉编译器无论如何都不要删掉我。

Extern volatile int event_flag;

这样声明event_flag全局变量的话,就不用担心event_flag 被优化掉,程序将按照设计来运行。

 

  

10、赋值运算符(从右到左运算)

=  =右边的值赋给=左边

num=8;   8赋值给num

 

11、标准输出函数printf()

(1)引入头文件   #include <stdio.h>

(2)调用函数

参数1:字符串

printf("helloworld");//把字符串里面的内容原样显示在输出屏幕上

printf("字符串+格式化符",多个和格式化符一样多的参数)

int num = 8;

printf("num = %d",num);

 

12、存储方式

正数:以补码形式存储

正数的原码、补码、反码都一样

char ch =127; 0111 1111

负数:以补码形式存储,最高位是符号位,正数是0,负数是1,剩下的都是数据位

char ch = 129;

1000 0001  (补码)

1000 0000

1111 1111   -127

补码转为原码:

a.先减1,再取反(数据位)

b.先取反,再加1

 

char ch = 128;---->%d  -128

1000 0000 (补码)

1111 1111

1000 0000 -128的原码)

 

13、算术运算符

注:用移位运算符代替算术运算符,效率最高

A=b%m-----a=b&(m-1)  a=b*2^n-----a=b<<n    a=b/2^n------a=b>>n

a=b/8*8+b%4 -> a=((b>>3)<<3)+(b&3)
 a=b*15 -> a=(b<<4)-b

+  -  *  /  %

%----》两边的表达式只能是int 或者 char

5/2=2   int/int=int   5.0/2 = 2.500000  float/int = float--->float/float=float

 

隐式转换:范围小----》范围大

int  +   float = float

int  +  short  = int

unsigned + signed = unsigned

float + double = double

 

unsigned a = 2;signed b = -5;

printf("%d",a+b);------>-3

0000 .... 0010 a的原码)

1000....  0101  (b的补码)

1111....  1011 (b的原码)  signed  ----> unsigned

1111....  1101 (a+b)     unsigned---->signed

1000....  0011

 

强制转换:(数据类型)变量名   (数据类型)(表达式)

float f =12.5;

(int)f;  %d--->12

f; %f--->12.5   在强制转换过程中,变量本身并没有发生改变

 

 

++:如果放在变量名前,先自加后使用;放在变量名后,先使用后自加

++如果单独成句,没有区别

注:不要在同一行使用多个++’‘--

三:C基础(2

1. 常数如何描述

#define X 65

65

0x41

0101

'\101'   ('\0' == 0)

 

2. 变量空间如何申请

(数据类型关键字: 1.要多大; 2. 如何使用此空间)

char

short

int

long

float

double

3. 如何表达运算

数学运算符(加减乘除)

+

-

*

/

==

%

 

示例: a的十位数(a/10%10

 

位运算符(比特位操作)

~

<<

>>

逻辑右移---unsigned

算数右移---[signed] xx

左移---有符号和无符号一样

 

 

----这个算数右移才对

&      (清楚某个bit位,保留必要字段) 掩码~(子网掩码)

清除掉abit na = a & ~(1<<n);

提取abit n: (a & (1<<n))>>n;

|       置位某个bit

abit n变成1a = a | (1<<n)

abit n开始的三个bit设置成任意值x0-7): a = a&~(7<<n) | (x<<n);-----当所要设置的三位数原来为111时,无论你想要设置为什么值‘|’后还为111,因此应先将这三位清0,再”|”,(想要修改连续2位时---3<<n0,以此类推)

 

1〉作业:计算一个整数的二进制中1的个数(整数可为正为负)

int main()

{

        int n=12;

        int count=0,i=0;

 

        while(i<=sizeof(int)*8)//int就是一个坑,不同系统字节不同

        {

                if(n&(1<<i))

                        count++;

                i++;

        }

        printf("%d\n",count);

        return 0;

}

//2

int main()

{

        int num=12,i=0,j;

 

        while(num)

        {

                num = num&(num-1);

                i++;

        }

 

        printf("%d\n",i);

        j=count_bits(num);

 

        printf("%d\n",j);

        return 0;

//3

include <stdio.h>

 

int main()

{

int a = 0xffffffff;

int bitn = 0,n=0;

//提取bit

While(n<=sizeof(int)*8)//不同操作系统数据类型所占空间不同!!!!!!!!!!!!!!!!!!

{

If(a&(1<<n))

{

n++;

Bitn++;

 

}}

 

printf("bits: %d\n", bitn);

 

}

 

 

^(扫雷应用)

a = a^b;

b = a^b;

a = a^b;

 

逻辑运算符(真与假)

&&:int i=0,j=0;

If(i++ && j++);   ---->i==1,j==0(逻辑判断第一个表达式逻辑为假,运行即中断)

||

?:

 

 

第二个#define定义的常量可读性更强

 

4. 内存值如何查看

 

Printf(“%d%d%d%d\n”,i++,++i,i++,i++);

1>逗号运算从右到左运算

2>i++先将i暂存在寄存器中然后自加,++i直接取加1后的值给i

1〉作业:编写一个猜数字的软件

        int x = rand()%100;//随机获取100以内的数

        int num;

 

        printf("input a number:");

        while(1)

        {   

          getchar();    

          scanf("%d",&num);

    

          if(num == x)

          {   

                printf("right\n");

                break;

          }   

          else if(num > x)

          {   

                printf("too big:");

          }   

          else

                  printf("too small:");

 

        }

}

 

5.控制语句

1if要点

A:注意区分ifa=1)与ifa==1

B:if语句中else总是与紧挨着的那个if配对,与书写格式的缩进无关,若要实行强制的配对,可用以下语句

If()

{if() 语句块1}

Else 语句块2

2〉作业:判断一年是否为闰年?

1:能被4整除但又不能被100整除

2:能被100整除又能被400整除

             int main()

{

        int year;

        printf("please input a year number:");

        while(1)

        {   

                scanf("%d",&year);

                if((year%4==0 && year%100!=0) || (year%100==0 && year%400==0))        

                {

                        printf("%d is a full year!\n",year);

                        break;

                }           

                else

                        printf("%d is not a full year!please input a another year:",year);    

                printf("\n");

        }

 

 

        return 0;

3switch语句

A:其表达式可以是整型 字符型 枚举型

Bdefault后的break可省略

4for语句

三个表达式都可以省略,但“;”不能省:注意省略的条件,当语句2省略时,如果循环中无goto,break,return则陷入死循环  

5break只能用在循环语句和switch语句中

注:如何使用break跳出多层循环-------使用flag(看门狗设置0/1,再通过判断真假来跳出循环)

6*求素数的三种方法
一:for(i=2;i<=(n-1);i++)
ifn%i==0i2n-1之间任取一个数,如果n能被整除则不是素数,否则就是素数
二:for(i=2;i<n/2;i++)
if(n%i==0) /*i2n/2之间任取一个数,如果n能被整除则不是素数,否则就是素数

三:for(i=2;i<(n=sqrt(n+i));i++)
if(n%i==0) /*i2sqrt(n)之间任取一个数,如果n能被整除则不是素数,否则就是素数,在下省了下面的输出步骤*/

/*在本程序中使用第三种方法来求解*/
#include <stdio.h>
#include <math.h>
int main(void)
{
int i; /*外循环*/
int j; /*内循环*/
int flag; /*素数标志,flag1则此数为素数*/
flag = 0;
//int n;
i = 2;
while( i <= 100)
{
j = 2;
flag = 1; /*假设此数为素数*/
while(j <= (int) sqrt(float(i)))
{
if(0 == (i %j))
flag = 0; /*根据第三种算法可知次数不为素数*/
j ++;
}
if(flag)
printf("%d\t",i);
i++;
}
printf("\n");
return 0;
}                            

四:C基础(3

一〉技术点:

1. 溢出越界

1〉、溢出:小容器装大东西 

  数据类型超过了计算机字长的界限而出现的数据溢出;

2〉、溢出可能原因:

   当应用程序读取用户数据,复制到应用程序开辟的内存缓冲区中,却无法保证缓冲区的空间足够时 (假设定义数组int array[10], 而在调用时使用array[11] 或存放的数据超过int类型容量等),  内存缓冲区就可能会溢出.

越界:使用的东西超过了本身的范围

比如你定义的A[3][3],这是二维数组,意为三行三列,其中第一行的元素有A[0][0]A[0][1]A[0][2](第二三行依次类推)在后面你调用这个数组中的元素时,如果你调用A[0][3],这样就应该算越界了,也就是超过定义数组的范围了,因为这个数组第一行最多到A[0][2]

 

2. ++ii++

Printf(“%d%d%d”,i,i++,++i);-----------(2,1,2)----i++当作i先放着,把表达式计算完后再将值赋给i

函数:先将表达式的值计算好了再传给参给函数

3. atoi()

函数原型:int  atoi(const  char*  nptr);

 

函数的用法:参数nptr字符串(且为数字字符串),如果第一个非空格字符存在,是数字或者正负号则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停

 

止转换,返回整型数。否则,返回零。

4.十进制转十六进制:

1:先取低四位-------a&oxf   2:右移四位-----a>>4

 

二〉C语句

1.分支语句

1gotolongjmp

Goto-----短跳转语句(作用域限定---只在一个{}以内有作用)---在硬件驱动时应用

Longjmp----c长跳转语句

2switch语句

-------case后的表达式为整型或字符型,,必须有default(可不用放在最后,但最好放在最后)

输入输出语句:

3Scanf-------从键盘获取数据

\n’敏感应与getchar()配对使用

*---抑制符(scanf(“%*d%c”,&s,&a)-----第一个数据接收        scanf("%*d%d%*d",&a,&a,&a);

        printf("%d\n",a);

4Gets()-------在如数组这样有界的数据操作时容易发生越界!!!!!!!!!!!!!

5Sscanf()-------可从字符串中获取想要的字符

Eg char arr[]={N: 100}

Int x=0;

Sscanf(arr,”%*s%d”,&x);----arr中提取100

Sscanf()atoi()的联系

6例子:猜数字游戏------rand()获取随机数,但一般比较大,根据需要利用%/来获取数据

7Printf()-------必须加‘\n’,打印首先输出在缓冲区中,有‘\n’时数据直接刷出缓冲区并打印到显示器上

\t----制表符(打印时以最优格式输出)

Eg:printf(“xxxxx\t1234\n”);

Printf(“xxxx\t123\n”);

8Puts()------专用打字符串,自带‘\n

Eg:while(1){

Sleep(1);

Printf(“ .......\n”);//putchar(r);fflush(stdout);(刷出缓冲区)

}

Printf(“\rh\re\rl\rl\n”)------’\n’---回到行首

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

Printf(“/r%d”,i);

Fflush(stdout);

Sleep(1);

}------------数据每隔一秒显示在行首

注:printf()---------------------打印前/背景颜色----应用:将调试信息分级别(红--error--waring--right

9Sizeof()--------运算符(求空间容量,编译器统计在编译阶段就获得)

10Strlen()--------一种算法(以0结束统计并结束)

Char a=”hello”;

Sizeof(a);-------6

Strlen(a);--------5;

Eg:void func(int arr[100])

{

Printf(“%d\n”,sizeof(arr));--------------4(int arr[100]--------地址(指针))

}

2.数据类型:

1enum----枚举(快速宏定义)-----依次为所列元素自动定为01.。。。

2void --------*:空指针

      ---------无:代表万能

351c------sbit(bit----资源有限)

----支持访问bit型,但无此数据类型,也无bool型,但有逻辑真假表示

4char:有符号字节变量

动作:越界------int  a[4]={0,0,1,2,3};-------有危险

:溢出-------char c=128;(数据越界)----有误差

Char c=500;char a=500;------------编译时:就将一个常量500放在了不可改变的内存中

运行时:将500的备份分赋给c,a;

5〉字符串常量-------不能被修改也不能被优化

3.内存:

 

1〉常量--------放在只读区(本身就存在不可修改,可在a.out文件中修改你想要改变的输出内容),编译时已经存在

2〉变量-------运行时才出现,常量备份给他,临时存在,可改

3Static--------放在data区,若在全局变量前加此关键字,则该变量只能被本文件使用

-----------------1〉作用域限定(全局变量或函数内)2〉申请data静态数据存储区

4Const-----(符号常量,常变量)------伪存储类型关键字

Egconst float g=9.8-------类似于将变量放在常量区

*((float*&g))= 10.1-----通过地址改值

Extern -----定义的变量可被其他文件使用

六:C基础(5

 

1、二维数组

//定义一个长度为4的数组,数组里面的每个元素又是一个长度为3int数组

int brr[4][3]; ----->数据类型:int [4][3]

brr[0] ~ brr[3] ----->数据类型:int [3]

brr[0][0] ~ brr[0][2] ----->数据类型:int

 

初始化:

int brr[4][3]={ {123}

{456}

{789}

{101112}}

int brr[][3]={1,2,3,4,5,6,7,8,9,10,11,12};

int brr[4][3]={{1},{2}};    brr[0][0] = 1    brr[1][0]=2

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

 

输入输出:

int brr[][3]={1,2,3,4,5,6,7,8,9,10,11,12};

brr[0][0] -----%d  printf("%d",brr[0][0]);

brr[0]:

for(j=0;j<3;j++)

{

printf("%d",brr[0][j]);

}

brr[1]:

for(j=0;j<3;j++)

{

printf("%d",brr[1][j]);

}

...

brr:

for(i=0;i<4;i++)

{

for(j=0;j<3;j++)

{

printf("%d",brr[i][j]);

}

}

 

2、字符数组

 

//定义一个长度为20的字符数组

char str[20];

 

char str[]={'h','e'};

char btr[20];

char str[20]={'h','e','l','l','o'};

char str[20]={"hello"};

char str[20]="hello";    sizeof(str)=20    strlen(str)=5;

字符串的特点:以'\0'作为结束标志

char str[]="hello";      sizeof(str)=6    strlen(str)=5

字符串的输入输出:

 

printf("%s",字符串的首地址) %s在输出的时候自动去寻找\0,遇到\0就输出结束

puts(字符串的首地址)//自动将\0转换成\n

gets(字符串的首地址)//遇到\n认为输入结束-------------容易发生越界,造成栈爆炸

scanf("%s",字符串的首地址)//遇到\n、空格、TAB键认为输入结束

Eg:char str[]=ab\n\012\\\””;

Printf(“%d”,strlen(str));-------------输出6

 

转义字符:

 

 

3、跟字符串相关的函数

1strlen   计算字符串的长度

int len = strlen(字符串的首地址)----\0作为结束标志

2strcpy    复制-------以字符串2\0作为结束标志

EGchar str[]={‘h’,’e’};btr[20];----即当字符数组全部初始化且不含’\0’时,strlen结果不一定正确

Strcopy(btr,str);--------------结果可能有误(strlen\0作为复制的结束标志而str中无’\0’)

strcpy(字符串1的首地址,字符串2的首地址)//将字符串2复制到字符串1里面去

//字符串1的空间必须足够大,返回值是字符串1的首地址

连缀调用:

strcpy(ctr,strcpy(btr,str));//str复制给btr,又将btr复制给ctr

3strcat   链接

strcat(字符串1的首地址,字符串2的首地址)//将字符串2链接到字符串1后面去

//字符串1的空间必须足够大,返回值是字符串1的首地址

连缀调用

strcat(ctr,strcat(btr,str)); //str链接到btr后面去,又将btr链接到ctr后面去

4strcmp    比较(ASCII码值)

"helloworld"   "hellokitty"

strcmp(字符串1的首地址,字符串2的首地址)

int n = strcmp(str1,str2);

if(n>0)printf("str1>str2");

else if(n<0)printf("str1<str2");

else printf("str1=str2");

自己实现以上函数:

5.重点练习

 

1strcpy()-------注意,当完成元素复制后,在目标串的最后,人为加上\0

 

 

 

2>strcat()--------------------最后手动加上\0

 

3strlen()----------\0结束

 

 

3>Strcmp

 

4Int型数组中的次大值

 

 

 

 

Strlen()------\0结束

Strlen(str1)不一定为5strlen(str2)也不一定为5(\0)

Sizeof(str1)=sizeof(str2)=5  strlen(str3)=strlen(str4)=6

部分初始化输入字符--strlen()结果正确

全部初始化输入字符---strlen 结果不一定正确

 

5〉打印ab对称图形

 

int main()

{

        int i,j,k,m,c;

 

        char ch='A';

        printf("input your lines:");

        scanf("%d",&m);

    

        for(i=0;i<m;i++)

        {   

                for(k=1;k<m-i;k++)

                {   

                        printf(" ");

                }   

                for(c=i;c>=0;c--)

                {   

                        printf("%c",ch+c);

                }   

                for(j=1;j<=i;j++)

                {   

                        printf("%c",ch+j);

                }   

                printf("\n");

        }   

}

6〉二维字符数组排序

#include <stdio.h>

#include <string.h>

 

int main()

{

char a[5][20]={"apple","banana","orange","pineapple","watermelon"};

int i,j;

char s[20]={‘\n’};

//通过比较大小排序

for(i=0;i<4;i++)

{

for(j=0;j<4-1-i;j++)

{

if(strcmp(a[j],a[j+1])>0)

strcpy(s,a[j]);

strcpy(a[j],a[j+1]);

strcpy(a[j+1],s);

}

}

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

{

printf("%s  ",a[i]);

}

printf("\n");

//通过比较长度排序

for(i=0;i<4;i++)

{

for(j=0;j<4-1-i;j++)

{

if(strlen(a[j]>strlen[j+1]))

strcpy(s,a[j]);

strcpy(a[j],a[j+1]);

strcpy(a[j+1],s);

}

}

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

{

printf("%s  ",a[i]);

}

printf("\n");

return 0;

}

7〉寻找字符串中出现次数最多的字符

 

#include <stdio.h>

 

int main()

{

int count=0,max=0,index=-1;//count 记录每个字符出现的次数,max出现次数最多的字符次数,index次数最多字符的下标

char a[]="helloworld";

int i=0,j=0;

 

for(i=0;a[i]!='\0';i++)

{

for(j=0;a[j]!='\0';j++)//查找每个字符出现的次数

{

count=0;

if(a[i]==a[j])

count++;

if(count > max)

{

max=count;

index=i;

}

}

}

}

8〉字符串转换为int-----------已知int为正

 

#include <stdio.h>

 

int main()

{

char a[]="1234"

int i,sum=0;

 

for(i=0;str[i]!=0;i++)

{

sum = sum*10+str[i]-'0';

}

printf("%s",sum);

}

9int(有正有负)转换为char

 

#include <stdio.h>

 

int main()

{

int i=0,num;

int flag=0;

char a[20]={'\0'};

printf("input a int num:");

scanf("%d",&num);

 

if(0 == num)

{

a[i++]='0';

}

 

if(0>num)

{

num=-num;

flag=1;

}

while(num>0)

{

a[i++] = num%10+'0';

num /= 10;

}

if(flag)

{

a[i++] = '-';

}

int len=strlen(a);

 

for(i=0;i<len/2;i++)

{

int temp = a[i];

a[i] = a[len-1-i];

a[len-1-i] = temp;

}

printf("%s",a);

return 0;

 

 

}

10〉查找特定字符

 

七:C基础(6

一〉一维数组:

定义  数据类型  数组名[数组长度]

int arr[5];//定义了一个长度为5int 数组   sizeof(arr)=int [5]=20

二〉二维数组

定义  数据类型  数组名[数组长度]

//定义一个长度为3的数组,数组里面每个元素又是一个长度为4Int数组

int brr[3][4]; ------>sizeof(brr)=int [3][4]

brr[0] ~ brr[2];------>sizeof(brr[0])=int [4]

brr[0][0] ~ brr[2][3];----->sizeof(brr[0][0])=int

brr == &brr[0]

brr[0] == &brr[0][0]

 

三〉一维字符数组:

//定义一个长度为20char数组

char str[20];

char str[20]={'a','b','c'};   sizeof(str)=20       strlen(str)=3

char str1[]={'a','b','c'};    sizeof(str1)=3       strlen(str1)=?

char str2[]="abc";            sizeof(str2)=4       strlen(str2)=3

输入输出:%s

printf("%s",字符串的首地址);    printf("%s",str);

%s在输出的时候会自动去寻找\0,遇到\0就打印结束

scanf("%s",字符串的首地址);     scanf("%s",str);

%s在输入的时候遇到空格、回车、TAB键就认为输入结束

 

四〉二维字符数组:

 

//定义一个长度为5的数组,数组里面每个元素又是一个长度为20char数组

char str[5][20];

char str[5][20]={{"apple"},{"banana"},{"orange"}{"pineapple"}{"watermelon"}};

输入输出:%s

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

{

Scanf(“%s”,str[i]);

Printf(“%s”,str[i]);

}

//按照字符串的大小将其从小到大排序

//按照字符串的长度将其从小到大排序

 

int main()

{

char a[5][20]={"apple","banana","orange","pineapple","watermelon"};

int i,j;

char s[20]={‘\n’};

//通过比较大小排序

for(i=0;i<4;i++)

{

for(j=0;j<4-1;j++)

{

if(strcmp(a[j],a[j+1])>0)

strcpy(s,a[j]);

strcpy(a[j],a[j+1]);

strcpy(a[j+1],s);

}

}

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

{

printf("%s  ",a[i]);

}

printf("\n");

//通过比较长度排序

for(i=0;i<4;i++)

{

for(j=0;j<4-1;j++)

{

if(strlen(a[j]>strlen[j+1]))

strcpy(s,a[j]);

strcpy(a[j],a[j+1]);

strcpy(a[j+1],s);

}

}

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

{

printf("%s  ",a[i]);

}

printf("\n");

return 0;

 

 

五〉什么是指针

1.指针的定义

 

指针是一种数据类型,用来保存地址的数据类型

地址:计算机内存单元的编号

2、什么是指针变量

用来保存地址的变量,指针变量的值就是地址

 

数据类型 * 指针变量名

*”:代表我们定义了一个指针

数据类型:该指针变量所指向的变量的数据类型

int * p;//p是一个指针变量,p指向了一个Int变量,p的值是一个int变量的地址

char *s;   ----->s的数据类型:char *

32位操作系统下,所有的数据类型的指针都占4个字节(sizeof(int))

3、指针的初始化

int i = 5;

int * p;

p = &i;   //p指向i

 

int i =5;

int *p = &i;

 

int i=5,*p=&i;

!!!在使用指针之前,必须进行初始化

4、指针的访问

通过取值运算符*

前提:int i=5,*p=&i;    *p实质上就是i这片内存空间,就是i的一个别名,操作*p就是在操作i

 

int *a;

*a = 52; //这里的指针变量a是一个野指针

int *p = NULL; //p是一个空指针

!!!操作空指针和野指针都是不合法的

5*C语言中的三种用法

1)乘法

2)定义指针变量     int *p;

3)取值运算符           *p;

如果*号前面有数据类型,是在定义指针变量;如果没有,就是在取值

 

6、指针的运算

指针的运算实质上是地址的运算

1算术运算

p+n/p-n:p向地址增大(减小)的方向移动n个数据

具体移动的字节跟指针指向的数据类型有关   sizeof(数据类型)*n

p++:p向地址增大的方向移动1个数据

 

 

int i = 5, j =10;

int *p = &i;

int *q = &j;

p-q:两个指针之间相隔元素的个数(pq必须是同类型的指针)

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

int *p = arr;

int *q = &arr[4];

printf("%d",q-p);  4   

注意:

同类型的指针不可以进行相加、相乘、相除

2关系运算

>  <  >=  <= == !=

两个指针必须是同类型的,而且必须指向同一数据区域才可以进行关系运算

指针s q指向同一数据区域

 

 

指针可以和0进行比较,判断指针是否为空

 

7.指针与一维数组

 

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

int *p = arr;//指针变量P指向了数组的首元素

p = &arr[0] =arr

p+1 = &arr[1] =arr+1

p+2 = &arr[2] = arr+2 ....

!!!*p = *&arr[0] = arr[0] = *arr =p[0]

*(p+1)= *&arr[1] = arr[1] =*(arr+1) =p[1]

*(p+2)= *&arr[2] = arr[2] =*(arr+2) =p[2]

*(p+3)= *&arr[3] = arr[3] =*(arr+3) =p[3]

*(p+4)= *&arr[4] = arr[4] =*(arr+4) =p[4]

注意:arr++ ----->error

      arr是个地址常量,p是个变量,所以数组名在运算中可以作为指针参与运算,但不可以被赋值

*s+1!!!!!!!!!!!违法操作

*s++----------*(s++)---先将s++表达式的值得出再取值

 

六〉作业

 

D

 

 

 

 

A-----常量区不能被修改

 

D-----------p(一个未知地址)的值传给了s,但后来字符数组的首地址又给了s,所以最后没有对p所指向的地址操作,FUN函数没有返回值,子函数执行完就被销毁,因此为P所指向的地址空间随机

八:C基础(七)

一〉计算机内存分布:

 

二〉二级指针

 

int i = 5;

int *p = &i;  //p的数据类型:(int *)    *p的数据类型:int

int **pI = &p;   //pi的数据类型:(int **)   *pi的数据类型:(int *)   **pi的数据类型:int

 

*p = i = 5;

*pi = p = &i;  //*pi就是p的一个别名,操作*pi就是在操作p

**pi = *p = i = 5;  //**pii的别名,操作**pi就是在操作i

 

1.指针与二维数组

 

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

//定义一个指针指向数组中的第一个int元素

int *p = &arr[0][0] = arr[0];

p = &arr[0][0] = arr[0]

p+1 = &arr[0][1]

p+2 = &arr[0][2]

p+3 = &arr[1][0]

p+4 = &arr[1][1]

p+5 = &arr[1][2]

 

*p = *&arr[0][0] = arr[0][0] = *arr[0]

*(p+1) = *&arr[0][1] = arr[0][1] = *(arr[0]+1)

*(p+2) = *&arr[0][2] = arr[0][2] = *(arr[0]+2)

*(p+3) = *&arr[1][0] = arr[1][0] = *(arr[0]+3)

*(p+4) = *&arr[1][1] = arr[1][1] = *(arr[0]+4)

*(p+5) = *&arr[1][2] = arr[1][2] = *(arr[0]+5)

 

for(i=0;i<6;i++)

{

printf("%d",*(p+i));

}

 

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

//定义一个指针指向二维数组的首元素此时首元素名称:a[0]---a[2]数据类型:int  [3]

数据类型 * 变量名

数组指针--(指向二维数组其数据类型为int [3])int (*p)[3];  //[]的优先级比*高,所以*p必须要括起来

sizeof(p) = 4

p = &arr[0] = arr;

p+1 = &arr[1] = arr+1

*p = *&arr[0] = arr[0] = &arr[0][0] = *arr   //*p是一个地址

*(p+1) = *&arr[1] = arr[1] = &arr[1][0] = *(arr+1)

**p = *(&arr[0][0]) = arr[0][0] = **arr = p[0][0]

**(p+1) = *&arr[1][0] = arr[1][0] = **(arr+1) =p[1][0]

arr[0][1] = *&arr[0][1] = *(&arr[0][0]+1) = *(*p+1)

arr[0][2] = *&arr[0][2] = *(&arr[0][0]+2) = *(*p+2)

arr[1][1] = *&arr[1][1] = *(&arr[1][0]+1) = *(*(p+1)+1)

arr[1][2] = *&arr[1][2] = *(&arr[1][0]+2) = *(*(p+1)+2)

arr可以看成是一个二级指针

 

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

int * p = &arr[0] = arr;  //定义一个指针指向数组中的首元素

int (*p1)[5] = &arr; //定义一个指针指向整个数组

 

2.指针数组:

 

int *p[2]; //定义了一个长度为2的数组,数组的元素都是一个指向int的指针

sizeof(p) = 8

int m = 5;

int n = 10;

p[0] = &m;

p[1] = &n;

p = &p[0]

*p = *&p[0] = p[0] = &m

**p = *p[0] = *&m = 5

*(p+1) = p[1] = &n

**(p+1) = *p[1] = *&n = 10

 

 

3.字符指针

 

char str[20] = "helloworld";

char *pc = str;

 

char *pc1 = "helloworld";  //字符串常量本身就是字符串的首地址

 

(1)scanf("%s",str); ok

   scanf("%s",pc1); error  不可以对常量区的内容进行修改

(2)printf("%s",str); ok

   printf("%s",pc1); ok

(3)str[1] = *(pc+1)

*(pc+1) = 's';  ok

*(pc1+1) ='s';   error   不可以对常量区的内容进行修改

(4)char *pc1 = "helloworld";    ok

char str[20];

str = "helloworld";      error      str是一个地址常量

注:常量只可被读,不能修改

三〉函数

 

1)函数的作用:使我们的程序变得更加模块化,同时可复用性更强

2)函数的分类

库函数:

1)先引入头文件

2)调用函数

如果函数有返回值,变量 = 函数名(实际参数1,实际参数2...

#include <stdio.h>

printf("字符串",实际参数2,实际参数3...)

自定义函数:

1)函数声明   //告诉计算机有这个函数

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

//形式参数必须要写数据类型,变量名可省略,句末一定要有分号,返回值如果没有写void

2)函数定义

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

{

函数体;

return 变量名; //如果没有返回值,该句话可省略

}

//函数定义的时候形式参数的变量名一定不能省

3)函数调用

 

变量 = 函数名(实际参数1,实际参数2...

调用子函数结束,给子函数分配的这片空间就被销毁

 

在调用子函数之前,如果该子函数已经定义,那么可以不写函数声明

如果该子函数的定义在调用子函数之后,那么必须写函数声明

 

全局变量:定义在函数体外部的变量  作用域:自定义开始到文件结束

局部变量:定义在函数体内部的变量  作用域:自定义开始到最近的}结束

 

 

四〉gdb调试工具

1)编译的时候添加参数 -g

gcc -g cal.c -o cal

2)进入gdb

gdb cal

3)设置断点

b main   //main函数处设置断点

b 30     //在第30行处设置断点

4r(run) 运行

5n(next)  ---->不进入子函数

6s(step)  ---->进入子函数

7q(quit)  ----->退出

8)回车代表执行上一个命令

 

 

五〉static

修饰局部变量:如果该变量没有被初始化,那么就被初始化0;如果已经被初始化,那么就只能被初始化一次

修饰全局变量该变量只能在本.c文件使用

修饰函数该函数只能在本.c文件使用

static修饰全局变量

static修饰函数

隐藏,只允许在本文件中调用,不允许在其他文件文件中调用

static修饰局部变量(增长变量的生命周期);

首先static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0

 

 

六〉作业:

用子函数实现两个数的交换

void change(int *a,int *b)

{

        *a ^= *b;

        *b ^= *a;

        *a ^= *b;

}

 

int main()

{

        int m,n;

        m=1;

        n=2;

        printf("m=%d n=%d\n",m,n);

 

        change(&m,&n);

        printf("m=%d n=%d\n",m,n);

 

        return 0;

}

 

九:C基础(8

一〉结构体

1. 定义:

构造一个新的数据类型

 

struct person{

char name[20];

int height;

};

该数据类型叫 struct person

typedef struct person per;

 

typedef struct person{

char name[20];  //成员变量之间要用分号隔开,成员变量的数据类型可以相同也可以不同

int height;

}per;

 

初始化:per p1={"lijianfei",175};

访问结构体成员变量:结构体变量名.成员变量名

输出:printf("%s %d\n",p1.name,p1.height);

输入:scanf("%s%d",p1.name,&p1.height);

 

//定义一个指针指向p1

per * pper;

pper = &p1;

*pper <====> p1

(*pper).name   (*pper).height

//通过结构体指针访问成员变量

指针变量名->成员变量名

pper->name

pper->height

 

//定义一个结构体变量p2

per p2;

p2 = p1; //p1的值赋值给p2

p2.name    p2.height

 

2、字节对齐32OS    gcc编译器)

系统一次性分配的字节数是成员变量里面最大的字节对齐数

 

3、共同体

union union{

char ch;

int i;

};

注意:共同体所占内存空间取决于成员变量中最大的内存空间  sizeof(union un) = 4

  共同体中所有成员变量的首地址都是一致的,所以在某一时刻只能取一个成员变量使用

//定义一个共同体变量

union un u1;

 

4、大小端

大端序:低字节存高地址处,高字节存低地址处

小端序:低字节存低地址处,高字节存高地址处

 

判断计算机是大端序还是小端序:(通过共同体)

u1.i = 0x12345678;

if(u1.ch == 0x78)

printf("小端序\n");

else

printf("大端序\n");

 

5、Const

 

const 数据类型  变量名;  //该变量只读

const int a = 10;

a = 20;  //error    a只读

 

const char *p = "helloworld";

char str[20] = "helloworld";

const char *p = str;   //<====>char const *p = str;

*p = 'e';  --->error  str这片空间只读

 

char * const p = "hello";

p就只能指向“hello”这个字符串,不能再指向其他字符串

const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的安全性和可靠性。另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助。另外CONST在其他编程语言中也有出现,如C++PHP5C#.netHC08C

 

3、指针函数:返回值是指针的函数就是指针函数

LINUX  C

 

一:SHELL基础3

一〉嵌入式系统3

二〉Linux软件管理机制3

1. dpkg-----3

2.apt_get-3

3.apt-cache-3

三〉APT软件包管理器3

四〉LINUX系统结构4

五〉SHELL命令5

六〉通配符6

七〉输入输出重定向6

八〉命令置换7

九〉进程管理7

十〉linux文件系统8

1.文件系统类型8

2.SCSI(机械硬盘)与IDE8

3.根目录文件9

4.文件类型10

5.创建链接文件:10

6.文件压缩与解压10

二:shell脚本编程基础11

一〉编写流程11

二〉:变量11

1.自定义变量11

2.位置参数与预定义变量11

3.环境变量12

三〉shell程序和语句12

1.语句12

1〉说明性语句13

2〉功能性语句13

3〉结构性语句15

四〉shell函数21

1.定义21

2.传参:21

三:c高级23

一〉引入23

二〉数组24

1:一维数组24

2:二维数组--按行存放24

三〉指针24

1:值访问25

2:运算25

3:一维数组与指针25

4.指针与二维数组26

5.指针数组27

6字符指针数组27

7:多级指针28

8:const/void指针28

四〉函数29

1.函数定义:29

2.函数声明:29

3.函数传参30

1〉复制传参30

2〉地址传递30

3〉全局变量31

4.指针函数31

5.函数指针32

六〉递归函数34

七〉GCC编译器35

1.编译运行步骤35

2.GNU工具35

3.定义-交叉平台编译器35

4.主要组件35

八〉GDB(用途小36

九〉结构体**36

1.结构体数组37

1〉定义struct stu a[3];37

2〉初始化38

3〉提取元素38

2.结构体指针38

3.结构体指针数组38

十>内存分配***39

1.存储模型39

1>变量39

2.动态分配39

十一〉makefile基本结构39

1. 工作原理40

2.基本格式40

 

 

 

 

 

一:SHELL基础

一〉嵌入式系统

X86 arm---体系架构

MIT---麻省理工

Ubuntu----”人道待人”理念

艾伦.图灵---计算机之父

Richard staliman-----自由软件之父(GNU运动(软件开源,免费)----gcc.gdb.gedit---->GNU/Linux(GNU运动下开发的LINUX系统)

嵌入式应用:无人驾驶----利用声呐不断测试与障碍物的距离来控制车速

二〉Linux软件管理机制

三个配置文件:

软件源配置文件(软件仓库):/etc/apt/sources.list

本地软件包索引文件(可下载的目录):/var/lib/apt/lists

本地文件下载缓存目录:/var/cache/apt/archives

  1. dpkg------

完成本地软件包安装管理(依赖关系明确)

注:在/var/cache/apt/archives(本地缓存目录---安装包存放的地方)下输入命令

命令:sudo dpkg -i <package(完整的安装包文件名--就在上面的那个目录下可以查看)>:安装软件

Sudo dpkg -P <package>:移除已经安装的软件包及配置文件

2.apt_get---管理下载文件

步骤:1:查找软件最新版本 2:配置文件依赖关系  3:下载  4:安装

Sudo apt-get install (-d) packg------下载并安装(不安装)

Sudo apt-get remove/clean/update/upgread/check(卸载/删除已下载的包文件/下载更新软件包信息列表(包括更新软件源里的软件信息)/升级到最新版本/查看系统中依赖关系的完整性)  [-d/--purge/--reinstall/-v/-f] (仅下载不安装/remove连用完全卸载(包括软件包与文件)/重新安装/获取版本号/修复依赖关系)packg

3.apt-cache---查询软件相关信息

Apt-cache  show/search/policy/depend(获取二进制软件包的详细信息/检索软件包/获取安装状态/获取依赖关系)

三〉APT软件包管理器

---1:检查修复软件包依赖关系 2:利用网络主动获取软件包

deb软件包(ubuntu系统):二进制软件包(deb--可直接安装   源码包(deb-src--需解压再安装

rehat系统:rpm软件包

四〉LINUX系统结构

  1. Shell是一个命令编译器,将用户命令编译成二进制程序,交给操作系统执行。【 F】??
  2. 在默认情况下,所定义的Shell变量的作用域是局部有效。【 F】
  3. 使用DHCP服务配置动态IP的过程,就犹如一个租借过程。【T 】

 

 

 

linux内核含有硬件驱动控制硬件,硬件做出相应的反应来控制shell,shell再将信息反馈给用户

 

SHELL---命令行解释器(更快更直接)

当前使用版本--bash(bourn again shell)<------sh(bourn shell)的增强版

五〉SHELL命令

Sudo shoutdown -h n/now--关机

Ctrl+c---取消关机

Sudo shoutdown -r n/now---重启==reboot(直接执行boot-loder(系统引导程序))

命令---指令  选项   参数

Ls -l DS/----显示DS目录下的内容

多命令在一行同时执行-----命令1;命令2..ls;pwd

一个命令在多行------命令.........

\命令.....

Tab---命令补齐

(两次tab----显示当前目录下具有相同前缀的名称

Less/more -----分页显示

查询历史命令:history n(默认500)

设置历史命令容纳量:HISTSIZE =m

Echo $HISTSIZE----查看

基本系统维护命令

Passwd---修改密码(root 可修改其他用户的(su))

Cd /home/----用户主目录

Export----查看环境变量----可以修改其中的环境变量(su -m

Echo----显示指令(当有多个空格时只打印一个(认为其为一个指令))  

Echo “ ”---显示字符串

Echo $PATH--查看当前编译路径

???Mips--:交叉编译

Date--查看当前时间

While(1)

{

System(“date”);

Sleep(1);

}//每秒打印一次时间

??????Date -s “%y-%m-%d”

**********df--查看磁盘空间使用率(tmpfs--虚拟内存空间:1G的虚拟内存可虚拟出4G的内存空间)

Df -a-----显示所有的文件系统使用情况(包括proc,sysfs虚拟内存)

Df -ah--M为单位显示

Du----显示每个文件/目录所占磁盘块数(每个磁盘占512个字节)

/etc/passwd 文件----用户清单(p86

/etc/group 文件-----组与成员列表(p89)

 

Adduser <用户名>----创建用户

************/etc/skel目录----/etc/sbin/adduser使用,将新用户想要的配置文件拷贝到/etc/skel

Usermod---修改用户属性(推出登陆root用户)

sudo usermod  -l  newname oldname(修改用户名)   

sudo usermod -d /home/user1(全新目录) -m(将家目录搬到新目录下,与-d一起使用) -l newname  oldname  --------------------(修改用户名并修改家/主目录)

Sudo deluser name----仅仅删除用户名,相关文件还存在

Sudo  deluser  --remove-home user1-----删除用户并删除用户目录

/etc/adduser.conf---- 用户配置文件

Sudo delgroup groupname---删除组

Exit----退出用户

*********************************

 

 

 

 

 

六〉通配符

1〉‘*---匹配任意长度的字符串(file_*.txt

’?’----匹配一个长度的字符

[]---匹配其中指定的一个字符(file_[ot].txt==file_o.txt,file_t.txt

‘[ - ]’-------指定的一个字符范围([a-z]

‘[^ ]’-----除了其指定的字符

管道:|-----第一个命令的输出作为第二个命令的输入

Eg:ls /usr/bin | wc -w-----统计指定目录下的文件数目

七〉输入输出重定向

1〉‘〉file---覆盖输入重定向

2〉‘〉〉file----追加输入重定向

3〉‘〈file---覆盖输出重定向

4〉‘<<file---追加输出重定向

’2>file’-----错误覆盖输出重定向

2>>file----错误追加重定向

Eg:ls 2.c 2> e.c

Char * fgets(char *s,int size,FILE *stream);

Fgets(str,10,stdin)----从缓冲区获取指定长度的字符(stdin(标准输入)  stdout(标准输出)

流;标准输入流-------》文件描述符    0

标准输出流                     1

标准错误流                     2

八〉命令置换

命令1  `命令2`------将命令2esc键下的但引号)的结果作为命令1 的参数

Eg:ls `pwd`

九〉进程管理

程序==数据结构+算法    静态

进程:程序的一次执行

 

命令:

Ps -au  ---〉仅显示当前用户的进程详细信息

%cpu---cpu占用率   %MEM---内存占用率  VSZ--虚拟文件使用字节数 RSS---占用磁盘字节数   TTY---正在使用的配置文件  STAT--状态 START---运行时间

Ps  -aux ---->显示所有用户进程信息

Top ----实时监控进程: NI----进程优先级    PR---进程控制块     

???????Nice -----调整进程优先级

KILL   PID-----终止进程==ctrl+c(向内核发送KILL9)(强制终止进程)

进程状态

 

Z---将死态(没运行,但占一部分空间) L不重要

+----进程挂起

十〉linux文件系统

1.文件系统类型

df查看磁盘空间

磁盘文件系统:

网络文件系统:NFS(文件系统)---系统移植应用

专有/虚拟文件系统

2.SCSI(机械硬盘)与IDE

固态读写快,作为系统盘15秒开机了解一下。240g再储存点常用软件和网游绰绰有余了。

机械读写慢,但可以作为储存文档,电影等数据之类的硬盘,相对于固态也更安全,更稳定。如果固态的容量不够可以考虑再加一个机械。如果240g就够用的话也没必要再加机械。

内存----内存条(执行程序时的变量等)--断电重启后数据不在

外存----a.out存在磁盘空间---断电重启后数据还在

IDE--固定硬盘

Sata---机械硬盘

交换分区----交换分区(了解)(将内存内容写到磁盘,或从内存读出)

 

 

3.根目录文件

/(linux文件系统根目录)          /bin(存放系统中最常用的可执行文件(二进制文件))   

/boot(存放Linux内核和系统启动文件)          /dev(设备文件)

  /etc(配置文件,用户信息文件等)              /home(用户主目录)   

/lib(存放共享的库文件)     /mnt(存放被挂载文件的挂载点----可用于文件共享)        

/proc(存放所有标志为文件的进程)    /root(超级用户主目录)  /var(存放长度可变的文件)

 

Linuxwindows区别

EXT4---LINNX现在最新文件格式   FAT64--windows常用文件格式

最大区别:(换行符区别)LINUX---\n windows---\r\-n

4.文件类型

 

命令:

File  <name>---查看文件类型

Cp  目标  被复制  -r  ----------------复制目录

Mv day2/ ~ ---移动到家目录

Mkdir -p mm/kk/ll

LINUX不会显示二进制内容   cat a.out---结果是乱码

Head -n name  tail -n name-----显示头尾指定行数

 

5.创建链接文件:

硬链接:利用linux分配的物理编号--inode建立链接-----不能跨越文件系统---不可恢复

软链接:利用文件的路径名建立链接(相对路径)--可恢复(重新创建一个同名的link-name链接又会重新启动)

ln [-s(软链接)] target link-name(改变target的内容Link-name的内容会相应的改变)

6.文件压缩与解压

归档文件(.tar):将一组文件或目录保存在一个文件中---使占用磁盘空间增大

压缩文件(.gz):将一组文件或目录保存在一个文件中,并以某种存储格式存储在磁盘空间上,内存总和比所有文件之和小

1Gzip工具:有链接文件不能被压缩打包(windows无链接文件)

Gzip -d/-l/-num(1-9)(解压/查看压缩文件内的信息/指定压缩比率(默认6),数字越大压缩力度越大)  name

Gunzip  [-f] (提示已经有的同名文件)name-----解压

2Tar命令(归档文件)[-c]  tarname  filename

 

Tar -cf 123.tar 1.c 2.c 3.c ---->tar -xvf 123.tar  创建一个新的归档文件

Tar -xfv  123.tar  -----解压并显示指定归档文件

Gzip  -d  123.tar --->解压==gunzip

二:shell脚本编程基础

运维师与外挂

shell区分大小写

一〉编写流程#!/bin/bash(当前使用的脚本类型,执行该文件的程序)--开头一行(!虽然注释掉了但系统可以阅读)-----------〉编写程序并保存退出----〉给文件设置执行权限(chmod  权限  文件名)-----./x.sh(运行程序)

 

二〉:变量

1.自定义变量(默认为全局变量)

变量名=

取用变量值:$变量名6g

Num=20

Unset num

2.位置参数与预定义变量

c语言中:int main(int argc ,char *argv[])命令行参数

 

$?-返回调用函数的返回值

3.环境变量

 

 

$HOME--引用

PATH(默认路径,执行shell脚本时可以快速找到):---shell可执行的路径(x.sh放在其路径下,不用指定其路径(x.sh直接运行))

执行程序必须知道其存放路径:./x.sh

/bin-----存放基本的指令(二进制可执行程序)

DATE=`date`----命令置换   LIST=`list`

Unset---取消环境变量,在命令行输入:unset z

Set---设置环境变量

三〉shell程序和语句

1.语句

 

比较---条件测试语句

1〉说明性语句

 

2〉功能性语句

 

Read----阻塞功能,被read赋值的变量不允许再次被赋值,read 可被回车终止

 

Read var1 var2 var3  

              

注:运算符左右两侧必须加空格

 

*----通配符,利用‘\’去除二义性

$num=9---$命令行提示符

I++------->$i=`expr $i + 1`(x)   对:i=`expr $i + 1`

test==[ x ]

$?(上一条命令的结果)------0为真,非0为假

 

Z--zero  n--no

 

eq==ne==not eq  gt==big than  ge==big eq lt==last than le==last eq

text测试时“=”两边必须有空格

-d(目录文件) -f(普通文件)重要

整数测试时-ge表达式, 前后都是需要数字类型的变量或者常量, 一般都是${xxx} 不用加双引号  

3〉结构性语句

分支语句

 

 

注:条件(test) ’[]‘里面最左边与最右边必须有空格

-a(逻辑与) -o(逻辑或)  !(逻辑非)

 

If  [ 条件 ]

Then

 Elif [ 条件 ]

Then

 Else

 fi

 

 

Let 指令--取十位      ‘|’将多个项合并

 

循环语句

 

 

 

实现1-100的和 将当前目录下的所有文件拷贝到上一级目录

        

                    

*可打印出当前路径下的所有文件名     

仅仅打印当前路径

 

 

 

创建文件 $1$i--文件名,从键盘输入file 3

 

 

删除文件:命令行输入file 1 3

if [ $# -eq 3 ]

then

count=$3

else

echo input error

exit

fi

 

i=$2//1

while [ $i -le $count ]

do

rm $1$i # file1 file2 file3

let i++

done

 

 

循环控制语句

第一次$output为空

作业:用shell打印9*9乘法表

Echo (默认换行) 参数选项: -n 输出文字不换行
       -e 将转义符跟后边的特殊字符解释成特殊意义
       -E  不解释转义字符 

1〉#!/bin/bash

For i in {1..9}

Do

Foe j in {1..9}//error----{1..$i}

Do

If [ $j -le $i ]

Then

Let sum=$i*$j

Echo -ne “$j*$i=$sum\t”//\t----水平制表符

Fi

Done

Echo

Done

2〉

for ((i=1;i<=9;i++))

        {   

                for ((j=1;j<=$i;j++))

                        {   

                                let sum=$i*$j

                                echo -ne "$j*$i=$sum\t"

        }   

                echo " "

 

}

 

 

 

3

 

 

\t----水平制表符

四〉shell函数

1.定义

 

2.传参:

 

 

..传给$1  -aux传给$2

 

实现两个数相加($?获取上一程序的状态)

 

abc为全局变量123  456

 

设置局部变量:local 变量名

 

打印出123 123

 

三:c高级

一个寄存器只有十多个字节。定义寄存器变量时,也存放在栈区

一〉引入

判断寄存器存储变量与AUTO变量执行速度

Time(&sttar)---以秒统计时间

 

For(;j<=N;j++);

Time(&stop);

Printf(“%d\n”,stop-start);

 

Time_t t;time(&t);//将从1970.1.1到当前时间的秒数赋给变量t

printf(“today’s time and date is %s”,ctime(&t));------打印出当前日期与时间(ctime(&t)将秒数转换为日期与时间)

二〉数组

1:一维数组

Int n=10;int arr[n];()

Int n=10;int arr[n]={1,2,3,4};()---n为可变值

初始化时,才被分配空间

gcc编译不能查看数组越界

 

str后面存放str1打印结果---hellohaa

2:二维数组--按行存放

 

 

Arr=&arr[0]

Arr[0]=&arr[0][0]

因为arr[0]arr[0][0]的地址重合因此打印出的地址相同,但是*arr=&arr[0][0]为一个地址,*&arr[0][0]=arr[0][0]--为一个值

三〉指针

地址--内存单元的编号

此时野指针并没有被使用因此不会报错

空指针 ---物理--0地址

       ---逻辑-不会指向任何地方(与野指针相对)

Int *p=NULL<==>int *p=0;(0NULL的编号)vi /user/lib/gcc/.....(宏定义地址)

1:值访问

Int n=20;int  *p=&n;

Int *p = (int *)100;(强制转换)对---

1〉直接访问:n=20                  2>间接访问:*p=20-----寄存器只能间接访问

‘*’-----解引用符

2:运算----实质是地址的偏移

1>两个指针之间不能进行‘+           2〉倒叙字符串

              

3数据类型不匹配,无法获取想要的数据,将返回0

 

3:一维数组与指针

 

a为地址常量,只读,a++

1〉求最小值

 

4.指针与二维数组

二维数组元素名,为行地址

数组指针--〉行指针只能指向二维数组---int (*p)[3]=a//[二维数组的每个元素里有多少个数据]

 

 

p[i] <-->*(p+i)-----*/ []:降维作用

P[i][j]----1:p[i]看作一个整体将其解引用得(*p+i)[j]-----[j]先解引用*(p[i]+j)-----将两个都解引用*(*p+i+j)

 

5.指针数组

Int *a3[2]-----[二维数组元素个数]

 

 

a2,a4所存内容一样,为同一片内存空间,只是行列数划分不同,但对其操作不会越界

A2[2][3]; 1 2 3/4 5 6/

A4[3][2]:1 2/3 4/5 6/

6字符指针数组---存放的为字符指针常量的首地址,不能被修改

 

Char *str[5]:指针访问常量区,字符串  常量   char str1[]:字符串变量

printf(%c,**y);---h  y++--->段错误

7:多级指针

二级指针--指针的地址

&char *

 

打印出world                                      打印出e

 P+1------地址偏移4个字节,因为其中存的字符串地址占四个字节

二级指针与二维Int数组                               

 

Int **p=b----p指向a[0]

*p+1---第一行再移一个

8const/void指针

1Const---修饰一个变量为只读

Egstrcat(char *dest,const char *src)

Strcat(dest,”http”);

修饰指针:

1

Int  const *p=&n;//*p不能修改

指针数据类型与所指对象的数据类型要相同

2void 指针

Void *p=&a;

引用:*int *p

---可指向任意数据类型--但因无确定的数据类型,无法知道取多少空间里的数据,因此需要强制转换

 

四〉函数

1.函数定义:完成某些特定功能的代码模块。形参名不可省

 

2.函数声明:若函数定义写在main函数之后,就必须写.   形参名可省

Eg:int add(int ,int ); int add(int a,int b);

 

注:个代码程序,有且仅有一个main函数

3.函数传参

1〉复制传参

实参并没发生交换

2〉地址传递

Swap&x,&y

仅仅将p q里面的内容传给了子函数,而p q地址不变----------相当于复制传递

 

实现了两个实参值的交换

传递函数:一维整型数组,字符数组传参,二维数组

地址传参:int (*a)[3]    int a[][3]--复制传参       但两者都是地址

  

3〉全局变量---定义在所有函数之外

Int flag;

Func(flag)

static变量与全局变量不做初始化,初始化默认为0----放在静态变量数据区

Eg:

N--二维数组行    m----二维数组列

 

4.指针函数----返回值为地址

Eg:

 

p--变量的值,str3----地址

函数可以返回一个值:p可以返回,并由p存储的地址里面的内容依然存在,而str3能返回,但其内容已经被销毁,因此不能返回一个局部变量的地址

static修饰时,可以返回str里面的内容

Static:(变量存放在静态存储区)

一:修饰局部变量----增长了变量的生命周期

二:修饰函数:限制函数的作用域,只能在当前文件中被调用

三:修饰全局变量:限制变量作用域,只能在本文件中使用

static可由程序员手动放入堆区,没有运行的代码放入代码段中

5.函数指针==函数名

定义:存放函数地址的指针

 

 

函数返回值类型  *指针名)(函数参数类型)

指针指向函数:函数名就为函数的起始地址

 

q==add-->add[10,20]==q[20][20];

 

Char * *p(char *,char*)

小应用:float decall(float (*fp)(int),int n)//float (*fp)()函数指针

{

        float s;

        s=(*fp)(n);//调用函数指针

        return s;

}

 

 

五〉函数指针数组

 

 

调用:

六〉递归函数(做题)

1〉自己调用自己 2〉寻找递归终止条件

先递推再回归

 

例子:5

 

 

 

七〉GCC编译器GNU CC

1.编译运行步骤

 

1: .c ----->.i    2: .i--.s  3: .s-->.o

.so/----动态库  ./a静态库  ----------cd /lib

2.GNU工具

3.定义-交叉平台编译器

4.主要组件

分析器:将源语言程序代码转换为汇编语言

汇编器:将汇编语言代码转换为CPU可执行字节代码(二进制文件)

链接器:将汇编器生成的单独目标文件组合成可执行的应用程序

标准C库:标准的C函数都由C库提供

生成汇编文件----〉检查语法错误

 

 

八〉GDB(用途小---数组越界

----printf()代替,查看错误 printf行缓存函数---当输出内容占满一行才输出,因此需利用\n来结束一行的缓存

 

九〉结构体***

---数据结构的链表使用

 

 

结构体对齐标准:最长字节对齐方式(编译器不同对齐不同),GCC4字节对齐方式

 

 

1.结构体数组

1〉定义struct stu a[3];     

 

2〉初始化

 

3〉提取元素

 

4:结构体调用结构体

-----调用

2.结构体指针

1:定义                             2:调用

                  

3.结构体指针数组

 

十>内存分配***

1.存储模型

1>变量

 

全局变量与局部变量---若两个变量名相同,在局部就对局部变量进行操作

 

具有外部链接的静态   :外部链接,所有函数之外

具有内部链接的静态 :内部链接(static,所有函数之外

空链接的静态  :局部变量+static

2.动态分配-----heap(堆区)

 

----应为malloc返回为void *因此需强制转换为与p的数据类型相同的空间

Free()---仅仅需要释放空间的首地址

十一〉makefile基本结构

----------工程管理器

1.工作原理

make工程管理器根据( 文件时间戳 )来自动发现更新过的文件从而减少编译的工作量。

2.基本格式

 

避免头文件重复定义

sunq为可执行程序

 

 

$@  $^:所有的依赖文件

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

C基础

一:linux基础 3

1Linux常用命令 4

2Vim编辑器 6

二:C基础 6

1、计算机的组成 6

2、计算机的数据表示 8

3C补习内容 8

4LinuxC的开发流程 8

5、程序的入口:main()函数 9

6、变量 9

7、基本数据类型(32位操作系统) 9

三:C基础(2 12

1. 常数如何描述 12

1〉作业:计算一个整数的二进制中1的个数(整数可为正为负) 14

4. 内存值如何查看 16

1〉作业:编写一个猜数字的软件 16

5.控制语句 17

1if要点 17

2〉作业:判断一年是否为闰年? 17

3switch语句 18

四:C基础(3 19

一〉技术点: 19

1. 溢出越界 19

2. ++ii++ 19

3. atoi() 20

4.十进制转十六进制: 20

二〉C语句 20

1.分支语句 20

1gotolongjmp 20

2switch语句 21

3Scanf-------从键盘获取数据 21

2.数据类型: 22

1enum----枚举 22

2void 22

351c------sbit 22

4char: 22

5〉字符串常量 22

3.内存: 23

1〉常量 23

2〉变量 23

3Static 23

4Const 23

六:C基础(5 23

1、二维数组 23

2、 字符数组 25

3、跟字符串相关的函数 26

1strlen 26

2strcpy 26

3strcat 26

4strcmp 26

1strcpy()-- 27

2> strcat()--- 27

3strlen()- 28

3> Strcmp 29

4Int型数组中的次大值 29

5〉打印ab对称图形 30

6〉二维字符数组排序 31

7〉寻找字符串中出现次数最多的字符 32

8〉字符串转换为int-----------已知int为正 33

9int(有正有负)转换为char 34

10〉查找特定字符 35

七:C基础(6 35

一〉一维数组: 35

二〉二维数组 36

三〉一维字符数组: 36

四〉二维字符数组: 36

五〉什么是指针 38

1.指针的定义 38

2、什么是指针变量 38

3、指针的初始化 39

4、指针的访问 39

5*C语言中的三种用法 40

6、指针的运算 40

1算术运算 40

2关系运算 40

7.指针与一维数组 41

六〉作业 42

八:C基础(七) 44

一〉计算机内存分布: 44

二〉二级指针 44

1.指针与二维数组 45

2.指针数组: 46

3.字符指针 47

三〉函数 48

四〉gdb调试工具 49

五〉static 50

六〉作业: 50

九:C基础(8 51

一〉结构体 51

1. 定义: 51

2、字节对齐 52

3、共同体 52

4、大小端 53

5Const 53

4、指针函数: 54

 

一:linux基础

 

什么是嵌入式:软件控制的硬件

嵌入式---一个定制的计算机

   所以:硬件和软件需要根据设备要实现的功能专门去设计

   也就是说嵌入式系统所需要的操作系统是可以被修改的

   linux系统是一个开源软件--可以免费得到源代码并且可以自由修改

 

学习软件:

1VNC   (同屏) server   viewr

2、飞秋

3VM(虚拟机)   虚拟的一台电脑,可以在这台虚拟的电脑上运行linux操作系统           

4ubuntu

 

  LinuxOS                       windows

  ubuntu                           windowxp

  redhat                             window7

  红旗                                 window10

 

 ubuntu每半年更新一次    04   10

 每两年更新一个长期版本(稳定)LST   

 

 Linux是一个开源的、多用户的、多任务的操作系统,要求必须以用户和密码去登录

 

shell:命令行解释器     用户和内核进行沟通的桥梁

   shell其实就是程序,程序提供给我们一个界面(终端),这个界面可以让我们输入命令 (shell命令)

    

 

1Linux常用命令

ctrl+alt+t:打开一个终端

命令行提示符-------》   用户名@计算机名:当前路径$

$:代表当前登录的用户是一个普通用户

#:超级用户,root用户,权限最高

su - 用户名:切换到该用户

ctrl+d:从超级用户切换回普通用户

pwd:查看当前路径

sudo:增加权限

绝对路径:从根目录开始的路径

相对路径:具体看参照物

windows的文件系统犹如一片森林,各自独立

Linux的文件系统犹如一颗倒置的树,所有的目录都在跟目录之下

ls:查看当前目录下的内容

ls 目录路径:查看该目录下的内容

ls -a:查看当前路径下的所有内容(包括隐藏文件   以.开头的文件叫隐藏文件)

ls -l :以长格的形式显示当前目录下内容的详细信息

 

drwxrwxrwx  6 linux linux    4096 Jun  9 20:14 A9Server

d:文件类型

linux下文件分为7种:

-     --------->普通文件

d   ---------->文件夹

p   ----------->管道文件

l    ----------->链接文件

b  ------------>块设备文件

c   ------------>字符设备文件

s   ------------->套接字文件

 

cd:切换目录路径

cd .. :退回上一级目录

cd ../..:退回上一级目录的上一级目录

cd -:返回上一次的目录路径

cd .:返回当前目录

cd ~(cd):快速返回家目录

 

ctrl+shift+'+':放大字体

ctrl + '-':缩小字体

安装中文:ibus-setup

ctrl+空格:语言切换

clear(ctrl+l):清屏

touch 文件名:创建一个文件(文件名可以多跟)

rm 文件名:删除一个文件

mkdir 文件夹名:创建一个文件夹

mkdir -p :连续创建多级目录

rmdir 文件夹名:删除一个文件夹(只能删除空文件夹)

rm -rf 文件夹名:删除一个文件夹

 

cp 被复制的文件名 目标路径:

cp -r 被复制的文件夹名  目标路径

cp -i  被复制的文件名 目标路径:提示是否被覆盖

 

mv 被移动的文件  目标路径:

mv 1.c 2.c   ------>2.c不存在则把1.c改名为2.c   存在则先改名然后覆盖

mv day1 day2 ----->day2不存在改名,存在移动

 

cat 文件名:查看该文件的内容(一般适用于比较短的

more 文件名:查看该文件的内容(一般适用于比较长的

按回车:一行一行的向下查看

q退出

 

sudo reboot:重启

sudo shutdown -h now:立即关机

sudo shutdown -h 20:20分钟后关机

chmod 777 文件名:把该文件的权限全都打开

Tab:自动补全

向上的箭头:上一次的命令

ctrl+c:结束当前进程

 

2Vim编辑器

vim 文件名:如果文件时存在的就直接打开,如果不存在新建该文件再打开

vim的三种模式:命令行模式、插入模式、底行模式

刚打开一个文件是命令行模式,命令行模式---》插入模式(按i)  插入模式---》命令行模式(esc) 命令行模式---》底行模式(shift+:

命令行模式:

i:从光标所在地方的前面开始插入

I:从光标所在的行首开始插入

a:从光标的下一个字符的前面开始插入

A:从光标所在行的行末开始插入

o:从光标所在的下一行(新建的行)开始插入

O:从光标所在的上一行(新建的行)开始插入

插入模式:在插入模式下才可以编辑文本

底行模式:(以:开始)

w    保存

q     退出

wq    保存并退出    :x      ZZ(命令行模式下)

wq!    强制保存退出

wq  文件名  以新名字保存的备份文件

set nu   设置行号

set nonu  取消行号

set hlsearch   设置高亮

range %s/str1/str2/g   range范围内所有的str1都替换成str2

/str  (命令行模式)    查找str

nyy:n代表行数(命令行模式下进行复制粘贴)

p:粘贴

ndd:剪切

u:撤销

=gg  (命令行模式下)自动调整格式

 

gcc编译器,gcc 2.c会默认生成可执行文件a.out,执行 :./a.out

gcc 2.c -o 2将可执行文件a.out改名为2,执行:./2

 

3.6 文本内容的删除操作;

x 一个字符;
#x 删除几个字符,#表示数字,比如3x;
dw 删除一个单词;
#dw 删除几个单词,#用数字表示,比如3dw表示删除三个单词;
dd 删除一行;
#dd 删除多个行,#代表数字,比如3dd 表示删除光标行及光标的下两行;
d$ 删除光标到行尾的内容;

J 清除光标所处的行与上一行之间的空格,把光标行和上一行接在一起;

 

二:C基础

1、计算机的组成

硬件

CPU:运算器、控制器控制从内存获取数据,与内存交换数据很快、寄存器

存储器:

内部:ROM(只读存储器) RAM(随机存储器,断电后数据易丢失)

外部:硬盘、U

输入设备:键盘、鼠标、麦克风

输出设备:显示器、音响、打印机

软件

系统软件:windows  linux   UNIX

应用软件: wps  qq

 

一台没有任何软件的计算机称为“裸机”。

 

储存1T是指硬盘的总容量为1TB太字节Terabyte),计算机存储容量单位,也常用TB来表示。1TB=1024GB==2^40字节

 

2、计算机的数据表示

数值数据    非数值数据

数值数据:二进制   十进制   八进制(0作为前缀,0~7)    十六进制(以0x作为前缀,0~f(F)

 

十进制转其他进制:除2/8/16倒取余

非数值数据:a'\n' '5'

 

3C补习内容

1)数据类型

基本数据类型:int   float   char

复合数据类型:数组、指针、函数、结构体

2)运算符

3)结构性语句

顺序语句

选择语句

循环语句

4)算法

求最大值    冒泡排序

4LinuxC的开发流程

输入一个数,求这个数是奇数还是偶数

1)分析建模

num

num%2==0---->偶数

num%2==1---->奇数

2)画流程图

a.输入一个数num

b.如果num%2==0,输出该数是偶数

c.如果num%2==1,输出该数是奇数

3)翻译成C代码

4)编译

5)运行

 

5、程序的入口:main()函数

int main()

{

return 0;

}

 

6、变量

在程序运行过程中其值可以改变的量

 

7、基本数据类型(32位操作系统)

int 4个字节)  [signed]int-2^31 ~ 2^31-1   unsigned int:0 ~ 2^32-1

short  2个字节)[signed]short:-2^15 ~ 2^15-1   unsigned short:0 ~ 2^16-1

long    4个字节)

long long   8个字节)

 

float:4个字节

double8个字节

 

char:1个字节  [signed]char:-128~127   unsigned char :0~255

看成是一个字节的int

列子:int a=’\101’;//0101;//0x41;//65

Float 1.4;//1.4=14*10-1

(浮点数存储:左边为符号   中间整数存储   右边指数存储)

指数存储占低8位,符号位占高八位

8、标识符的定义(变量名、数组名、函数名)

a.由数字、字母、下划线组成

b.首字母不能是数字

c.不能与关键字重名

d.尽量见名知意

 

9、关键字

关键字:32个   由系统定义的   全都是小写

      数据类型(用于定义变量或类型):char double float  int long  short struct union void enum(枚举型) longlong   signed  unsigned

      控制语句:break case continue default do  else for  goto if switch while  return

     存储类型:auto register  extern static  const

  其他类型:         

      sizeof:求所占内存大小(单位是字节)

      typedef:给已有类型取别名

      volatile:防止编译器优化的

关于volatile的意义,根据标准C的定义、volatile的目的是,避免进行默认的优化处理.比如说对于编译器优化的功能,如果从编译器看来,有些多余的代码的话,编译器就会启动优化程序,并删除一些代码,但是这在嵌入式系统中很有可能是关键性的处理,必须不能保证被编译器删掉,所以提供了Volitile来声明,告诉编译器无论如何都不要删掉我。

Extern volatile int event_flag;

这样声明event_flag全局变量的话,就不用担心event_flag 被优化掉,程序将按照设计来运行。

 

  

10、赋值运算符(从右到左运算)

=  =右边的值赋给=左边

num=8;   8赋值给num

 

11、标准输出函数printf()

(1)引入头文件   #include <stdio.h>

(2)调用函数

参数1:字符串

printf("helloworld");//把字符串里面的内容原样显示在输出屏幕上

printf("字符串+格式化符",多个和格式化符一样多的参数)

int num = 8;

printf("num = %d",num);

 

12、存储方式

正数:以补码形式存储

正数的原码、补码、反码都一样

char ch =127; 0111 1111

负数:以补码形式存储,最高位是符号位,正数是0,负数是1,剩下的都是数据位

char ch = 129;

1000 0001  (补码)

1000 0000

1111 1111   -127

补码转为原码:

a.先减1,再取反(数据位)

b.先取反,再加1

 

char ch = 128;---->%d  -128

1000 0000 (补码)

1111 1111

1000 0000 -128的原码)

 

13、算术运算符

注:用移位运算符代替算术运算符,效率最高

A=b%m-----a=b&(m-1)  a=b*2^n-----a=b<<n    a=b/2^n------a=b>>n

a=b/8*8+b%4 -> a=((b>>3)<<3)+(b&3)
 a=b*15 -> a=(b<<4)-b

+  -  *  /  %

%----》两边的表达式只能是int 或者 char

5/2=2   int/int=int   5.0/2 = 2.500000  float/int = float--->float/float=float

 

隐式转换:范围小----》范围大

int  +   float = float

int  +  short  = int

unsigned + signed = unsigned

float + double = double

 

unsigned a = 2;signed b = -5;

printf("%d",a+b);------>-3

0000 .... 0010 a的原码)

1000....  0101  (b的补码)

1111....  1011 (b的原码)  signed  ----> unsigned

1111....  1101 (a+b)     unsigned---->signed

1000....  0011

 

强制转换:(数据类型)变量名   (数据类型)(表达式)

float f =12.5;

(int)f;  %d--->12

f; %f--->12.5   在强制转换过程中,变量本身并没有发生改变

 

 

++:如果放在变量名前,先自加后使用;放在变量名后,先使用后自加

++如果单独成句,没有区别

注:不要在同一行使用多个++’‘--

三:C基础(2

1. 常数如何描述

#define X 65

65

0x41

0101

'\101'   ('\0' == 0)

 

2. 变量空间如何申请

(数据类型关键字: 1.要多大; 2. 如何使用此空间)

char

short

int

long

float

double

3. 如何表达运算

数学运算符(加减乘除)

+

-

*

/

==

%

 

示例: a的十位数(a/10%10

 

位运算符(比特位操作)

~

<<

>>

逻辑右移---unsigned

算数右移---[signed] xx

左移---有符号和无符号一样

 

 

----这个算数右移才对

&      (清楚某个bit位,保留必要字段) 掩码~(子网掩码)

清除掉abit na = a & ~(1<<n);

提取abit n: (a & (1<<n))>>n;

|       置位某个bit

abit n变成1a = a | (1<<n)

abit n开始的三个bit设置成任意值x0-7): a = a&~(7<<n) | (x<<n);-----当所要设置的三位数原来为111时,无论你想要设置为什么值‘|’后还为111,因此应先将这三位清0,再”|”,(想要修改连续2位时---3<<n0,以此类推)

 

1〉作业:计算一个整数的二进制中1的个数(整数可为正为负)

int main()

{

        int n=12;

        int count=0,i=0;

 

        while(i<=sizeof(int)*8)//int就是一个坑,不同系统字节不同

        {

                if(n&(1<<i))

                        count++;

                i++;

        }

        printf("%d\n",count);

        return 0;

}

//2

int main()

{

        int num=12,i=0,j;

 

        while(num)

        {

                num = num&(num-1);

                i++;

        }

 

        printf("%d\n",i);

        j=count_bits(num);

 

        printf("%d\n",j);

        return 0;

//3

include <stdio.h>

 

int main()

{

int a = 0xffffffff;

int bitn = 0,n=0;

//提取bit

While(n<=sizeof(int)*8)//不同操作系统数据类型所占空间不同!!!!!!!!!!!!!!!!!!

{

If(a&(1<<n))

{

n++;

Bitn++;

 

}}

 

printf("bits: %d\n", bitn);

 

}

 

 

^(扫雷应用)

a = a^b;

b = a^b;

a = a^b;

 

逻辑运算符(真与假)

&&:int i=0,j=0;

If(i++ && j++);   ---->i==1,j==0(逻辑判断第一个表达式逻辑为假,运行即中断)

||

?:

 

 

第二个#define定义的常量可读性更强

 

4. 内存值如何查看

 

Printf(“%d%d%d%d\n”,i++,++i,i++,i++);

1>逗号运算从右到左运算

2>i++先将i暂存在寄存器中然后自加,++i直接取加1后的值给i

1〉作业:编写一个猜数字的软件

        int x = rand()%100;//随机获取100以内的数

        int num;

 

        printf("input a number:");

        while(1)

        {   

          getchar();    

          scanf("%d",&num);

    

          if(num == x)

          {   

                printf("right\n");

                break;

          }   

          else if(num > x)

          {   

                printf("too big:");

          }   

          else

                  printf("too small:");

 

        }

}

 

5.控制语句

1if要点

A:注意区分ifa=1)与ifa==1

B:if语句中else总是与紧挨着的那个if配对,与书写格式的缩进无关,若要实行强制的配对,可用以下语句

If()

{if() 语句块1}

Else 语句块2

2〉作业:判断一年是否为闰年?

1:能被4整除但又不能被100整除

2:能被100整除又能被400整除

             int main()

{

        int year;

        printf("please input a year number:");

        while(1)

        {   

                scanf("%d",&year);

                if((year%4==0 && year%100!=0) || (year%100==0 && year%400==0))        

                {

                        printf("%d is a full year!\n",year);

                        break;

                }           

                else

                        printf("%d is not a full year!please input a another year:",year);    

                printf("\n");

        }

 

 

        return 0;

3switch语句

A:其表达式可以是整型 字符型 枚举型

Bdefault后的break可省略

4for语句

三个表达式都可以省略,但“;”不能省:注意省略的条件,当语句2省略时,如果循环中无goto,break,return则陷入死循环  

5break只能用在循环语句和switch语句中

注:如何使用break跳出多层循环-------使用flag(看门狗设置0/1,再通过判断真假来跳出循环)

6*求素数的三种方法
一:for(i=2;i<=(n-1);i++)
ifn%i==0i2n-1之间任取一个数,如果n能被整除则不是素数,否则就是素数
二:for(i=2;i<n/2;i++)
if(n%i==0) /*i2n/2之间任取一个数,如果n能被整除则不是素数,否则就是素数

三:for(i=2;i<(n=sqrt(n+i));i++)
if(n%i==0) /*i2sqrt(n)之间任取一个数,如果n能被整除则不是素数,否则就是素数,在下省了下面的输出步骤*/

/*在本程序中使用第三种方法来求解*/
#include <stdio.h>
#include <math.h>
int main(void)
{
int i; /*外循环*/
int j; /*内循环*/
int flag; /*素数标志,flag1则此数为素数*/
flag = 0;
//int n;
i = 2;
while( i <= 100)
{
j = 2;
flag = 1; /*假设此数为素数*/
while(j <= (int) sqrt(float(i)))
{
if(0 == (i %j))
flag = 0; /*根据第三种算法可知次数不为素数*/
j ++;
}
if(flag)
printf("%d\t",i);
i++;
}
printf("\n");
return 0;
}                            

四:C基础(3

一〉技术点:

1. 溢出越界

1〉、溢出:小容器装大东西 

  数据类型超过了计算机字长的界限而出现的数据溢出;

2〉、溢出可能原因:

   当应用程序读取用户数据,复制到应用程序开辟的内存缓冲区中,却无法保证缓冲区的空间足够时 (假设定义数组int array[10], 而在调用时使用array[11] 或存放的数据超过int类型容量等),  内存缓冲区就可能会溢出.

越界:使用的东西超过了本身的范围

比如你定义的A[3][3],这是二维数组,意为三行三列,其中第一行的元素有A[0][0]A[0][1]A[0][2](第二三行依次类推)在后面你调用这个数组中的元素时,如果你调用A[0][3],这样就应该算越界了,也就是超过定义数组的范围了,因为这个数组第一行最多到A[0][2]

 

2. ++ii++

Printf(“%d%d%d”,i,i++,++i);-----------(2,1,2)----i++当作i先放着,把表达式计算完后再将值赋给i

函数:先将表达式的值计算好了再传给参给函数

3. atoi()

函数原型:int  atoi(const  char*  nptr);

 

函数的用法:参数nptr字符串(且为数字字符串),如果第一个非空格字符存在,是数字或者正负号则开始做类型转换,之后检测到非数字(包括结束符 \0) 字符时停

 

止转换,返回整型数。否则,返回零。

4.十进制转十六进制:

1:先取低四位-------a&oxf   2:右移四位-----a>>4

 

二〉C语句

1.分支语句

1gotolongjmp

Goto-----短跳转语句(作用域限定---只在一个{}以内有作用)---在硬件驱动时应用

Longjmp----c长跳转语句

2switch语句

-------case后的表达式为整型或字符型,,必须有default(可不用放在最后,但最好放在最后)

输入输出语句:

3Scanf-------从键盘获取数据

\n’敏感应与getchar()配对使用

*---抑制符(scanf(“%*d%c”,&s,&a)-----第一个数据接收        scanf("%*d%d%*d",&a,&a,&a);

        printf("%d\n",a);

4Gets()-------在如数组这样有界的数据操作时容易发生越界!!!!!!!!!!!!!

5Sscanf()-------可从字符串中获取想要的字符

Eg char arr[]={N: 100}

Int x=0;

Sscanf(arr,”%*s%d”,&x);----arr中提取100

Sscanf()atoi()的联系

6例子:猜数字游戏------rand()获取随机数,但一般比较大,根据需要利用%/来获取数据

7Printf()-------必须加‘\n’,打印首先输出在缓冲区中,有‘\n’时数据直接刷出缓冲区并打印到显示器上

\t----制表符(打印时以最优格式输出)

Eg:printf(“xxxxx\t1234\n”);

Printf(“xxxx\t123\n”);

8Puts()------专用打字符串,自带‘\n

Eg:while(1){

Sleep(1);

Printf(“ .......\n”);//putchar(r);fflush(stdout);(刷出缓冲区)

}

Printf(“\rh\re\rl\rl\n”)------’\n’---回到行首

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

Printf(“/r%d”,i);

Fflush(stdout);

Sleep(1);

}------------数据每隔一秒显示在行首

注:printf()---------------------打印前/背景颜色----应用:将调试信息分级别(红--error--waring--right

9Sizeof()--------运算符(求空间容量,编译器统计在编译阶段就获得)

10Strlen()--------一种算法(以0结束统计并结束)

Char a=”hello”;

Sizeof(a);-------6

Strlen(a);--------5;

Eg:void func(int arr[100])

{

Printf(“%d\n”,sizeof(arr));--------------4(int arr[100]--------地址(指针))

}

2.数据类型:

1enum----枚举(快速宏定义)-----依次为所列元素自动定为01.。。。

2void --------*:空指针

      ---------无:代表万能

351c------sbit(bit----资源有限)

----支持访问bit型,但无此数据类型,也无bool型,但有逻辑真假表示

4char:有符号字节变量

动作:越界------int  a[4]={0,0,1,2,3};-------有危险

:溢出-------char c=128;(数据越界)----有误差

Char c=500;char a=500;------------编译时:就将一个常量500放在了不可改变的内存中

运行时:将500的备份分赋给c,a;

5〉字符串常量-------不能被修改也不能被优化

3.内存:

 

1〉常量--------放在只读区(本身就存在不可修改,可在a.out文件中修改你想要改变的输出内容),编译时已经存在

2〉变量-------运行时才出现,常量备份给他,临时存在,可改

3Static--------放在data区,若在全局变量前加此关键字,则该变量只能被本文件使用

-----------------1〉作用域限定(全局变量或函数内)2〉申请data静态数据存储区

4Const-----(符号常量,常变量)------伪存储类型关键字

Egconst float g=9.8-------类似于将变量放在常量区

*((float*&g))= 10.1-----通过地址改值

Extern -----定义的变量可被其他文件使用

六:C基础(5

 

1、二维数组

//定义一个长度为4的数组,数组里面的每个元素又是一个长度为3int数组

int brr[4][3]; ----->数据类型:int [4][3]

brr[0] ~ brr[3] ----->数据类型:int [3]

brr[0][0] ~ brr[0][2] ----->数据类型:int

 

初始化:

int brr[4][3]={ {123}

{456}

{789}

{101112}}

int brr[][3]={1,2,3,4,5,6,7,8,9,10,11,12};

int brr[4][3]={{1},{2}};    brr[0][0] = 1    brr[1][0]=2

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

 

输入输出:

int brr[][3]={1,2,3,4,5,6,7,8,9,10,11,12};

brr[0][0] -----%d  printf("%d",brr[0][0]);

brr[0]:

for(j=0;j<3;j++)

{

printf("%d",brr[0][j]);

}

brr[1]:

for(j=0;j<3;j++)

{

printf("%d",brr[1][j]);

}

...

brr:

for(i=0;i<4;i++)

{

for(j=0;j<3;j++)

{

printf("%d",brr[i][j]);

}

}

 

2、字符数组

 

//定义一个长度为20的字符数组

char str[20];

 

char str[]={'h','e'};

char btr[20];

char str[20]={'h','e','l','l','o'};

char str[20]={"hello"};

char str[20]="hello";    sizeof(str)=20    strlen(str)=5;

字符串的特点:以'\0'作为结束标志

char str[]="hello";      sizeof(str)=6    strlen(str)=5

字符串的输入输出:

 

printf("%s",字符串的首地址) %s在输出的时候自动去寻找\0,遇到\0就输出结束

puts(字符串的首地址)//自动将\0转换成\n

gets(字符串的首地址)//遇到\n认为输入结束-------------容易发生越界,造成栈爆炸

scanf("%s",字符串的首地址)//遇到\n、空格、TAB键认为输入结束

Eg:char str[]=ab\n\012\\\””;

Printf(“%d”,strlen(str));-------------输出6

 

转义字符:

 

 

3、跟字符串相关的函数

1strlen   计算字符串的长度

int len = strlen(字符串的首地址)----\0作为结束标志

2strcpy    复制-------以字符串2\0作为结束标志

EGchar str[]={‘h’,’e’};btr[20];----即当字符数组全部初始化且不含’\0’时,strlen结果不一定正确

Strcopy(btr,str);--------------结果可能有误(strlen\0作为复制的结束标志而str中无’\0’)

strcpy(字符串1的首地址,字符串2的首地址)//将字符串2复制到字符串1里面去

//字符串1的空间必须足够大,返回值是字符串1的首地址

连缀调用:

strcpy(ctr,strcpy(btr,str));//str复制给btr,又将btr复制给ctr

3strcat   链接

strcat(字符串1的首地址,字符串2的首地址)//将字符串2链接到字符串1后面去

//字符串1的空间必须足够大,返回值是字符串1的首地址

连缀调用

strcat(ctr,strcat(btr,str)); //str链接到btr后面去,又将btr链接到ctr后面去

4strcmp    比较(ASCII码值)

"helloworld"   "hellokitty"

strcmp(字符串1的首地址,字符串2的首地址)

int n = strcmp(str1,str2);

if(n>0)printf("str1>str2");

else if(n<0)printf("str1<str2");

else printf("str1=str2");

自己实现以上函数:

5.重点练习

 

1strcpy()-------注意,当完成元素复制后,在目标串的最后,人为加上\0

 

 

 

2>strcat()--------------------最后手动加上\0

 

3strlen()----------\0结束

 

 

3>Strcmp

 

4Int型数组中的次大值

 

 

 

 

Strlen()------\0结束

Strlen(str1)不一定为5strlen(str2)也不一定为5(\0)

Sizeof(str1)=sizeof(str2)=5  strlen(str3)=strlen(str4)=6

部分初始化输入字符--strlen()结果正确

全部初始化输入字符---strlen 结果不一定正确

 

5〉打印ab对称图形

 

int main()

{

        int i,j,k,m,c;

 

        char ch='A';

        printf("input your lines:");

        scanf("%d",&m);

    

        for(i=0;i<m;i++)

        {   

                for(k=1;k<m-i;k++)

                {   

                        printf(" ");

                }   

                for(c=i;c>=0;c--)

                {   

                        printf("%c",ch+c);

                }   

                for(j=1;j<=i;j++)

                {   

                        printf("%c",ch+j);

                }   

                printf("\n");

        }   

}

6〉二维字符数组排序

#include <stdio.h>

#include <string.h>

 

int main()

{

char a[5][20]={"apple","banana","orange","pineapple","watermelon"};

int i,j;

char s[20]={‘\n’};

//通过比较大小排序

for(i=0;i<4;i++)

{

for(j=0;j<4-1-i;j++)

{

if(strcmp(a[j],a[j+1])>0)

strcpy(s,a[j]);

strcpy(a[j],a[j+1]);

strcpy(a[j+1],s);

}

}

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

{

printf("%s  ",a[i]);

}

printf("\n");

//通过比较长度排序

for(i=0;i<4;i++)

{

for(j=0;j<4-1-i;j++)

{

if(strlen(a[j]>strlen[j+1]))

strcpy(s,a[j]);

strcpy(a[j],a[j+1]);

strcpy(a[j+1],s);

}

}

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

{

printf("%s  ",a[i]);

}

printf("\n");

return 0;

}

7〉寻找字符串中出现次数最多的字符

 

#include <stdio.h>

 

int main()

{

int count=0,max=0,index=-1;//count 记录每个字符出现的次数,max出现次数最多的字符次数,index次数最多字符的下标

char a[]="helloworld";

int i=0,j=0;

 

for(i=0;a[i]!='\0';i++)

{

for(j=0;a[j]!='\0';j++)//查找每个字符出现的次数

{

count=0;

if(a[i]==a[j])

count++;

if(count > max)

{

max=count;

index=i;

}

}

}

}

8〉字符串转换为int-----------已知int为正

 

#include <stdio.h>

 

int main()

{

char a[]="1234"

int i,sum=0;

 

for(i=0;str[i]!=0;i++)

{

sum = sum*10+str[i]-'0';

}

printf("%s",sum);

}

9int(有正有负)转换为char

 

#include <stdio.h>

 

int main()

{

int i=0,num;

int flag=0;

char a[20]={'\0'};

printf("input a int num:");

scanf("%d",&num);

 

if(0 == num)

{

a[i++]='0';

}

 

if(0>num)

{

num=-num;

flag=1;

}

while(num>0)

{

a[i++] = num%10+'0';

num /= 10;

}

if(flag)

{

a[i++] = '-';

}

int len=strlen(a);

 

for(i=0;i<len/2;i++)

{

int temp = a[i];

a[i] = a[len-1-i];

a[len-1-i] = temp;

}

printf("%s",a);

return 0;

 

 

}

10〉查找特定字符

 

七:C基础(6

一〉一维数组:

定义  数据类型  数组名[数组长度]

int arr[5];//定义了一个长度为5int 数组   sizeof(arr)=int [5]=20

二〉二维数组

定义  数据类型  数组名[数组长度]

//定义一个长度为3的数组,数组里面每个元素又是一个长度为4Int数组

int brr[3][4]; ------>sizeof(brr)=int [3][4]

brr[0] ~ brr[2];------>sizeof(brr[0])=int [4]

brr[0][0] ~ brr[2][3];----->sizeof(brr[0][0])=int

brr == &brr[0]

brr[0] == &brr[0][0]

 

三〉一维字符数组:

//定义一个长度为20char数组

char str[20];

char str[20]={'a','b','c'};   sizeof(str)=20       strlen(str)=3

char str1[]={'a','b','c'};    sizeof(str1)=3       strlen(str1)=?

char str2[]="abc";            sizeof(str2)=4       strlen(str2)=3

输入输出:%s

printf("%s",字符串的首地址);    printf("%s",str);

%s在输出的时候会自动去寻找\0,遇到\0就打印结束

scanf("%s",字符串的首地址);     scanf("%s",str);

%s在输入的时候遇到空格、回车、TAB键就认为输入结束

 

四〉二维字符数组:

 

//定义一个长度为5的数组,数组里面每个元素又是一个长度为20char数组

char str[5][20];

char str[5][20]={{"apple"},{"banana"},{"orange"}{"pineapple"}{"watermelon"}};

输入输出:%s

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

{

Scanf(“%s”,str[i]);

Printf(“%s”,str[i]);

}

//按照字符串的大小将其从小到大排序

//按照字符串的长度将其从小到大排序

 

int main()

{

char a[5][20]={"apple","banana","orange","pineapple","watermelon"};

int i,j;

char s[20]={‘\n’};

//通过比较大小排序

for(i=0;i<4;i++)

{

for(j=0;j<4-1;j++)

{

if(strcmp(a[j],a[j+1])>0)

strcpy(s,a[j]);

strcpy(a[j],a[j+1]);

strcpy(a[j+1],s);

}

}

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

{

printf("%s  ",a[i]);

}

printf("\n");

//通过比较长度排序

for(i=0;i<4;i++)

{

for(j=0;j<4-1;j++)

{

if(strlen(a[j]>strlen[j+1]))

strcpy(s,a[j]);

strcpy(a[j],a[j+1]);

strcpy(a[j+1],s);

}

}

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

{

printf("%s  ",a[i]);

}

printf("\n");

return 0;

 

 

五〉什么是指针

1.指针的定义

 

指针是一种数据类型,用来保存地址的数据类型

地址:计算机内存单元的编号

2、什么是指针变量

用来保存地址的变量,指针变量的值就是地址

 

数据类型 * 指针变量名

*”:代表我们定义了一个指针

数据类型:该指针变量所指向的变量的数据类型

int * p;//p是一个指针变量,p指向了一个Int变量,p的值是一个int变量的地址

char *s;   ----->s的数据类型:char *

32位操作系统下,所有的数据类型的指针都占4个字节(sizeof(int))

3、指针的初始化

int i = 5;

int * p;

p = &i;   //p指向i

 

int i =5;

int *p = &i;

 

int i=5,*p=&i;

!!!在使用指针之前,必须进行初始化

4、指针的访问

通过取值运算符*

前提:int i=5,*p=&i;    *p实质上就是i这片内存空间,就是i的一个别名,操作*p就是在操作i

 

int *a;

*a = 52; //这里的指针变量a是一个野指针

int *p = NULL; //p是一个空指针

!!!操作空指针和野指针都是不合法的

5*C语言中的三种用法

1)乘法

2)定义指针变量     int *p;

3)取值运算符           *p;

如果*号前面有数据类型,是在定义指针变量;如果没有,就是在取值

 

6、指针的运算

指针的运算实质上是地址的运算

1算术运算

p+n/p-n:p向地址增大(减小)的方向移动n个数据

具体移动的字节跟指针指向的数据类型有关   sizeof(数据类型)*n

p++:p向地址增大的方向移动1个数据

 

 

int i = 5, j =10;

int *p = &i;

int *q = &j;

p-q:两个指针之间相隔元素的个数(pq必须是同类型的指针)

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

int *p = arr;

int *q = &arr[4];

printf("%d",q-p);  4   

注意:

同类型的指针不可以进行相加、相乘、相除

2关系运算

>  <  >=  <= == !=

两个指针必须是同类型的,而且必须指向同一数据区域才可以进行关系运算

指针s q指向同一数据区域

 

 

指针可以和0进行比较,判断指针是否为空

 

7.指针与一维数组

 

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

int *p = arr;//指针变量P指向了数组的首元素

p = &arr[0] =arr

p+1 = &arr[1] =arr+1

p+2 = &arr[2] = arr+2 ....

!!!*p = *&arr[0] = arr[0] = *arr =p[0]

*(p+1)= *&arr[1] = arr[1] =*(arr+1) =p[1]

*(p+2)= *&arr[2] = arr[2] =*(arr+2) =p[2]

*(p+3)= *&arr[3] = arr[3] =*(arr+3) =p[3]

*(p+4)= *&arr[4] = arr[4] =*(arr+4) =p[4]

注意:arr++ ----->error

      arr是个地址常量,p是个变量,所以数组名在运算中可以作为指针参与运算,但不可以被赋值

*s+1!!!!!!!!!!!违法操作

*s++----------*(s++)---先将s++表达式的值得出再取值

 

六〉作业

 

D

 

 

 

 

A-----常量区不能被修改

 

D-----------p(一个未知地址)的值传给了s,但后来字符数组的首地址又给了s,所以最后没有对p所指向的地址操作,FUN函数没有返回值,子函数执行完就被销毁,因此为P所指向的地址空间随机

八:C基础(七)

一〉计算机内存分布:

 

二〉二级指针

 

int i = 5;

int *p = &i;  //p的数据类型:(int *)    *p的数据类型:int

int **pI = &p;   //pi的数据类型:(int **)   *pi的数据类型:(int *)   **pi的数据类型:int

 

*p = i = 5;

*pi = p = &i;  //*pi就是p的一个别名,操作*pi就是在操作p

**pi = *p = i = 5;  //**pii的别名,操作**pi就是在操作i

 

1.指针与二维数组

 

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

//定义一个指针指向数组中的第一个int元素

int *p = &arr[0][0] = arr[0];

p = &arr[0][0] = arr[0]

p+1 = &arr[0][1]

p+2 = &arr[0][2]

p+3 = &arr[1][0]

p+4 = &arr[1][1]

p+5 = &arr[1][2]

 

*p = *&arr[0][0] = arr[0][0] = *arr[0]

*(p+1) = *&arr[0][1] = arr[0][1] = *(arr[0]+1)

*(p+2) = *&arr[0][2] = arr[0][2] = *(arr[0]+2)

*(p+3) = *&arr[1][0] = arr[1][0] = *(arr[0]+3)

*(p+4) = *&arr[1][1] = arr[1][1] = *(arr[0]+4)

*(p+5) = *&arr[1][2] = arr[1][2] = *(arr[0]+5)

 

for(i=0;i<6;i++)

{

printf("%d",*(p+i));

}

 

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

//定义一个指针指向二维数组的首元素此时首元素名称:a[0]---a[2]数据类型:int  [3]

数据类型 * 变量名

数组指针--(指向二维数组其数据类型为int [3])int (*p)[3];  //[]的优先级比*高,所以*p必须要括起来

sizeof(p) = 4

p = &arr[0] = arr;

p+1 = &arr[1] = arr+1

*p = *&arr[0] = arr[0] = &arr[0][0] = *arr   //*p是一个地址

*(p+1) = *&arr[1] = arr[1] = &arr[1][0] = *(arr+1)

**p = *(&arr[0][0]) = arr[0][0] = **arr = p[0][0]

**(p+1) = *&arr[1][0] = arr[1][0] = **(arr+1) =p[1][0]

arr[0][1] = *&arr[0][1] = *(&arr[0][0]+1) = *(*p+1)

arr[0][2] = *&arr[0][2] = *(&arr[0][0]+2) = *(*p+2)

arr[1][1] = *&arr[1][1] = *(&arr[1][0]+1) = *(*(p+1)+1)

arr[1][2] = *&arr[1][2] = *(&arr[1][0]+2) = *(*(p+1)+2)

arr可以看成是一个二级指针

 

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

int * p = &arr[0] = arr;  //定义一个指针指向数组中的首元素

int (*p1)[5] = &arr; //定义一个指针指向整个数组

 

2.指针数组:

 

int *p[2]; //定义了一个长度为2的数组,数组的元素都是一个指向int的指针

sizeof(p) = 8

int m = 5;

int n = 10;

p[0] = &m;

p[1] = &n;

p = &p[0]

*p = *&p[0] = p[0] = &m

**p = *p[0] = *&m = 5

*(p+1) = p[1] = &n

**(p+1) = *p[1] = *&n = 10

 

 

3.字符指针

 

char str[20] = "helloworld";

char *pc = str;

 

char *pc1 = "helloworld";  //字符串常量本身就是字符串的首地址

 

(1)scanf("%s",str); ok

   scanf("%s",pc1); error  不可以对常量区的内容进行修改

(2)printf("%s",str); ok

   printf("%s",pc1); ok

(3)str[1] = *(pc+1)

*(pc+1) = 's';  ok

*(pc1+1) ='s';   error   不可以对常量区的内容进行修改

(4)char *pc1 = "helloworld";    ok

char str[20];

str = "helloworld";      error      str是一个地址常量

注:常量只可被读,不能修改

三〉函数

 

1)函数的作用:使我们的程序变得更加模块化,同时可复用性更强

2)函数的分类

库函数:

1)先引入头文件

2)调用函数

如果函数有返回值,变量 = 函数名(实际参数1,实际参数2...

#include <stdio.h>

printf("字符串",实际参数2,实际参数3...)

自定义函数:

1)函数声明   //告诉计算机有这个函数

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

//形式参数必须要写数据类型,变量名可省略,句末一定要有分号,返回值如果没有写void

2)函数定义

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

{

函数体;

return 变量名; //如果没有返回值,该句话可省略

}

//函数定义的时候形式参数的变量名一定不能省

3)函数调用

 

变量 = 函数名(实际参数1,实际参数2...

调用子函数结束,给子函数分配的这片空间就被销毁

 

在调用子函数之前,如果该子函数已经定义,那么可以不写函数声明

如果该子函数的定义在调用子函数之后,那么必须写函数声明

 

全局变量:定义在函数体外部的变量  作用域:自定义开始到文件结束

局部变量:定义在函数体内部的变量  作用域:自定义开始到最近的}结束

 

 

四〉gdb调试工具

1)编译的时候添加参数 -g

gcc -g cal.c -o cal

2)进入gdb

gdb cal

3)设置断点

b main   //main函数处设置断点

b 30     //在第30行处设置断点

4r(run) 运行

5n(next)  ---->不进入子函数

6s(step)  ---->进入子函数

7q(quit)  ----->退出

8)回车代表执行上一个命令

 

 

五〉static

修饰局部变量:如果该变量没有被初始化,那么就被初始化0;如果已经被初始化,那么就只能被初始化一次

修饰全局变量该变量只能在本.c文件使用

修饰函数该函数只能在本.c文件使用

static修饰全局变量

static修饰函数

隐藏,只允许在本文件中调用,不允许在其他文件文件中调用

static修饰局部变量(增长变量的生命周期);

首先static的最主要功能是隐藏,其次因为static变量存放在静态存储区,所以它具备持久性和默认值0

 

 

六〉作业:

用子函数实现两个数的交换

void change(int *a,int *b)

{

        *a ^= *b;

        *b ^= *a;

        *a ^= *b;

}

 

int main()

{

        int m,n;

        m=1;

        n=2;

        printf("m=%d n=%d\n",m,n);

 

        change(&m,&n);

        printf("m=%d n=%d\n",m,n);

 

        return 0;

}

 

九:C基础(8

一〉结构体

1. 定义:

构造一个新的数据类型

 

struct person{

char name[20];

int height;

};

该数据类型叫 struct person

typedef struct person per;

 

typedef struct person{

char name[20];  //成员变量之间要用分号隔开,成员变量的数据类型可以相同也可以不同

int height;

}per;

 

初始化:per p1={"lijianfei",175};

访问结构体成员变量:结构体变量名.成员变量名

输出:printf("%s %d\n",p1.name,p1.height);

输入:scanf("%s%d",p1.name,&p1.height);

 

//定义一个指针指向p1

per * pper;

pper = &p1;

*pper <====> p1

(*pper).name   (*pper).height

//通过结构体指针访问成员变量

指针变量名->成员变量名

pper->name

pper->height

 

//定义一个结构体变量p2

per p2;

p2 = p1; //p1的值赋值给p2

p2.name    p2.height

 

2、字节对齐32OS    gcc编译器)

系统一次性分配的字节数是成员变量里面最大的字节对齐数

 

3、共同体

union union{

char ch;

int i;

};

注意:共同体所占内存空间取决于成员变量中最大的内存空间  sizeof(union un) = 4

  共同体中所有成员变量的首地址都是一致的,所以在某一时刻只能取一个成员变量使用

//定义一个共同体变量

union un u1;

 

4、大小端

大端序:低字节存高地址处,高字节存低地址处

小端序:低字节存低地址处,高字节存高地址处

 

判断计算机是大端序还是小端序:(通过共同体)

u1.i = 0x12345678;

if(u1.ch == 0x78)

printf("小端序\n");

else

printf("大端序\n");

 

5、Const

 

const 数据类型  变量名;  //该变量只读

const int a = 10;

a = 20;  //error    a只读

 

const char *p = "helloworld";

char str[20] = "helloworld";

const char *p = str;   //<====>char const *p = str;

*p = 'e';  --->error  str这片空间只读

 

char * const p = "hello";

p就只能指向“hello”这个字符串,不能再指向其他字符串

const是一个C语言的关键字,它限定一个变量不允许被改变。使用const在一定程度上可以提高程序的安全性和可靠性。另外,在观看别人代码的时候,清晰理解const所起的作用,对理解对方的程序也有一些帮助。另外CONST在其他编程语言中也有出现,如C++PHP5C#.netHC08C

 

3、指针函数:返回值是指针的函数就是指针函数

LINUX  C

 

一:SHELL基础3

一〉嵌入式系统3

二〉Linux软件管理机制3

1. dpkg-----3

2.apt_get-3

3.apt-cache-3

三〉APT软件包管理器3

四〉LINUX系统结构4

五〉SHELL命令5

六〉通配符6

七〉输入输出重定向6

八〉命令置换7

九〉进程管理7

十〉linux文件系统8

1.文件系统类型8

2.SCSI(机械硬盘)与IDE8

3.根目录文件9

4.文件类型10

5.创建链接文件:10

6.文件压缩与解压10

二:shell脚本编程基础11

一〉编写流程11

二〉:变量11

1.自定义变量11

2.位置参数与预定义变量11

3.环境变量12

三〉shell程序和语句12

1.语句12

1〉说明性语句13

2〉功能性语句13

3〉结构性语句15

四〉shell函数21

1.定义21

2.传参:21

三:c高级23

一〉引入23

二〉数组24

1:一维数组24

2:二维数组--按行存放24

三〉指针24

1:值访问25

2:运算25

3:一维数组与指针25

4.指针与二维数组26

5.指针数组27

6字符指针数组27

7:多级指针28

8:const/void指针28

四〉函数29

1.函数定义:29

2.函数声明:29

3.函数传参30

1〉复制传参30

2〉地址传递30

3〉全局变量31

4.指针函数31

5.函数指针32

六〉递归函数34

七〉GCC编译器35

1.编译运行步骤35

2.GNU工具35

3.定义-交叉平台编译器35

4.主要组件35

八〉GDB(用途小36

九〉结构体**36

1.结构体数组37

1〉定义struct stu a[3];37

2〉初始化38

3〉提取元素38

2.结构体指针38

3.结构体指针数组38

十>内存分配***39

1.存储模型39

1>变量39

2.动态分配39

十一〉makefile基本结构39

1. 工作原理40

2.基本格式40

 

 

 

 

 

一:SHELL基础

一〉嵌入式系统

X86 arm---体系架构

MIT---麻省理工

Ubuntu----”人道待人”理念

艾伦.图灵---计算机之父

Richard staliman-----自由软件之父(GNU运动(软件开源,免费)----gcc.gdb.gedit---->GNU/Linux(GNU运动下开发的LINUX系统)

嵌入式应用:无人驾驶----利用声呐不断测试与障碍物的距离来控制车速

二〉Linux软件管理机制

三个配置文件:

软件源配置文件(软件仓库):/etc/apt/sources.list

本地软件包索引文件(可下载的目录):/var/lib/apt/lists

本地文件下载缓存目录:/var/cache/apt/archives

  1. dpkg------

完成本地软件包安装管理(依赖关系明确)

注:在/var/cache/apt/archives(本地缓存目录---安装包存放的地方)下输入命令

命令:sudo dpkg -i <package(完整的安装包文件名--就在上面的那个目录下可以查看)>:安装软件

Sudo dpkg -P <package>:移除已经安装的软件包及配置文件

2.apt_get---管理下载文件

步骤:1:查找软件最新版本 2:配置文件依赖关系  3:下载  4:安装

Sudo apt-get install (-d) packg------下载并安装(不安装)

Sudo apt-get remove/clean/update/upgread/check(卸载/删除已下载的包文件/下载更新软件包信息列表(包括更新软件源里的软件信息)/升级到最新版本/查看系统中依赖关系的完整性)  [-d/--purge/--reinstall/-v/-f] (仅下载不安装/remove连用完全卸载(包括软件包与文件)/重新安装/获取版本号/修复依赖关系)packg

3.apt-cache---查询软件相关信息

Apt-cache  show/search/policy/depend(获取二进制软件包的详细信息/检索软件包/获取安装状态/获取依赖关系)

三〉APT软件包管理器

---1:检查修复软件包依赖关系 2:利用网络主动获取软件包

deb软件包(ubuntu系统):二进制软件包(deb--可直接安装   源码包(deb-src--需解压再安装

rehat系统:rpm软件包

四〉LINUX系统结构

  1. Shell是一个命令编译器,将用户命令编译成二进制程序,交给操作系统执行。【 F】??
  2. 在默认情况下,所定义的Shell变量的作用域是局部有效。【 F】
  3. 使用DHCP服务配置动态IP的过程,就犹如一个租借过程。【T 】

 

 

 

linux内核含有硬件驱动控制硬件,硬件做出相应的反应来控制shell,shell再将信息反馈给用户

 

SHELL---命令行解释器(更快更直接)

当前使用版本--bash(bourn again shell)<------sh(bourn shell)的增强版

五〉SHELL命令

Sudo shoutdown -h n/now--关机

Ctrl+c---取消关机

Sudo shoutdown -r n/now---重启==reboot(直接执行boot-loder(系统引导程序))

命令---指令  选项   参数

Ls -l DS/----显示DS目录下的内容

多命令在一行同时执行-----命令1;命令2..ls;pwd

一个命令在多行------命令.........

\命令.....

Tab---命令补齐

(两次tab----显示当前目录下具有相同前缀的名称

Less/more -----分页显示

查询历史命令:history n(默认500)

设置历史命令容纳量:HISTSIZE =m

Echo $HISTSIZE----查看

基本系统维护命令

Passwd---修改密码(root 可修改其他用户的(su))

Cd /home/----用户主目录

Export----查看环境变量----可以修改其中的环境变量(su -m

Echo----显示指令(当有多个空格时只打印一个(认为其为一个指令))  

Echo “ ”---显示字符串

Echo $PATH--查看当前编译路径

???Mips--:交叉编译

Date--查看当前时间

While(1)

{

System(“date”);

Sleep(1);

}//每秒打印一次时间

??????Date -s “%y-%m-%d”

**********df--查看磁盘空间使用率(tmpfs--虚拟内存空间:1G的虚拟内存可虚拟出4G的内存空间)

Df -a-----显示所有的文件系统使用情况(包括proc,sysfs虚拟内存)

Df -ah--M为单位显示

Du----显示每个文件/目录所占磁盘块数(每个磁盘占512个字节)

/etc/passwd 文件----用户清单(p86

/etc/group 文件-----组与成员列表(p89)

 

Adduser <用户名>----创建用户

************/etc/skel目录----/etc/sbin/adduser使用,将新用户想要的配置文件拷贝到/etc/skel

Usermod---修改用户属性(推出登陆root用户)

sudo usermod  -l  newname oldname(修改用户名)   

sudo usermod -d /home/user1(全新目录) -m(将家目录搬到新目录下,与-d一起使用) -l newname  oldname  --------------------(修改用户名并修改家/主目录)

Sudo deluser name----仅仅删除用户名,相关文件还存在

Sudo  deluser  --remove-home user1-----删除用户并删除用户目录

/etc/adduser.conf---- 用户配置文件

Sudo delgroup groupname---删除组

Exit----退出用户

*********************************

 

 

 

 

 

六〉通配符

1〉‘*---匹配任意长度的字符串(file_*.txt

’?’----匹配一个长度的字符

[]---匹配其中指定的一个字符(file_[ot].txt==file_o.txt,file_t.txt

‘[ - ]’-------指定的一个字符范围([a-z]

‘[^ ]’-----除了其指定的字符

管道:|-----第一个命令的输出作为第二个命令的输入

Eg:ls /usr/bin | wc -w-----统计指定目录下的文件数目

七〉输入输出重定向

1〉‘〉file---覆盖输入重定向

2〉‘〉〉file----追加输入重定向

3〉‘〈file---覆盖输出重定向

4〉‘<<file---追加输出重定向

’2>file’-----错误覆盖输出重定向

2>>file----错误追加重定向

Eg:ls 2.c 2> e.c

Char * fgets(char *s,int size,FILE *stream);

Fgets(str,10,stdin)----从缓冲区获取指定长度的字符(stdin(标准输入)  stdout(标准输出)

流;标准输入流-------》文件描述符    0

标准输出流                     1

标准错误流                     2

八〉命令置换

命令1  `命令2`------将命令2esc键下的但引号)的结果作为命令1 的参数

Eg:ls `pwd`

九〉进程管理

程序==数据结构+算法    静态

进程:程序的一次执行

 

命令:

Ps -au  ---〉仅显示当前用户的进程详细信息

%cpu---cpu占用率   %MEM---内存占用率  VSZ--虚拟文件使用字节数 RSS---占用磁盘字节数   TTY---正在使用的配置文件  STAT--状态 START---运行时间

Ps  -aux ---->显示所有用户进程信息

Top ----实时监控进程: NI----进程优先级    PR---进程控制块     

???????Nice -----调整进程优先级

KILL   PID-----终止进程==ctrl+c(向内核发送KILL9)(强制终止进程)

进程状态

 

Z---将死态(没运行,但占一部分空间) L不重要

+----进程挂起

十〉linux文件系统

1.文件系统类型

df查看磁盘空间

磁盘文件系统:

网络文件系统:NFS(文件系统)---系统移植应用

专有/虚拟文件系统

2.SCSI(机械硬盘)与IDE

固态读写快,作为系统盘15秒开机了解一下。240g再储存点常用软件和网游绰绰有余了。

机械读写慢,但可以作为储存文档,电影等数据之类的硬盘,相对于固态也更安全,更稳定。如果固态的容量不够可以考虑再加一个机械。如果240g就够用的话也没必要再加机械。

内存----内存条(执行程序时的变量等)--断电重启后数据不在

外存----a.out存在磁盘空间---断电重启后数据还在

IDE--固定硬盘

Sata---机械硬盘

交换分区----交换分区(了解)(将内存内容写到磁盘,或从内存读出)

 

 

3.根目录文件

/(linux文件系统根目录)          /bin(存放系统中最常用的可执行文件(二进制文件))   

/boot(存放Linux内核和系统启动文件)          /dev(设备文件)

  /etc(配置文件,用户信息文件等)              /home(用户主目录)   

/lib(存放共享的库文件)     /mnt(存放被挂载文件的挂载点----可用于文件共享)        

/proc(存放所有标志为文件的进程)    /root(超级用户主目录)  /var(存放长度可变的文件)

 

Linuxwindows区别

EXT4---LINNX现在最新文件格式   FAT64--windows常用文件格式

最大区别:(换行符区别)LINUX---\n windows---\r\-n

4.文件类型

 

命令:

File  <name>---查看文件类型

Cp  目标  被复制  -r  ----------------复制目录

Mv day2/ ~ ---移动到家目录

Mkdir -p mm/kk/ll

LINUX不会显示二进制内容   cat a.out---结果是乱码

Head -n name  tail -n name-----显示头尾指定行数

 

5.创建链接文件:

硬链接:利用linux分配的物理编号--inode建立链接-----不能跨越文件系统---不可恢复

软链接:利用文件的路径名建立链接(相对路径)--可恢复(重新创建一个同名的link-name链接又会重新启动)

ln [-s(软链接)] target link-name(改变target的内容Link-name的内容会相应的改变)

6.文件压缩与解压

归档文件(.tar):将一组文件或目录保存在一个文件中---使占用磁盘空间增大

压缩文件(.gz):将一组文件或目录保存在一个文件中,并以某种存储格式存储在磁盘空间上,内存总和比所有文件之和小

1Gzip工具:有链接文件不能被压缩打包(windows无链接文件)

Gzip -d/-l/-num(1-9)(解压/查看压缩文件内的信息/指定压缩比率(默认6),数字越大压缩力度越大)  name

Gunzip  [-f] (提示已经有的同名文件)name-----解压

2Tar命令(归档文件)[-c]  tarname  filename

 

Tar -cf 123.tar 1.c 2.c 3.c ---->tar -xvf 123.tar  创建一个新的归档文件

Tar -xfv  123.tar  -----解压并显示指定归档文件

Gzip  -d  123.tar --->解压==gunzip

二:shell脚本编程基础

运维师与外挂

shell区分大小写

一〉编写流程#!/bin/bash(当前使用的脚本类型,执行该文件的程序)--开头一行(!虽然注释掉了但系统可以阅读)-----------〉编写程序并保存退出----〉给文件设置执行权限(chmod  权限  文件名)-----./x.sh(运行程序)

 

二〉:变量

1.自定义变量(默认为全局变量)

变量名=

取用变量值:$变量名6g

Num=20

Unset num

2.位置参数与预定义变量

c语言中:int main(int argc ,char *argv[])命令行参数

 

$?-返回调用函数的返回值

3.环境变量

 

 

$HOME--引用

PATH(默认路径,执行shell脚本时可以快速找到):---shell可执行的路径(x.sh放在其路径下,不用指定其路径(x.sh直接运行))

执行程序必须知道其存放路径:./x.sh

/bin-----存放基本的指令(二进制可执行程序)

DATE=`date`----命令置换   LIST=`list`

Unset---取消环境变量,在命令行输入:unset z

Set---设置环境变量

三〉shell程序和语句

1.语句

 

比较---条件测试语句

1〉说明性语句

 

2〉功能性语句

 

Read----阻塞功能,被read赋值的变量不允许再次被赋值,read 可被回车终止

 

Read var1 var2 var3  

              

注:运算符左右两侧必须加空格

 

*----通配符,利用‘\’去除二义性

$num=9---$命令行提示符

I++------->$i=`expr $i + 1`(x)   对:i=`expr $i + 1`

test==[ x ]

$?(上一条命令的结果)------0为真,非0为假

 

Z--zero  n--no

 

eq==ne==not eq  gt==big than  ge==big eq lt==last than le==last eq

text测试时“=”两边必须有空格

-d(目录文件) -f(普通文件)重要

整数测试时-ge表达式, 前后都是需要数字类型的变量或者常量, 一般都是${xxx} 不用加双引号  

3〉结构性语句

分支语句

 

 

注:条件(test) ’[]‘里面最左边与最右边必须有空格

-a(逻辑与) -o(逻辑或)  !(逻辑非)

 

If  [ 条件 ]

Then

 Elif [ 条件 ]

Then

 Else

 fi

 

 

Let 指令--取十位      ‘|’将多个项合并

 

循环语句

 

 

 

实现1-100的和 将当前目录下的所有文件拷贝到上一级目录

        

                    

*可打印出当前路径下的所有文件名     

仅仅打印当前路径

 

 

 

创建文件 $1$i--文件名,从键盘输入file 3

 

 

删除文件:命令行输入file 1 3

if [ $# -eq 3 ]

then

count=$3

else

echo input error

exit

fi

 

i=$2//1

while [ $i -le $count ]

do

rm $1$i # file1 file2 file3

let i++

done

 

 

循环控制语句

第一次$output为空

作业:用shell打印9*9乘法表

Echo (默认换行) 参数选项: -n 输出文字不换行
       -e 将转义符跟后边的特殊字符解释成特殊意义
       -E  不解释转义字符 

1〉#!/bin/bash

For i in {1..9}

Do

Foe j in {1..9}//error----{1..$i}

Do

If [ $j -le $i ]

Then

Let sum=$i*$j

Echo -ne “$j*$i=$sum\t”//\t----水平制表符

Fi

Done

Echo

Done

2〉

for ((i=1;i<=9;i++))

        {   

                for ((j=1;j<=$i;j++))

                        {   

                                let sum=$i*$j

                                echo -ne "$j*$i=$sum\t"

        }   

                echo " "

 

}

 

 

 

3

 

 

\t----水平制表符

四〉shell函数

1.定义

 

2.传参:

 

 

..传给$1  -aux传给$2

 

实现两个数相加($?获取上一程序的状态)

 

abc为全局变量123  456

 

设置局部变量:local 变量名

 

打印出123 123

 

三:c高级

一个寄存器只有十多个字节。定义寄存器变量时,也存放在栈区

一〉引入

判断寄存器存储变量与AUTO变量执行速度

Time(&sttar)---以秒统计时间

 

For(;j<=N;j++);

Time(&stop);

Printf(“%d\n”,stop-start);

 

Time_t t;time(&t);//将从1970.1.1到当前时间的秒数赋给变量t

printf(“today’s time and date is %s”,ctime(&t));------打印出当前日期与时间(ctime(&t)将秒数转换为日期与时间)

二〉数组

1:一维数组

Int n=10;int arr[n];()

Int n=10;int arr[n]={1,2,3,4};()---n为可变值

初始化时,才被分配空间

gcc编译不能查看数组越界

 

str后面存放str1打印结果---hellohaa

2:二维数组--按行存放

 

 

Arr=&arr[0]

Arr[0]=&arr[0][0]

因为arr[0]arr[0][0]的地址重合因此打印出的地址相同,但是*arr=&arr[0][0]为一个地址,*&arr[0][0]=arr[0][0]--为一个值

三〉指针

地址--内存单元的编号

此时野指针并没有被使用因此不会报错

空指针 ---物理--0地址

       ---逻辑-不会指向任何地方(与野指针相对)

Int *p=NULL<==>int *p=0;(0NULL的编号)vi /user/lib/gcc/.....(宏定义地址)

1:值访问

Int n=20;int  *p=&n;

Int *p = (int *)100;(强制转换)对---

1〉直接访问:n=20                  2>间接访问:*p=20-----寄存器只能间接访问

‘*’-----解引用符

2:运算----实质是地址的偏移

1>两个指针之间不能进行‘+           2〉倒叙字符串

              

3数据类型不匹配,无法获取想要的数据,将返回0

 

3:一维数组与指针

 

a为地址常量,只读,a++

1〉求最小值

 

4.指针与二维数组

二维数组元素名,为行地址

数组指针--〉行指针只能指向二维数组---int (*p)[3]=a//[二维数组的每个元素里有多少个数据]

 

 

p[i] <-->*(p+i)-----*/ []:降维作用

P[i][j]----1:p[i]看作一个整体将其解引用得(*p+i)[j]-----[j]先解引用*(p[i]+j)-----将两个都解引用*(*p+i+j)

 

5.指针数组

Int *a3[2]-----[二维数组元素个数]

 

 

a2,a4所存内容一样,为同一片内存空间,只是行列数划分不同,但对其操作不会越界

A2[2][3]; 1 2 3/4 5 6/

A4[3][2]:1 2/3 4/5 6/

6字符指针数组---存放的为字符指针常量的首地址,不能被修改

 

Char *str[5]:指针访问常量区,字符串  常量   char str1[]:字符串变量

printf(%c,**y);---h  y++--->段错误

7:多级指针

二级指针--指针的地址

&char *

 

打印出world                                      打印出e

 P+1------地址偏移4个字节,因为其中存的字符串地址占四个字节

二级指针与二维Int数组                               

 

Int **p=b----p指向a[0]

*p+1---第一行再移一个

8const/void指针

1Const---修饰一个变量为只读

Egstrcat(char *dest,const char *src)

Strcat(dest,”http”);

修饰指针:

1

Int  const *p=&n;//*p不能修改

指针数据类型与所指对象的数据类型要相同

2void 指针

Void *p=&a;

引用:*int *p

---可指向任意数据类型--但因无确定的数据类型,无法知道取多少空间里的数据,因此需要强制转换

 

四〉函数

1.函数定义:完成某些特定功能的代码模块。形参名不可省

 

2.函数声明:若函数定义写在main函数之后,就必须写.   形参名可省

Eg:int add(int ,int ); int add(int a,int b);

 

注:个代码程序,有且仅有一个main函数

3.函数传参

1〉复制传参

实参并没发生交换

2〉地址传递

Swap&x,&y

仅仅将p q里面的内容传给了子函数,而p q地址不变----------相当于复制传递

 

实现了两个实参值的交换

传递函数:一维整型数组,字符数组传参,二维数组

地址传参:int (*a)[3]    int a[][3]--复制传参       但两者都是地址

  

3〉全局变量---定义在所有函数之外

Int flag;

Func(flag)

static变量与全局变量不做初始化,初始化默认为0----放在静态变量数据区

Eg:

N--二维数组行    m----二维数组列

 

4.指针函数----返回值为地址

Eg:

 

p--变量的值,str3----地址

函数可以返回一个值:p可以返回,并由p存储的地址里面的内容依然存在,而str3能返回,但其内容已经被销毁,因此不能返回一个局部变量的地址

static修饰时,可以返回str里面的内容

Static:(变量存放在静态存储区)

一:修饰局部变量----增长了变量的生命周期

二:修饰函数:限制函数的作用域,只能在当前文件中被调用

三:修饰全局变量:限制变量作用域,只能在本文件中使用

static可由程序员手动放入堆区,没有运行的代码放入代码段中

5.函数指针==函数名

定义:存放函数地址的指针

 

 

函数返回值类型  *指针名)(函数参数类型)

指针指向函数:函数名就为函数的起始地址

 

q==add-->add[10,20]==q[20][20];

 

Char * *p(char *,char*)

小应用:float decall(float (*fp)(int),int n)//float (*fp)()函数指针

{

        float s;

        s=(*fp)(n);//调用函数指针

        return s;

}

 

 

五〉函数指针数组

 

 

调用:

六〉递归函数(做题)

1〉自己调用自己 2〉寻找递归终止条件

先递推再回归

 

例子:5

 

 

 

七〉GCC编译器GNU CC

1.编译运行步骤

 

1: .c ----->.i    2: .i--.s  3: .s-->.o

.so/----动态库  ./a静态库  ----------cd /lib

2.GNU工具

3.定义-交叉平台编译器

4.主要组件

分析器:将源语言程序代码转换为汇编语言

汇编器:将汇编语言代码转换为CPU可执行字节代码(二进制文件)

链接器:将汇编器生成的单独目标文件组合成可执行的应用程序

标准C库:标准的C函数都由C库提供

生成汇编文件----〉检查语法错误

 

 

八〉GDB(用途小---数组越界

----printf()代替,查看错误 printf行缓存函数---当输出内容占满一行才输出,因此需利用\n来结束一行的缓存

 

九〉结构体***

---数据结构的链表使用

 

 

结构体对齐标准:最长字节对齐方式(编译器不同对齐不同),GCC4字节对齐方式

 

 

1.结构体数组

1〉定义struct stu a[3];     

 

2〉初始化

 

3〉提取元素

 

4:结构体调用结构体

-----调用

2.结构体指针

1:定义                             2:调用

                  

3.结构体指针数组

 

十>内存分配***

1.存储模型

1>变量

 

全局变量与局部变量---若两个变量名相同,在局部就对局部变量进行操作

 

具有外部链接的静态   :外部链接,所有函数之外

具有内部链接的静态 :内部链接(static,所有函数之外

空链接的静态  :局部变量+static

2.动态分配-----heap(堆区)

 

----应为malloc返回为void *因此需强制转换为与p的数据类型相同的空间

Free()---仅仅需要释放空间的首地址

十一〉makefile基本结构

----------工程管理器

1.工作原理

make工程管理器根据( 文件时间戳 )来自动发现更新过的文件从而减少编译的工作量。

2.基本格式

 

避免头文件重复定义

sunq为可执行程序

 

 

$@  $^:所有的依赖文件

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2020-01-12 17:04  糖糖_彭  阅读(69)  评论(0编辑  收藏  举报