目录
一、一维数组
二、二维数组
三、数组越界
四、数组名是什么?
五、冒泡排序
【前言】
数组这块没有什么特别难理解的东西,所以容易上手,在这里,我就补充一些容易出现错误的小知识点,很容易理解哦。
一、一维数组
定义:数组是一组相同类型元素的集合。
type_t arr_name[const_n];
//type_t:数组元素类型
//arr_name:数组名
//const_n:常量表达式,用来指定数组的大小
数组的创建错误示范:
int const = 10;
int arr[const];//注意哦,这样写是错误的
【敲黑板】:数组的创建,在C99标准之前,[ ]中要给一个常量才可以,不能使用变量。在C99之后支持了变长数组的概念,允许数组的大小是变量,但是对编译器有所要求,要求编译器支持C99标准。但是有很多编译器对C99的支持就不够好,所以我要说啥你肯定知道咯。
注意,对于字符数组要格外注意:
如:
char arr2[3] = {'a','b','c'};
//注意哦,末尾没有\0
sizeof(arr2) -->3
strlen(arr2) -->乱码!
【敲黑板】:注意比较strlen() 和sizeof
- strlen() 是一个库函数,计算的是字符串的长度,并且只能作用于字符串,关注点在于字符串中是否有\0 ,计算的是字符串\0 之前的字符个数;
- sizeof 是一个操作符,sizeof 是用来计算变量所占空间大小的,任何类型都可以使用,只关注空间大小,不在乎内存中是否有\0, 而且单位是字节
总结:
- 数组是使用下标来访问的,下标是从0开始的;
- 数组的大小可通过计算得到
int arr[10];
int sz = sizeof(arr) / sizeof(arr[0]);//40 / 4 == 10
【敲黑板】:
- 一维数组在内存中是连续存放的;
- 数组随着下标的增长,地址由低到高变化
二、二维数组
二维数组在数学里面叫矩阵。
注意哦,二维数组的初始化和一维数组不一样:
如:
int arr[ ][4]; //正确(行可以省略)
int arr[ ][ ]; //错误(列一定不能省略)
二维数组在内存中的存储:也是连续存放的哦!
二维数组可以理解为一维数组的数组,二维数组在内存中也是连续存放的,如果省略了列数,那么每行有几个元素也就不知道了,则第一行在哪里结束也就不知道了,所以不知道第二行应该放在第一行哪里。
三、数组越界
数组的下标是有范围限制的,规定数组的下标从0开始,如果数组有N个元素,那么最后一个元素的下标是N - 1,所以数组下标如果小于0 或者大于 N - 1,就属于越界访问了,超出了数组合法空间的访问。
C语言本身不作数组下标的越界检查,编译器也不一定报错,但是编译器不报错并不意味着程序是正确的。而且二维数组的行列也可能存在越界。
如:
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
for(int i = 0; i <= 10; i++)
{
arr[i] = 0; //当i == 10 时,就属于越界访问了!
}
四、数组名是什么?
一般情况下,数组名是首元素的地址,但是有两个特例:
- sizeof(数组名):计算的是整个数组的大小,此时的数组名表示的是整个数组;
- &数组名:取出的是整个数组的地址,此时的数组名表示的是整个数组。
除了上面两种情况,所有的数组名都表示数组首元素的地址!
五、冒泡排序
以升序为例,每一趟冒泡排序都是把一个最大的元素放
到最后面的过程。
void bubble_sort(int* arr, int sz)
{
int i = 0;
for (i = 0; i < sz - 1; i++)//冒泡排序的趟数跟元素个数有关
{
int j = 0;
for (j = 0; j < sz - i - 1; j++)//比较的对数每一趟都不同,是在变化的
{
if (arr[j] > arr[j + 1])//以升序为例
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}