Day5 数组
概念
一组数据类型相同的元素组和在一起
特点:(1)数据类型相同 (2)地址连续
定义
存储类型 数据类型 变量名;
存储类型 数据类型 数组名[ 元素的个数 ];
存储类型:auto、static、extern、register
数据类型:数组中元素的数据类型
数组的数据类型:int [5];
数据类型:去掉变量名,剩下的就是数据类型;
数组所占的内存空间的大小 = sizeof(数据类型)* 元素的个数
数组名:(1)整个数组(2)数组首元素的地址
注意:定义数组时,元素的个数必须为一个确定的值(常量/常量表达式)
初始化
部分初始化
当进行部分初始化时:没有初始化的部分为0,因此,我们可以利用此特性给数组进行清零
全部初始化
只有在进行全部初始化时:元素的个数才可以省略
总结:
(1)数组定义在函数体内,如果没有进行初始化,里面的所有元素是随机值(局部变量)
(2)数组定义在函数体外,如果没有进行初始化,里面的所有元素为0(全局变量)
(3)数组定义在函数体内,并且用static进行修饰,里面的所有元素为0(静态局部变量)
访问
数组名[下标];
Day6
冒泡排序
字符数组
整型数组:保存一组int类型的数据
存储类型 数据类型 数组名[元素的个数];
数据类型:数组中元素的数据类型
字符数组:保存一组char类型的数据
存储类型 数据类型 数组名[元素的个数];
数据类型:数组中元素的数据类型
定义: char str[10];//定义了一个字符数组str,该数组中可以存放10个char类型的字符
数组所占的内存空间== sizeof(char)*10 = 10
数组的数据类型:char [10];//去掉数组名
字符串输入输出函数
输出函数
%s:字符串
Printf(“ %s ”, str);
puts(数组名);
功能:将数组中的内容打印到终端,并且自动换行
注意:打印到‘\0结束
输入函数
Scanf(“%s”,str);
gets(数组名);
功能:将输入的字符串保存在数组中,并且在末尾自动添加‘\0’
注意:gets不会进行越界检查,如果超出范围,就会操作未申请到的内存空间,段错误
出现段错误的原因:非法操作你没有申请的空间
scanf和gets的区别
(1)Scanf写在gets之上时,会出现异常情况(gets吃掉了‘\n’)
gets以回车作为结束符,但是scanf以空格,回车TAB作为变量输入结束的标志
(2)缓冲区:
Gets在输入结束后,会自动清空缓冲区的内容
Scanf在输入结束后,会在缓冲区中遗留空格、回车、tab
输入:
Gets:进行输入时,回先去检查缓冲区的内容,如果缓冲区有内容,会率先输出缓冲区当中的内容
Scanf:键入,不会检查缓冲区的内容
printf和puts的区别
puts会自动换行,而printf不会
字符串的处理函数
Strlen、 strcpy、strcat、strcmp
求长度
Strlen(数组名);
功能:求字符串的长度
返回值:求得的字符串的实际长度,不包含’\0’
strlen和sizeof的区别:
(1)strlen求到的是字符串的实际长度,而sizeof求到的是申请到的内存空间的大小
(2)Strlen是一个函数,sizeof是一个运算符
拷贝函数
Strcpy(数组1,数组2/字符串);
作用:将数组2中的内容拷贝给数组1,包含‘\0’,相当于完全拷贝
注意:数组1的容量要大于数组2
Strncpy(数组1,,数组2/字符串,n);
作用:将数组2或者字符串中的前n个字符拷贝给数组1
连接函数
Strcat(数组1,数组2/字符串);
功能:将数组2中的内容连接到数组1中去,数组1中的’\0’会被覆盖
Strncat(数组1,数组2/字符串,n)
功能:将字符串2的前n个字符连接到字符串1后
比较函数
Strcmp(数组1/字符串1,数组2/字符串2);
功能:比较字符串1和字符串2的大小
Day7 二维数组
概念
数组:一堆数据类型相同的元素组和在一起
整形数组:一堆int类型的元素组合在一起
字符数组:一堆char类型的元素组合在一起
二维数组:(数组数组):一堆数组的元素组合在一起
元素为一维数组的一维数组
特点:(1)数据类型相同 (2)地址连续
定义
存储类型 数据类型 数组名[元素的个数];
数据类型:元素的数据类型
一维数组的数据类型:int[3];
定义一个二维数组:存储类型 数据类型 数组名[行数][列数];
行数:一维整型数组的个数
列数:一维整型数组中元素的个数
实际的元素的个数:行数*列数
内存空间的大小:sizeof(数据类型)*行数*列数
数据类型:数组最里面的元素的数据类型
初始化
部分初始化
Int a[3][4] = {1,2,3};
Int a[3][4] = {{1,2,3},{1},{1,2}};
Int a[3][4] = {0};//清零
全部初始化
Int a[2][3] = {1,2,3,4,5,6};
Int a[2][3] = {{1,2,3},{4,5,6}};
访问
二维字符数组
二维整形数组
定义一个二维整型数组:存储类型 数据类型 数组名[行数][列数];
二维字符数组:存储类型 数据类型 数组名[行数][列数];
行数:字符串的个数(一维字符数组的个数)
列数:字符串最多可以保存几个字符(一维数组中元素的个数)
函数
定义
具有独立功能的模块
意义
(1)提高代码的复用率
(2)让程序变得模块化、简洁
库函数
eg:printf scanf strlen
引入头文件
#include <stdio.h>
#include <string.h>
调用函数
函数名(参数);
Strlen(参数);
返回值:int(字符串的实际长度)
注意:参数的个数,以及参数的类型;返回值的类型(是否需要接收返回值)
自定义函数
自定义函数
存储类型 数据类型 函数名(形式参数列表)
{
函数体;
}
存储类型:auto、static、extern、register
数据类型: 返回值的数据类型(void)(数据类型省略不写,默认是int类型)
函数名: 见名知意
形式参数列表:(由程序员自己去确定!)要实现的功能需要几个参数,以及每个参数是什么类型
函数体:实现具体的功能
返回值:若没有返回值,void;返回值也可以省略,如果省略,默认int类型(返回有且只能有一个)
调用函数
函数名(实际参数列表);
注意:
(1)需要将实参的值拷贝给形参,实参的个数以及数据类型要和形参一致
(2)实参,可以是变量,常量,表达式,但是必须是一个确定的值
(3)实参和形参是两块独立的空间
(4)传参,实际上是将实参的值拷贝给形参
(5)形参是局部变量,在函数调用时开辟空间,函数调用结束,立即释放
调用中与调用完毕
函数声明
如果函数没有写在main函数之前,就需要声明;
声明:将函数头部直接复制粘贴至main函数之前,然后加上分号
声明的作用:帮助编译器做语法检查
Day8 指针
概念
指针是一种数据类型,它是一种保存地址的数据类型
Int是一种数据类型,它是一种保存整形数的数据类型
Char是一种数据类型,它是一种保存字符的数据类型
地址
内存分配的最小单元:字节
每一个字节都有一个编号,我们把这个编号就叫做地址
地址的本质:内存单元的编号
指针:指针就是地址
指针的本质:内存单元的编号
指针变量
Int a ; //a是用来保存整形数 10(整型常量) a(整型变量)
Char b;//b是用来保存字符的 ‘a’
Float c;//c是用来保存浮点数 3.14
指针 p;//p就是用来保存地址的 0x100
P:指针变量
定义
存储类型 数据类型 * 指针变量名;
Int * p;
//定义了一个指针变量p,p用是用来保存(谁的(int)地址)地址
数据类型:指针指向的数据类型(指针保存的是什么数据类型的变量的地址)
指针的数据类型:int *
指针的赋值
指针的赋值相当于改变指针的指向(指针赋值时要注意 指针指向的数据类型必须相同)
空指针
指向零号地址的指针(值为0的指针,就认为该指针没有指向)
注意:零号地址禁止操作
野指针
野指针:不知道指向哪里的指针
局部变量,没有初始化,随机值
局部指针变量,如果没有初始化,就是野指针
二级指针
概念
Int *p; //用来保存int类型变量的地址 //整形指针
Char *p;//用来保存char类型变量的地址 //字符指针
Float *p;//用来保存float类型的变量的地址 //浮点型指针
保存一级指针的地址 //指针指针
定义
存储类型 数据类型 *指针变量名;
Int * *pp;
数据类型:指针指向的数据类型;(二级指针指向的数据类型:一级指针的数据类型)
(int *)
二级指针的数据类型:int **;
指针的算术运算
p+n:p向地址增大的方向移动了n个数据
p实际的变化:p + sizeof(指针指向的数据类型)*n
P-n: p向地址见效的方向移动了n个数据
p实际的变化:p - sizeof(指针指向的数据类型)*n
P++: p向地址增大的方向移动了一个数据 //改变指针的指向
p = p+sizeof(指针指向的数据类型)
P--:p向地址减小的方向移动了一个数据 //改变指针的指向
p = p-sizeof(指针指向的数据类型)
p-q:(p和q数据类型必须相同):这两个指针之间相隔的个数
实际的变化:(q-p)/sizeof(指针指向的数据类型)
指针和数组的关系
指针常量和一维数组
指针变量和一维数组
冒泡排序
指针的指向不发生改变:
指针的指向发生改变:
Day9
指针和二维数组的关系
1)&a、a、&a[0]、a[0]、&a[0][0]的值是一样的,但是表达的含义不一样
a:Int (*) [3] :他是一个指向一维数组的指针 a[0]:指向int类型元素的指针
(2)为什么说a不是int**类型?
如果a是int**类型,那么他指向的数据类型应该是int * ,那么a+1,应该移动移动4字节,但是a+1,移动了12字节,移动了一个数组,因此a一定不是int**类型
(3)a指向a[0]、a[0]指向a[0][0]
数组指针
概念
指向数组的指针
定义
存储类型 数据类型 (* 变量名) [元素的个数];
存储类型:auto、static、extern、register
数组类型:指针指向的数组中的元素数据类型
P:数组指针的数据类型: int (*)[3];
p指向的数据类型:int [3] //去掉变量名和一个*
p+1:移动sizeof(指向的数据类型) sizeof(int [3])
数组指针和一维数组
数组指针和二维数组
指针数组
概念
元素为指针的数组
定义
存储类型 数据类型 * 变量名[元素的个数];
指针数组和二维数组