嵌入式学习第二周

day6

数组

1概念

一组数据类型相同的元素组合在一起

1 数据类型相同 2 地址连续

2定义

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

          Int    a;

存储类型  数据类型  数组名【元素的个数】;

           Int       arr[5];

           Float     brr【5】;

定义了一个数组,数组名为arr,数组中有五个int类型元素;

数组名:arr

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

数组的数据类型是什么?

数据类型:去掉变量名,就是数据类型

数组的数据类型: int [5];

Int arr[5];//数据类型是 int [5];

Int brr[6];//数据类型是 int [6];

Int crr[5];

int [5]和int [6]表示的数据类型是不一样的;


元素的个数:必须为一个确定的值

数组名

代表数组首元素的地址(可以表示整个数组)

%p:打印地址

3初始化

3.1部分初始化

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

部分初始化,未被初始化的部分,值为0

用此特性给数组清零

Int arr[5]={0};

3.2全部初始化

全部进行初始化

Int arr【】;//error

只有全部初始化的时候才可以这样去做!!!

Int arr[ ] = {1,2,3}; //可以,编译器自动计算数组元素的个数

如果不进行初始化:产生的结果

总结:

  1. 数组定义在函数体外,(相当于全局变量)不初始化,元素都为0
  2. 数组定义在函数体内,(相当于局部变量)不初始化,元素为随机值

数组定义在函数体内,(相当于用static修饰局部变量)用static修饰,不初始化,元素都为0

4访问

案例:判断以下四个是否正确

1、int a[5];(a[0]----a[4])

   a[4] = {1,2,3,4,5} ;  //error 没有a[5]

2、int a[5];

   a = {1,2,3,4,5};  //error数组名表示数组首元素的地址

3、int a[ ] = {0};  //对,没有意义 int a = 0;

4、int a[ ];  //error 编译器不知道要分配多大的内存空间

5冒泡排序

(c语言阶段唯一一个算法)

Int arr[5] = { 14, 85,99,2,30};------------> 2,14,30,85,99

思想:从左向右两两依次比较,如果前一个数大于后一个数,就交换位置;反之,不变。

字符数组

定义:

字符数组的本质就是字符串

存储类型  数据类型 数组名[元素的个数];

          Char str[10];

定义了一个名为str的字符数组,所占内存空间:sizeof(数据类型)*元素的个数=1*10=10

数据类型:元素的数据类型

数组的数据类型:char [10];

初始化:char str[10]={‘s’,’h’,’a’,’n’,’g’};

        Char sstr[6]={‘h’,’e’,’l’,’l’,’o’};//自己最多只能去初始化五个字符,因为要给’\0’留位置

Char atr[10]=”hello”;

用部分初始化的特性去给字符数组清零:char btr[10]={‘\0’};   

1字符串的输出函数

%s:输出字符串

Puts(数组名);

功能:将数组的内容打印到终端,并自动添加换行

注意:遇到’\0’结束

2字符串的输入函数

gets(数组名)

功能:将键盘接受到的字符串存入数组,并会在末尾添‘\0’

注意:不会进行越界检查,输入的时候要注意不要越界

3scanf和gets的区别

  1. scanf是标准输入函数,他每次输入都会采用键入的方式,不会去检查缓冲区有无内容
  2. gets会先去检查缓冲区有没有东西,如果缓冲区有内容,他会率先去读取缓冲区的内容

注意:

scanf每次输入后,会在缓冲区遗留 空格回车tab键

gets每次输入完毕之后,他会自动清空缓冲区里面的内容

4printf和puts的区别

puts会自动换行,printf不会

day7

字符串处理函数

Strlen、 strcpy、 strcat、 strcmp、

man手册去查看字符串处理函数需要的头文件

头文件:#include <string.h>

1求字符串的长度

Strlen(数组名);

返回值:字符串的长度

功能:计算字符串的实际长度,不包括‘\0’

Sizeof和strlen的区别:

  1. sizeof是一个运算符,strlen是函数
  2. Sizeof求到的是所占内存空间的大小,strlen求到的字符串的实际长度(不包含’\0’)

示例:不使用字符串处理函数,求字符串的实际长度

2字符串拷贝函数

Strcpy(数组1,数组2/字符串);

Puts(数组1);

功能:将数组2的内容完全拷贝给数组1,包括‘\0’,相当于完全拷贝

strncpy(数组1,数组2/字符串,n);

功能:将数组2的前n个拷贝给数组1,不包含’\0’;

3 字符串连接函数

Strcat(数组1,数组2/字符串)

功能:将数组2的内容连接至数组1中,会覆盖数组1的‘\0’

