目录
一. 一维数组
1.1. 一维数组的创建和初始化
(1)数组的创建
在创建数组之前,我们应先了解数组是什么?
数组:是一组相同类型元素的集合。
数组的创建方式:
type_t arr_name [const_n];
// type_t 是数组的元素类型
// const_n 一个常量表达式,用来指定数组的大小
创建数组成功的实例:
// int 类型
int arr1[10];
int arr2[5];
// char 类型
char arr3[5];
char arr4[3];
// float/double 类型
float arr5[2];
double arr6[4];
创建数组错误的实例:
int n = 10;
int arr[n]; // 此时的 n 是个变量
注意:数组的创建,[ ] 中要给一个常量才可以,不能使用变量。
(2)数组初始化
数组的初始化:在创建数组的同时给数组的内容一些合理初始值(初始化)。
注:数组在创建的时候如果不指定数组的确定的大小就得初始化。数组的元素个数根据初始化的内容来确定。
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 1,2 };
char arr3[] = { 'a','s','b','d' };
此时编译器就会默认 arr1数组的大小是5, arr2数组的大小是2, arr3数组的大小是4。
完全初始化
数组内最多能存放几个元素就初始化几个元素。
int arr1[3] = { 1,2,3 };
int arr2[5] = { 1,2,3,4,5 };
char arr3[3] = { 'a','b','c' };
double arr4[5] = { 12.1,13.4,1.3,6.8,5.9 };
不完全初始化
初始化的元素小于数组内定义的元素大小,并且剩余的元素默认为 0。
字符数组存放字符串
char arr[] = "abcdef";
初始化后元素在数组中的位置:
' \0 ' 只是字符串的结束标志,是一个转义字符,并且在计算字符串长度时不作为字符串中内容,即此 arr 数组的大小长度为 6。
注:若省略数组大小,则数组就必须得初始化,数组的大小是根据初始化的内容来决定的。
1.2. 一维数组的使用
[ ]:下标引用操作符,其实就是数组访问的操作符。
1.数组是使用下标来访问元素的,下标从0开始。
2.数组的大小是可以通过计算得到的。
int arr[10] = { 0 };
int sz= sizeof(arr) / sizeof(arr[0]);
为什么 sz 就是数组的大小呢?不要急,后面的数组作为函数参数一节有着详细的讲解。
实战一下:
#include<stdio.h>
int main()
{
int arr[5] = { 0 }; // 数组的不完全初始化
int sz = sizeof(arr) / sizeof(arr[0]); // 用来计算数组的元素个数
// 数组是使用下标来访问元素的,下标从0开始
int i = 0; // 做下标,用于访问数组的各个元素
for (i = 0; i < sz; i++)
{
// 给数组赋值
arr[i] = i;
}
// 打印数组内容
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
1.3. 一维数组在内存中的存储
要了解数组在内存中的存储,就要了解 %p (打印数据的地址)。
#include<stdio.h>
int main()
{
int arr[10] = { 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("&arr[%d] = %p\n", i, &arr[i]);
}
return 0;
}
输出结果:
观察:地址以 4 个字节(int 类型的数组)的相差依次增大。
通过输出的结果,我们了解到:随着数组下标的增长,元素的地址也以 有规律的增长,故此,数组在内存中是连续存放的。
二. 二维数组
2.1. 二维数组的创建和初始化
(1)二维数组的创建
一维数组的性质二维数组基本上都有,二维数组的创建:
type_t arr_name [const_n1][const_n2];
type_t 数据类型
const_n1 二维数组行号,决定含有几行
const_n2 二维数组列号,决定含有几列
// 二维数组的创建
int arr[2][3]; // 此数组有 2行3列
char arr1[3][4]; // 此数组有 3行4列
float arr2[4][5];
在创建二维数组时,二维数组的行号可以省略,但列号一定不能省略。
// 正确示范
int arr[3][4];
char arr2[][3];
// 错误示范
int arr3[2][];
char arr4[][];
(2)二维数组初始化
// 数组的初始化
int arr[3][4] = { 1,2,3,4 };
int arr1[3][4] = { {1,2},{3,4} };
int arr2[][4] = { {2,3},{5,6} };
这时,arr1 和 arr2 中的一个{}标志着一个一维数组 ,即二维数组相当于多个一维数组相连接起来,第一个{}(一维数组)为此二维数组的第0行,第二个{}(一维数组)为此二维数组的第1行等。
2.2. 二维数组的使用
二维数组的使用也是通过下标的方法(通过双重循环嵌套法):
#include<stdio.h>
int main()
{
int arr[3][4] = { 0 };
int i = 0;
int j = 0;
// 给二位数组赋值
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
arr[i][j] = i + j;
}
}
// 打印二维数组
for (i = 0; i < 3; i++)
{
for (j = 0; j < 4; j++)
{
printf("%d ", arr[i][j]);
}
printf("\n");
}
return 0;
}
分析:此时的 i 决定二维数组在第几行,j 决定在第几列。
先赋值第一行,在赋值第一行这个“一维数组”。
2.3. 二维数组在内存中的存储
同样的,我们要了解二维数组在内存中的存储,就要先观察二维数组各个元素的地址
#include<stdio.h>
int main()
{
int arr[3][4] = { 0 };
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 4; j++)
{
printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);
}
}
return 0;
}
代码结果:
分析:我们可以看到二维数组也是在内存中连续存储的。
由分析我们还可以得出:二维数组其实可以看作是一维数组的数组。
三. 数组作为函数参数
3.1.数组名是什么?
#include<stdio.h>
int main()
{
int arr[5] = { 1,2,3,4 };
printf("%p\n", arr);
printf("%p\n", arr + 1);
printf("%p\n", &arr[0]);
printf("%p\n", &arr[0] + 1);
printf("%d\n", *arr);
return 0;
}

