一.数组误区:1.不管是什么数组,只有指定初始值的时候才可以用{}进行赋值,后续的输入输出数组,均需要通过循环来进行,2.不可直接通过键盘输入{}赋值数组(初始值除外),不可直接打印数组,直接进行都会报错3.当直接int max;时,后续若是引用该变量且未初始化,则该变量可以等于任意数,而不是固定等于0,这种时候就会随便指定数,导致计算错误4.当遍历数组时,尽量让循环中的数组赋完值后,在进行操作,不然该值可能会由系统自动生成一个数值来替代该元素1.数组:数组是一组相同数据类型的元素集合,这些元素在内存中是连续存储的, 通过唯一的数组名称和索引访问.数组可以用来存储大量相同类型的数据,避免了定义多个变量的麻烦2.一维数组:语法:数据类型 数组名[元素个数]int a[5]3.声明时显示初始化int arr[5]{1,2,3,4,5};int arr[5]{1,2}(部分初始化,未显示默认为0)int arr[]{1,2,3,4,5}(不指定数组大小,编译器自动推断)int arr[5];for(int i0;i5;i){arr[i]i1;}(for循环自增)static int arr[5](静态初始化,未显示初始化的元素会自动初始化)int arr[5]{0};4.访问元素,下标5.数组遍历for(int i0;i5;i)printf(%d,num[i])数组大小长度例子:int arr[5]sizeof(arr)/sizeof(int) 5(多少个元素)长度(多少字节)sizeof(arr) 20 其中一个元素sizeof(arr[1])46.好处:1.节省代码空间,避免重复定义2.方便批量操作3.数据的集中存储与管理4.提高代码可读性5.与算法数据结构结合6.高效随机访问(不管访问数组中的哪个数据,时间都是一样的)7.减少内存管理复杂性注:先进后出的数组叫做栈7.数据的指针number[0]地址:number[0]number[1]地址:number[1]1(数组中所存的变量是连续的)数组名可以直接当做指针使用,通过指针访问元素数组名是数组第一个元素所在的地址*(number1) number[1];(等价)8.常见操作:1.查找数据中的最大值和最小值遍历数组,找到最大值或最小值int max num[0];for(int i1;i5;i){if (num(i)max){max num(i);}printf(MAX:%d/n,max);数组元素求和int sum 0;for(int i0;i5;i){sum num[i];}printf(Sum:%d/n,sum);数组越界数组与函数数组作为函数参数时,传递的是数组的首地址,即指针void hanshu(int arr[],int size) //int arr[]-数组的名称 int size-数组的元素数量{for (int i0 ;isize;i){printf(%d,arr[i]);}printf(\n);}int main(){int number[5]{1,2,3,4,5};hanshu(number,5);return 0;}二.字符数组字符数据是存储字符的,char类型字符,本质上是字符的集合声明:char name[5]{H,E,L,L,O};不会自动加上结束符如果char name[]HELLO自动在末尾添加字符串结束符\0数组大小可以不显示指定,编译器自动推导注:char gee[5] hello;char str[20]str HELLO(不正确)HELLO是一个字面常量,如果等于成立的话,实际就是等于HELLO的地址这里的str本身就是一个数组的地址,就不能在等于字符串的地址了char str[20] HELLO;(正确)char b[20]{H,E,L,L,O};(正确)H:字符,char类型H:字符串字面量,指向常量的指针(const char*类型),实际上是一个字符数组,包含H,\0char b[20]{H,E,L,L,O};(不正确)函数:1.strcpy(复制字符串)char str[20]char *p Hello Worldstrcpy(str,p);printf(%s\n,str);//将*p复制给str,从一个字符串开始找\0,这个之前的进行复制注:这里必须要满足char *p的长度小于char str[20],不然就会溢出,溢出后会改变其他所存储的数据2.sprintfchar str[20];int i 10;char *pHello World;sprintf(str,%d,i);//将i转化成字符串的形式赋值给str,不在是数值类型了,此时的10占了三个位置,1,0,\0printf(%s\n,str);//打印出来是103.memcpy复制这段地址下的多少个字节,给这个目标地址int main(){char str[20];char i a;memcpy(str,i,1);//这里的1代表1个字节,将一个字节的i复制给str[20]printf(%c\n,i);return 0;}memcpy(str,HELLO,6)如果是这样的话,就要填6个字节,因为要加个结束符\0如果只传5个,可能会乱码,直到遇见\0字符数组常见的操作(用键盘赋值)1.scanf和printf#define max_num 50int main(){char name[50];scanf(%s\n,name);//遇到空格或者回车就停止读取了fgets(name,max_num,stdin);//可以识别空格printf(%s\n,name);}注:1.在char类型中,%c是单个字符%s是从开始连续打印,直到遇到\02.stdin是键盘输入;stdout是屏幕输出;stderr错误信息输出3.scanf(%[^\n],name)可以读取空格,但是遇到回车,依旧停止读取,^\n仅使用于字符串2.strlen字符串长度3.strcat拼接字符串int a[10]HELLO;int b[10]WORLDstrcat(a,b);//拼接的数据一般放在第一个数组中printf(%s/n,a);输出HELLOWORLD4.strcmp 只能标胶字符串int a[];int b[];strcmp[a,b]返回值:ab:负数ab:正数ab;f返回值0;两个字符串从左向右逐个字符相比,按ASCII值大小比较,直到出现不同的字符或者\0为止ABcomputer cpmpare 从u和a开始比较,前面一样不比较问题1.大小限制,2.数组越界3.空格处理二维数组相同类型的多行多列的集合,类似表格语法:type array_name[rows][cols];int a[3][4] 定义一个3行4列的二维数组内存布局:二维数组在内存中是线性存储的(其实就是一维方式),存储顺序按照行优先声明 int arr[3][4]初始化:显示:int arr[2][3]{{1,2,3},{4,5,6}}有多少行,就有多少小括号,小括号里面是列隐示:int arr[2][3]{{2,3},{6}}其余没有表示的用0代替隐示大小推断: int arr[][3]{{1,2,3},{4,5,6}}//必须指定列数,行数可根据初始值内容自动推断嵌套循环遍历二维数组:int arr[2][3]{{1,2,3},{4,5,6}};for (int i0,i2,i){for(int j0,j3,j){printf(%d,arr[i][j])}printf(\n);}逐个赋值(同理)拷贝操作:int arr2[3][4];memcpy(arr2,arr1,sizeof(arr1));将arr1拷贝给arr2,arr1不能超过48字节空间二维数组与指针arr[0][0]arr[0]arr 都是二维数组的首地址arr是指向arr[0]的指针,arr[0]又是指向第一行的指针通过指针访问二维数组元素:可以通过偏移指针来访问二维数组中的元素int *ptrarr[0][0]printf(%d\n,*(ptr1))打印arr[0][1];用指针打印数组int arr[2][3]{{1},{4}};int *parr[0] 声明要加*,用的时候直接用地址for (i 0,i6,i){printf(%d\n,*(pi))}指针:arr[10];arr是一个指针常量,值为数组首字母的地址*p是对指针p的解引用,结果是p指向的元素的值例如arr[0]区别:arr是地址,类型为int**p是值,类型为intp 是一个指针变量,存储的是内存地址