1.什么是数组?
数组是用来表示相同数据类型的一种构造/组合数据类型
它是一个长度固定的存储相同数据类型的数据结果,数组中的元素通常存储在一段连续的内存空间中。
2.如何定义数组?
数据类型 数组名[数组大小]
注意:方括号里面的整型常量表示数组里面有多少个元素,可以是整型常量或整型常量表达式,绝对不能是变量。
2.1 数组的初始化
比如int weight[5] = {1,2,3};//部分初始化,剩余两个自动补零
int weight[5] = {1,2,3,4,5}//完全初始化,也可以是int[] = {1,2,3,4,5} 注意:当初始化时只给部分元素时 数组的长度不能省略。
2.2 数组的索引
weight[0]表示数组的第零个元素。数组所引的下标是从0开始的。
在定义完数组后,可以使用数组名+方括号索引到数组里某一位置的值。只有在定义的时候方括号里的数据才表示数据大小。
3.数组数据的访问
3.1 下标越界
访问的数组索引超过了数组的内存地址,就会出现下标越界,下标越界的读取并不会出错,但他的写入/赋值操作会出现段错误(内存错误),造成程序终结。
计算数组长度可以通过sizeof(数组名)
数组在内存中是连续的。数组名可以表示数组在内存中的起始位置。
还可以通过sizeof(数组名)/sizeof(数组名[0])来得到数组中的元素个数.
4.冒泡排序
冒泡排序是一直简单的排序算法。通过比较相邻的元素,如果第一个比第二个大,就交换他们两个。然后比较第二与第三个,等等直到前面的元素小于后面的元素则第一次排序结束。针对所有元素重复以上步骤,除了最后一个。直到没有任何一对数字需要比较
例如
第一次排序5,6,1,8,2 =>5,6,1,8,2(5和6比较)=>5,1,6,8,2(6和1比较 )
代码实现:输入5个数字进行排序。len是数组长度可以更改
#include<stdio.h>
#define LEN 5
int main()
{
int num[LEN];
int i=0,temp;
//用户输入五个数字
for(i=0;i<LEN;i++)
{
scanf("%d",&num[i]);
}
//排序,共需要排n-1次
for(int j=0;j<LEN-1;j++)
{
for(i=0;i<LEN-1;i++)
{
if(num[i]>num[i+1])
{
temp = num[i];
num[i] = num[i+1];
num[i+1] = temp;
}
}
}
//输出排序结果
for(i=0;i<LEN;i++)
{
printf("%d ",num[i]);
}
}
5.二维数组
二维数组的定义:数据类型 数组名[行数][列数]
就比如学生的成绩 用二维数组来表示就很方便
int scores[3][6] = {82,110,110,45,45,90,96,145,80,60,74,70,120,80,70,76,85,81};也可以用 {} 把行的元素括起来比如:
int scores[3][6] = {{82,110,110,45,45,90},{96,145,80,60,74,70},{120,80,70,76,85,81}}
每一行都用 {} 时,可以把第一维长度省略(只能省略第一维)
int scores[][6] = {{82,110,110,45,45,90},{96,145,80,60,74,70},{120,80,70,76,85,81}}
6.字符数组和字符串数组
1.用来存放字符的数组就是字符数组,字符串其实就是字符数组(C语言中,不能定义存放字符串的变量,字符串通常用字符串数组来保存处理。而在C语言中,字符变量(char)和整型(int)变量是通用的,只是内存大小不一样罢了,因此也可以定义整型数组来存放字符型数据,但会造成内存空间浪费)
#include<stdio.h>
int main()
{
char test1[] = {'h','e','l','l','o'};//字符数组的初始化方法1
char test2[] = "hello";//字符数组的初始化方法2
printf("%c\n",test1[2]);
printf("%c\n",test2[0]);
printf("%s\n",test2);
printf("第一种%s\n",test1);
//也可以用for循环把test1中的元素全部输出
printf("第二种");
for(int i=0;i<5;i++)
{
printf("%c",test1[i]);
}
}
运行结果:
字符数组的初始化包括字符常量和字符串两种方式。
字符数组的初始化时,如果只给部分元素赋值,其余元素的值默认为 ‘\0’ ,即字符串结束的标志。
使用printf函数和格式控制 %s 输出字符数组中的字符串时,printf函数中的输出列表部分应该是数组名。如果输出列表部分写成某个元素的地址,输出将从该元素开始。
printf("第一种%s\n",&test1[2]);
2.字符串的结束符号 “\0”,每一个字符串的末尾都会自动加上“\0”(所有字符串都以"\0"结束)
char test2[] = "hel\0lo";
printf("%s\n",test2);
使用scanf函数和格式控制 %s 接收用户输入的字符串时,如果字符串中包含空格,将只接收第一个空格前面的字符。
如果想接收包含空格的字符串,可以采用格式控制符 %c进行循环接收,或者使用字符串接收函数。
7.字符串操作函数
gets: 从键盘读取一个字符串。一直读到换行才结束(空格不结束)。
puts: 打印字符串到屏幕上。并自动加上换行(\n)
strlen:计算字符串长度,不包括‘\0’
strcmp:比较两个字符串的大小。如果两个字符串完全一样那么返回0.否则,按照ASCII码进行挨个儿比较,返回大于0或小于0的数。通常我们只需要判断返回值是否为0,就直到两个字符串是否一样
strcnmp:与strcnp类似,只是比较前n个字符
strcat:字符串的拼接,把src拼接到dest中,会覆盖dest的 ‘\0',并在拼接完成后在最后加上一个“\0”.(注意dest要有足够的空间来存储src)
strcpy:把src拷贝到dest中(dest被覆盖包括"\0")
strlwr:转换大写的函数,将字符串中的小写转换为大写
浅拷贝:地址赋值,把一个字符串的地址传递给另一个字符指针
深拷贝:内容赋值,把一个字符串的内容全部拷贝到另一个字符指针指向的地址中。
8.数组的索引插入删除
8.1数组的索引
用要索引的数和数组内的元素比较,输出其下标
int search(int arr[],int length,int key)
{
for(int i=0;i<length;i++)
{
if (arr[i] == key)
return i;
}
return -1;
}
8.2 数组的插入
第一步是找出元素要插入的位置,第二步是将插入位置的元素以及后面的元素全部往后位移。
比如:
#include<stdio.h>
#define MAX_Size 6
int main()
{
int arr[MAX_Size] = {1,2,5,8,3};//初始化数组
int length = 5; //当前数组内元素数
int element = 50;//插入的数
int pos = 2;//插入的位置
//输出最开始的值
for(int i = length;i>pos;i-- )
{
arr[i] = arr[i-1];//数组后移
}
arr[pos] = element ;
length = length +1;
for(int i=0;i<MAX_Size;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
8.3数组的删除
首先找到待删除元素的位置,移除该元素,然后将后面的元素向前移
int remov(int arr[], int *length, int key) {
int index = search(arr, *length, key);
if (index == -1) {
return -1;
}
if (index < *length - 1) {
for (int i = index; i < *length - 1; i++) {
arr[i] = arr[i + 1];
}
}
(*length)--;
return index;
}