注意:数组1的内存大小要能够存储下两个数组1和数组2连接出来的结果

Char str1[20] = “hello”;

Char str2[20] = “world”;

Strcat(str1,str2);

Puts(str1);

Strncat

Strncat(数组1,数组2/字符串,n)

功能:将数组2 的前n个字符连接到数组1后面

4字符串比较函数

Strcmp(数组1,数组2/字符串);

功能:比较两个字符串的大小

返回值:

当字符串1 > 字符串2,返回值大于0

当字符串1 == 字符串2,返回值等于0

当字符串1 < 字符串2,返回值小于0

如何比较:从左往右依次对字符串中的ascii码值就行比较,直到遇到ascii码值不同时或‘\0’结束比较

二维数组

概念

一组数据类型相同的元素组合在一起

  1. 数据类型相同   2、地址连续

二维数组:他是元素为一维数组的一维数组,他的本质还是一维数组

定义

存储类型 数据类型 数组名[元素的个数];

存储类型 数据类型 数组名[行数][列数];

Int a[2][3];

行数:二维数组中有几个一维数组

列数:一维数组中元素的个数

数据类型: 元素的数据类型

二维数组的数据类型: int [2][3];

二维数组中存储了几个元素: 行数*列数

初始化

2.3.1 部分初始化

Int a[2][3]= {1,2};

a[0][0]= 1, a[0][1]= 2,a[0][2]= ?,a[1][0]=?,a[1][1]=?,a[1][2]= ?

部分初始化,未初始化的部分值为0

利用部分初始化的特性可以给数组清零:

Int a[2][3]= {0};

2.3.2 全部初始化

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

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

思考:行数和列数是否可以省略?(行可以省略,列不可以)

省略行数: a[ ][3]= {1,2,3,4,5,6,7,8};  //可以省略行数

省略列数: a[2][ ]= {1,2,3,4,5,6}; //不可以省略列数

访问

下标【】从零开始

 

二维字符数组

Int str[10];

Char atr[10];字符数组的本质是字符串

Int a[3][4];

Char btr[4][5];

存储类型 数据类型 数组名[行数][列数];

         Char    str[4][10];

行数:一维字符数组的个数(字符串的个数)

列数:一维数组里面元素的个数

 

day8

函数

具有独立功能的模块

为什么要使用函数

1、为了让程序变得模块化

2、提高代码的复用率

函数的分类

1 库函数

Printf  scanf  strlen

2 引用文件

#include<stdio.h>   #include <string.h>

3 调用函数

Strlen(str);

返回值:求到的字符串的实际长度,int类型

函数名(实际参数列表);

注意:有几个参数,数据类型是什么,返回值

自定义函数

1 定义一个函数

存储类型 数据类型 函数名(形式参数列表)

{

函数体;

返回值;

}

数据类型:返回值的数据类型

函数名:见名知意,标识符(3点要求)

形式参数列表:需要传的参数类型,需要调用者传入

函数体:具体功能的实现

返回值:不需要,可以不写,如果需要返回值,有且只能有一个返回值

2 调用函数

函数名(实际参数列表);

注意:

  1. 需要将实参的值传递给形参,实参的个数和数据类型必须和形参一样
  2. 实参可以是变量,常量,表达式,必须是一个确定的值
  3. 实参和形参是两块独立的空间
  4. 传参实际上是将实参的值拷贝给形参
  5. 形参在函数调用时被定义,函数调用完毕之后,释放

3 调用函数2

 

4 函数调用完毕

 

5 函数的声明

如果函数没有在main函数之前,需要添加声明;

未声明:

声明:将函数头部复制粘贴至main函数之前,加上;

加上声明之后:

声明的作用:帮助编译器做检查

案例:封装实现加减乘除的函数,并调用输出

指针

1 指针是什么?

指针是一种数据类型,他是一种保存地址的数据类型。

Int 类型是用来保存整型数据的

Int a;//保存整形数;

Float b;//保存小数

指针://保存地址的数据类型

2 指针的定义

内存分配的最小单元是字节,每个字节都有一个编号。这个编号就是地址

地址:内存单元的编号

Int a;

%p,打印a的地址;0x100(&a 为 0x100)

指针就是地址

指针的本质也就是内存单元的编号

3 访问

存储类型 数据类型 *指针变量名

Int  *p;

数据类型:指针指向的数据类型

指针的数据类型:int *;

数组的首元素的地址:

数组名:表示数组首元素的地址

 

4 赋值

注意:给指针赋值的时候要注意数据类型匹配

