本篇文章是关于数组的描述
重点内容:
- 一维数组的创建和初始化。
- 一维数组的使用。
- 一维数组在内存中的存储。
- 一维数组的指针访问。
- 二维数组的创建和初始化。
- 二维数组的使用。
- 二维数组在内存中的存储。
- 二维数组的指针访问。
一维数组的创建和初始化
数组的创建
对数组的描述:数组是一组相同类型元素的集合
数组的创建方式:
type_t arr_name [const_n];//也就是 类型 数组名 [常数];
数组创建实例:
//例1
int arr1[10];
//例2
char arr2[10];
float arr3[10];
double arr4[10];
注意:数组创建 [ ] 中要给一个常量才可以,不能使用变量,不能为空,不能为0。
例如:
int count = 10;
int arr2[count];//不能正常创建
数组的初始化
数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化)。
int arr1[10] = {1,2,3};//不完全初始化默认没有初始化处为0
int arr2[ ] = {1,2,3,4};
int arr3[5] = {1,2,3,4,5};
char arr4[3] = {‘a’,98,’c’};
char arr5[ ] = {‘a’ , ‘b’ , ‘c’};
char arr6[ ] = “abcdef”;
….
数组在创建的时候如果想不指定数组的确定大小([ ] 为空)就得初始化。数组元素的个数根据初始化的内容确定。
对于下面的代码要区分,内存中如何分配
char arr1[ ] = “abc”;//内存中 ‘a’ ‘b’ ‘c’ ‘\0’
char arr2[3] = {‘a’ , ‘b’ , ‘c’};//内存中 ‘a’ ‘b’ ‘c’
char *p = “abcdef”;
当初始化为char arr[ ] = {‘a’,’b’,’c’};内存中不自动分配’\0’所以输出会是乱码(%s输出需要’\0’才会停止)
这里有一些实例
char *p1 = "abcdef";//常量字符串,不能改,所以内存只存储一份,p1==p2
char *p2 = "abcdef";
if (p1 == p2)
printf("hahaha\n");
char arr1[] = "abcdef";//存在两个数组,这两个数组可以更改,所以存储两份,arr1!=arr2
char arr2[] = "abcdef";
if (arr1==arr2)
printf("hahaha\n");
一维数组的使用
操作符[ ],下标引用操作符就是数组访问的操作符。
int arr[10] = { 0 };
int i = 0;
for (i = 0; i < 10; i++)
{
arr[i] = i;
}
for (i = 0; i < 10; i++)
{
printf("%d", arr[i]);
}
注意:这里的循环中,数组内存大小不要越界
总结:
- 数组是使用下标来访问的,下标是从0开始。
- 数组的大小可以通过计算得到。
int arr[10];
int sz = sizeof(arr) / sizeof(arr[0]);
一维数组在内存中的存储
int arr[10] = { 0 };
int i = 0;
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
{
printf("&arr[%d] = %p\n", i, &arr[i]);
}
运行结果:
我们可以得出,随着数组下标的增长,元素的地址也在有规律的递增。
因此,可以得出结论:数组在内存中是连续存放的。
一维数组的指针访问
int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
printf("%p\n", arr);//数组地址
printf("%d\n", *arr);//对数组地址解引用
运行结果:
由此可见,数组的数组名其实就是数组首元素的地址。
因此,我们可以通过对数组名+整数的运算,就可以获得到数组中的每个元素的地址。
int i = 0;
int arr[10] = { 0 };
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); ++i)
{
printf("$arr[%d] = %p\n", i, &arr[i]);
printf("%p\n", arr + i);
}
两个输出结果相同。
所以我们可以通过指针访问数组了:
int arr[10] = { 0 };
int i = 0;
int *p = arr;
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
*(p + i) = i;
}
for (i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", *(p + i));
}
运行结果:
结论:
*(arr+i) = arr[i];
int *p = arr;
*(p+i) = p[i];
*(i+p) = i[p];
二维数组的初始化
二维数组的创建:
//数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];
//数组初始化
int arr[3][4] = { 1,2,3,4 };
int arr[3][4] = { {1,2},{4,5} };
int arr[][4] = { {2,3},{4,5} };
二维数组的使用
二维数组的使用也是通过下标的方法
int arr[3][4] = { 0 };
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 4; j++)
{
arr[i][j] = i * 4 + j;
}
}
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 4; j++)
{
printf("%d ", arr[i][j]);
}
}
运行结果:
二维数组在内存中的存储
int arr[3][4];
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]);
}
}
运行结果:
从结果可以看出,二维数组在内存中也是连续存储的。
二维数组的指针访问
int arr[3][4] = { 0 };
int *p = &arr[0][0];
int i = 0;
for (i = 0; i < 3 * 4; i++)
{
*(p + i) = i;
}
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 4; j++)
{
printf("%d ", arr[i][j]);
}
}
运行结果:
总结:
&arr[0] &arr[0]+1 //跳过一个元素
arr arr+1 //跳过一个类型
&arr &arr+1 //跳过整个数组