#include<stdio.h>
int main()
{
int arr[5] = { 1,2,3,4 };
printf("%p\n", arr);
printf("%p\n", arr + 1);
printf("%p\n", &arr[0]);
printf("%p\n", &arr[0] + 1);
printf("%p\n", &arr);
printf("%p\n", &arr+1);
printf("%zd\n", sizeof(arr));
printf("%zd\n", sizeof(arr[0]));
return 0;
}
运行结果:
由结果不难看出:sizeof(arr) 和 &arr 都表示了整个数组,故此:则就能用 sizeof(arr)/sizeof(arr[0]) 来求出数组元素的个数。
3.2.作为函数参数
在写代码的时候,往往不可避免的会将数组作为参数传给这个函数。比如:要实现一个专门打印数组的函数。
#include<stdio.h>
void Print(int arr[])
{
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[] = { 1,2,3,4,5,6 };
Print(arr);
return 0;
}
大家看一下:这样的代码行吗?
发现:打印结果是:1 2
why?
这是因为当数组传参的时候,实际上只是把数组的首元素的地址传递过去了,所以即使在函数参数部分写成数组的形式,int arr[]表示的依然是一个指针,int* arr,以前的文章已经说明 sizeof(指针)结果是4/8,(因为我的编译器是64位的,所以我的 sizeof(arr) 是 8,此时sz = 2,故打印 2位就不再打印了)
那该如何写呢
上述代码的主要错误就是因为 sz 的值错了,那么在传参的时候将 sz 的值传过去,行吗?
看代码:
#include<stdio.h>
void Print(int arr[],int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
int main()
{
int arr[] = { 1,2,3,4,5,6 };
int sz = sizeof(arr) / sizeof(arr[0]);
Print(arr,sz);
return 0;
}
发现是可以的。OK了
所以老铁们以后再对数组传参的时候要把数组的大小要传过去。
今天的分享就到这里了,若有大佬观察到这篇博文中的问题恳请大佬们不吝赐教。