思考:

  1. 什么是指针?
  2. 地址是什么?
  3. 什么是指针变量?
  4. 指针变量如何去定义?
  5. 如何去给指针变量赋值?
  6. 指针变量赋值之后,可以干什么?
  7. 注意:在32OS中,指针类型占4个字节

  8. 在64OS中,指针类型占8个字节

5 野指针

野指针:不知道指向哪里的指针

怎样避免野指针:定义时先让指针指向0号地址

6 空指针

没有指向指针(值为0的指针,指向NULL)

规定:0号地址不允许操作;

如果想要操作空指针,改变指针的指向

7 值传递

8 地址传递

作业:用函数封装实现数组的输入输出

  1. 先思考需要传递什么参数
  2. 是否需要返回值
  3. 给函数起名:见名知意

 

day9

二级指针

1概念

二级指针:保存一级指针的地址

存储类型 数据类型 *指针变量名;

定义一个一级指针:int  *p;指向整型的一个指针;

一级指针的数据类型: int *;

2定义

存储类型 数据类型 *指针变量名;

数据类型:指针指向的数据类型(二级指针现在要指向一级指针)

        Int **pp;

二级指针的数据类型: int **

 

3总结

1、指针的数据类型,(去掉指针变量名)

Int *p;//int *

Int **pp;//int **

Int ***ppp;//int ***

2、指针指向的数据类型,(去掉变量名和一个*)

Int *p;//指向int

Int **pp;//指向 int *

Int ***ppp;//指向int**

  1. 三级指针

Int ***ppp= NULL;

三级指针:保存二级指针的地址

Int **pp;

ppp= &pp;

4指针的算术运算

总结:

p+n:p+n相当于向地址增大的方向移动n个数据类型

实际的变化:向地址增大的方向移动:n *sizeof(p指向的数据类型)个字节

p-n: p-n相当于向地址减小的方向移动n个数据类型

实际的变化:向地址减小的方向移动:n*sizeof(p指向的数据类型)个字节

p++:p向地址增大的方向移动一个数据类型(p指向的数据类型)

p--:p向地址见效的方向移动一个数据类型(p指向的数据类型)

p-q:(p和q的数据类型要相同)//两个之间相差的元素

注意:1、指针可以进行计算,同时指针常量也可以进行计算,++,--除外

2、只有在访问连续的空间时,指针的运算才有意义

注意:printf又结合

5指针与一维数组的关系

1 通过指针常量访问数组元素

 注意:指针常量(数组名)不可以自加自减

2 通过指针变量访问数组元素

通过指针变量取访问数组,但是指针的指向并没有改变 

3 总结

1、访问数组的元素

2、数组名代表的是,数组首元素的地址,是一个指针常量,不可以++ ,--;

3、上面三种情况都相当做指针处理,在64os占8个字节,在32os占4个字节

4 案例:用指针实现冒泡排序

5.4.1 用指针变量实现

5.4.2 用指针移动实现

day10

 指针与二维数组的关系

通过指针常量去访问数组的元素

 

数组指针和指针数组

数组指针

谁在后面,那么这个东西的本质就是谁

数组指针:本质是一个指针

概念

指向数组的指针

定义

存储类型  数据类型 (*指针变量名) [元素的个数];

数据类型:数组指针指向的数组中元素的数据类型

* 和 [] :谁的优先级更高,[],可是,我们现在要定义的是一个指针,所以要让变量名先与*接触,所以,要将*与变量名用()括起来;

元素的个数:一维数组中元素的个数

int a; //数据类型  int

Int *p;//数据类型int*

P = &a;//一个指向整型变量的指针

Int arr[5]={0};//定义了一个整形数组  int [5]

Int (*p)[5]= NULL;//数据类型,int(*)[5]

P = &arr;

数组名:

1、表示数组中首元素的地址

  1. 整个数组

数组指针与一维数组

 注意:数组指针几乎是不用来操作一维数组,更多的是用来操作二维数组。因为指针在访问连续的内存空间才有意义,如果是一维数组,p+1就会越界

数组指针与二维数组

 

 

指针数组

本质:指针数组,是一个数组

整型数组:数组中的元素是整型

字符数组:数组中的元素是字符

指针数组:数组中的元素是指针(地址)

概念

元素为指针的数组

定义

以前定义一个整型数组:

Int arr[5];//定义了一个数组,数组中有五个元素,元素都是int类型

定义一个指针数组:

存储类型 数据类型 *变量名[元素的个数];

数组名先和*还是[ ]结合?

:此时变量名先和[ ]结合,所以定义的这个本质是一个数组

数据类型 * :数组中元素的数据类型

Int * arr[3];

//定义了一个数组,数组名为arr,数字组中有三个元素,每一个元素都是int *;

指针数组与二维数组

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值