数组是一组相同元素的集合。
数组的创建方式:
type_t arr_name [const_n];
//type_t 是指数组的元素类型
//const_n 是一个常量表达式,用来指定数组的大小
数组创建的实例:
int arr[10];
char ch[5];
double data[20];
int n = 10;
int arr1[n];
//在C99标准之前,数组的大小必须是常量或者常量表达式
//在C99之后,数组的大小可以是变量,为了支持变长数组
//变量数组不能初始化
数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)。
//不完全初始化,剩余的元素默认初始化为0
int arr1[10] = { 1,2,3 };
int arr2[10] = { 1,2,3,4,5,6,7,8,9,0 };
int arr3[] = { 1,2,3 };
//a b c 0 0 0 0 0 0 0
char ch1[10] = { 'a','b','c' };
//a b c \0 0 0 0 0 0 0
char ch2[10] = "abc";
//a b c
char ch3[] = { 'a','b','c' };
//a b c \0
数组在创建的时候如果想不指定数组的确定的大小就初始化。数组的元素个数根据初始化的内容来确定。
[],下标引用操作符。它其实就是数组访问的操作符。编号是从零开始的,这里的编号就是下标。
int arr[10];
int sz=sizeof(arr)/sizeof(arr[0]);
//数组存放在连续的空间中
int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
for (int i = 0; i < 10; i++)
{
printf("&arr[%d]=%p\n",i, &arr[i]);
}
int arr[3][4];
char ch[3][5];
double data[2][4];
int arr9[3][4] = { 1,2,3,4,5,6 };
int arr10[3][4] = { {1,2},{4,5} };
//二维数组行可以省略,但是列不能省略,以此类推三位也是只能省略第一维,后两维不能省略
int arr11[][4] = { {2,3},{4,5} };
int arr12[][4] = { 2,3,4,5 };
int arr[3][4] = {1,2,3,4,2,3,4,5,3,4,5,6};
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
二维数组也是存放在一片连续的空间中的,arr[0][j]后紧接着存放arr[1][j]。
数组下标是有范围限制的。
数组的下标规定是从零开始的,如果数组有n个元素,最后一个元素的下标就是n-1。所以数组的下标如果小于0或大于n-1,就是数组越界访问了,超出了数组合法空间的访问。
C语言本身不做数组下标的越界检查,编译器也不一定会报错,但是编译器不报错并不意味着程序就是正确的。
通过冒泡排序函数将一个整型数组排序。
//数组名本质上是:数组首元素的地址
//地址是应该使用指针来接收,所以arr这里看似是数组,本质是指针变量。
void bubble_sort(int arr[])
{
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < sz-1; i++) //趟数
{
for (int 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;
}
}
}
}
正确应该是
void bubble_sort(int arr[], int sz)
{
for (int i = 0; i < sz-1; i++) //趟数
{
for (int 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;
}
}
}
}
int main()
{
int arrB[10] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arrB) / sizeof(arrB[0]);
bubble_sort(arr,sz);
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
数组名确实能表示首元素的地址,但是有两个例外:
int arrC[10] = { 1,2,3,4,5 };
int arrC[10] = { 1,2,3,4,5 };
printf("%p\n", arrC); //arr就是首元素地址
printf("%p\n", arrC+1); //sizeof加一是加上一个元素的字节数
printf("--------------------");
printf("%p\n", &arrC[0]); //首元素地址
printf("%p\n", &arrC[0]+1);
printf("--------------------");
printf("%d\n", &arrC); //数组地址
printf("%d\n", &arrC+1); //这里是加上一个数组的字节数
printf("--------------------");
二维数组的数组名的理解:
int arr[3][4]={0};
printf("%p\n",arr); //是首元素arr[0][i]的地址,当sizeof加一的时候为arr[1][0]的地址
此时sizeof(arr)是二维数组大小,sizeof(arr[0])是数组[0][0]到[0][3]的大小,sizeof(arr[0][0])是第一个元素的大小。