数组是一组相同类型元素的集合
一维数组
一维数组的创建
一维数组的创建方式
type_t arr_name[const_n];
//type_t 指一维数组的元素类型
//const_n 是一个常量表达式,用来指定一维数组的大小
一维数组创建的实例
//代码1
int arr1[10];
char arr2[10];
float arr3[10];
double arr4[10];
//代码2
int count = 10;
int arr5[count]; //数组无法正常创建
//数组的创建,[]中要给一个常量,不能使用变量
一维数组的初始化
//在创建一维数组的同时给一维数组的内容一些合理的初始值
int arr1[10] = {1, 2, 3}
int arr2[5] = {1, 2, 3, 4, 5}
//在创建一维数组时若不想指定一维数组的大小就得到初始化,一维数组的元素个数根据初始化的内容来确定
char arr3[] = "abc"; //'\0'会自动放入
char arr4[] = {'a', 'b','c'}; //不会出现'\0'
char *p = "abcdef"; //产生的是首字符的地址
一维数组的使用
#include <stdio.h>
int main()
{
int arr[10] = { 0 }; //数组的不完全初始化
//数组是使用下标来访问的,下标从0开始
int i = 0; //做下标
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
arr[i] = i;
}
for (i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
总结
- 数组是使用下标来访问的,下标是从0开始。
- 数组的大小可以通过计算得到。
一维数组在内存中的存储
随着数组下标的增长,元素的地址也在有规律的递增。所以,数组在内存中是连续存放的。
一维数组的指针访问
#include <stdio.h>
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
printf("%p\n", arr); //输出地址
printf("%d\n", *arr); //输出 1
return 0;
}
//由此可见,数组的数组名其实是数组首元素的地址
#include <stdio.h>
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
printf("&arr[%d] = %p\n", i, &arr[i]); //获取数组每个元素的地址
printf("%p\n", arr+i);
}
return 0;
}
//通过对数组名+整数的计算,其实我们可以获取到数组每个元素的地址
//使用指针访问数组
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
int i = 0;
int *p_arr = arr;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
*(p_arr + i) = i;
}
for (i = 0; i < sz; i++)
{
printf("%d\n", *(p_arr + i));
}
return 0;
}
二维数组
二维数组的创建
int arr[3][4];
char arr[3][4];
double arr[3][4];
二维数组的初始化
int arr[3][4] = {1, 2, 3, 4};
int arr[3][4] = {{1, 2}, {3, 4}};
double arr[][4] = {{1, 2}, {3, 4}}; //可以不输入行号
二维数组的使用
#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++)
{
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]);
}
}
return 0;
}
二维数组在内存中的存储
二维数组在内存中也是连续存储的
二维数组的指针访问
#include <stdio.h>
#include <windows.h>
int main()
{
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]);
}
}
system("pause");
return 0;
}
有关数组的计算
一维数组
int arr[] = { 1, 2, 3, 4 };
printf("%d\n", sizeof(arr)); //16 整个数组的长度
printf("%d\n", sizeof(arr + 0)); //4 首元素的地址的长度
printf("%d\n", sizeof(*arr)); //4 首元素的长度
printf("%d\n", sizeof(arr + 1)); //4 第二个元素的地址的长度
printf("%d\n", sizeof(arr[1])); //4 第二个元素的长度
printf("%d\n", sizeof(&arr)); //4 数组的地址的长度
printf("%d\n", sizeof(*&arr)); //16 整个数组的长度
printf("%d\n", sizeof(&arr + 1)); //4 跳过整个数组后的第一个地址的长度
printf("%d\n", sizeof(&arr[0])); //4 首元素地址的长度
printf("%d\n", sizeof(&arr[0] + 1)); //4 第二个元素的地址的长度
字符数组
char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' }; //字符数组一个元素只有一个字节
printf("%d\n", sizeof(arr)); //6 整个数组的长度
printf("%d\n", sizeof(arr + 0)); //4 首元素的地址的长度
printf("%d\n", sizeof(*arr)); //1 首元素的长度
printf("%d\n", sizeof(arr[1])); //1 第二个元素的长度
printf("%d\n", sizeof(&arr)); //4
printf("%d\n", sizeof(&arr + 1)); //4 跳过整个数组后的第一个地址的长度
printf("%d\n", sizeof(&arr[0] + 1)); //4 第二个元素的地址的长度
printf("%d\n", strlen(arr)); //随机值
printf("%d\n", strlen(arr + 0)); //随机值
printf("%d\n", strlen(*arr)); //报错
printf("%d\n", strlen(arr[1])); //报错
printf("%d\n", strlen(&arr)); //随机值
printf("%d\n", strlen(&arr + 1)); //随机值
printf("%d\n", strlen(&arr[0] + 1)); //随机值
char arr[] = "abcdef";
printf("%d\n", sizeof(arr)); //7 整个数组的长度
printf("%d\n", sizeof(arr + 0)); //4 首元素的地址的长度
printf("%d\n", sizeof(*arr)); //1 首元素的长度
printf("%d\n", sizeof(arr[1])); //1 第二个元素的长度
printf("%d\n", sizeof(&arr)); //4
printf("%d\n", sizeof(&arr + 1)); //4 跳过整个数组后的第一个地址的长度
printf("%d\n", sizeof(&arr[0] + 1)); //4 第二个元素的地址的长度
printf("%d\n", strlen(arr)); //6
printf("%d\n", strlen(arr + 0)); //6
printf("%d\n", strlen(*arr)); //报错
printf("%d\n", strlen(arr[1])); //报错
printf("%d\n", strlen(&arr)); //6
printf("%d\n", strlen(&arr + 1)); //报错
printf("%d\n", strlen(&arr[0] + 1)); //5
char *p = "abcdef";
printf("%d\n", sizeof(p)); //4
printf("%d\n", sizeof(p + 1)); //4
printf("%d\n", sizeof(*p)); //1
printf("%d\n", sizeof(p[0])); //1
printf("%d\n", sizeof(&p)); //4 p的地址
printf("%d\n", sizeof(&p + 1)); //4 p的下一个地址
printf("%d\n", sizeof(&p[0] + 1)); //4
printf("%d\n", strlen(p)); //6
printf("%d\n", strlen(p + 1)); //5
printf("%d\n", strlen(*p)); //报错
printf("%d\n", strlen(p[0])); //报错
printf("%d\n", strlen(&p)); //随机值
printf("%d\n", strlen(&p + 1)); //随机值
printf("%d\n", strlen(&p[0] + 1)); //5
二维数组
int arr[3][4] = { 0 };
printf("%d\n", sizeof(arr)); //48 整个数组的长度
printf("%d\n", sizeof(arr[0][0])); //4 首元素的长度
printf("%d\n", sizeof(arr[0])); //16 第一行的长度
printf("%d\n", sizeof(arr[0]+1)); //4 第一行第二个元素的长度
printf("%d\n", sizeof(arr+1)); //4
printf("%d\n", sizeof(&arr[0] + 1)); //4 第二行的地址的长度
printf("%d\n", sizeof(*arr)); //16 第一行的长度的长度
printf("%d\n", sizeof(arr[3])); //16 最后一行的长度
总结
- 数组名单独放在sizeof内部,数组名表示整个数组。
- &数组名取出的是整个数组的地址,数组名表示整个数组。
除此之外的所有数组名都表示数组首元素的地址。
数组作为函数参数
数组作为函数参数时,不会把整个数组传递过去。实际上只是把数组首元素的地址传递过去了,所以即使在函数参数部分写成数组的形式: int arr[ ] 表示的依然是一个指针:int arr。