声明语法格式
c
// 1. 先声明数组长度,后赋值
int arr01[10];
// 此时,数组元素的值为随机的垃圾值
printf("%d\n", arr01[0]);
// 2. 声明的时候同时初始化
int arr02[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
printf("%d\n", arr02[1]); // 输出 2
// 3. 部分初始化,其他元素的值为默认值
int arr03[10] = {1, 2, 3};
printf("%d -- %d\n", arr03[0], arr03[9]); // 输出 1 -- 0
// 4. 省略长度,编译器会自动计算数组长度
int arr04[] = {1, 2, 3, 4};
printf("arr04 size = %llu\n", sizeof(arr04) / sizeof(arr04[0])); // 输出 arr04 size = 4
求数组长度
sizeof(arr): 整个数组占用的字节数
sizeof(arr[0]): 数组中单个元素占用的字节数
sizeof(arr) / sizeof(arr[0]): 计算出数组中元素的个数
数组作为函数的参数传递时,会退化为指针。在函数内不能使用
sizeof(arr)计算数组占用的字节数
c
int arr[] = {0, 1, 2, 3, 4, 5};
printf("数组占用的字节数: %llu\n", sizeof(arr)); // 输出数组占用的字节数 24
printf("数组单个元素占用的字节数: %llu\n", sizeof(arr[0])); // 输出数组单个元素占用的字节数 4
printf("数组元素个数:%llu\n", sizeof(arr) / sizeof(arr[0])); // 输出数组元素个数 6
数组遍历
c
int arr[] = {0, 1, 2, 3, 4, 5};
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++) {
printf("%d\t", arr[i]);
}
printf("\n");
数组名
- 数组名是指针常量(
int * const arr),无法修改(指向的值是可以修改的)
c
int arr[] = {0, 1, 2, 3, 4, 5};
// 数组名是一个常量指针,不能修改
// arr = NULL;
// 指向的值是可以修改的
printf("%d\n", *(arr+5)); // 5
*(arr+5) = 10;
printf("%d\n", *(arr+5)); // 10
-
数组名的本质
-
除了一下两种情况,一维数组的数组名是指向首个元素的指针:
sizeof计算数组占用的字节数- 对数组名进行取地址操作,取得是整个数组的首地址(对数组指针+1会跳过整个数组) 。
-
-
数组下标访问可以是负数,但是需要注意越界问题;
数组传参
!WARNING
数组名在传参时会退化为指向首元素的指针,因此数组传参时需要传递数组的长度(数组元素个数)
第一种方式,int arr[] 方式,更直观
c
int sum(int arr[], int length) {
// 这里数组名退化为指向首元素的指针,输出结果为8(64位平台)
printf("arr size = %llu \n", sizeof(arr));
int count = 0;
for (int i=0; i< length; i++) {
count += arr[i];
}
return count;
}
int main() {
int arr[] = {0, 1, 2, 3, 4};
int count = sum(arr, 5);
printf("count = %d\n", count); // 输出 count = 10
}
在for循环内可以通过指针方式访问元素:
c
// 指针方式方式元素
printf("%d\n", *(arr + i));
- 第二种方式,
int * p指针妨害
c
int sum(int *arr, int length) {
// 这里数组名退化为指向首元素的指针,输出结果为8(64位平台)
printf("arr size = %llu \n", sizeof(arr));
int count = 0;
for (int i=0; i< length; i++) {
// 数组方式访问元素
count += arr[i];
// 指针方式方式元素
printf("%d\n", *(arr + i));
}
return count;
}
int main() {
int arr[] = {0, 1, 2, 3, 4};
int count = sum(arr, 5);
printf("count = %d\n", count); // 输出 count = 10
}
一维数组指针定义
数组指针 :指向数组的指针,指针变量,存放整个数组的地址
语法:数据类型 (*p)[数组长度]
!TIP
指针数组 :
存放指针的数组,数组,每个元素是指针语法:
数据类型 *p[]
(*p)[]括号包住指针 → 数组指针(一个指针)*p[]星号和数组结合 → 指针数组(一堆指针)
c
int main() {
int arr[] = {0, 1, 2, 3, 4};
// 第一种方式,直接定义
int (*arr_p1)[5] = &arr;
printf("%p\n", arr_p1);
// 第二种方式,先定义数组的类型,然后根据数组类型定义数组指针
typedef int (ARRAY_TYPE)[5]; // 这是一个包含了5个int类型元素的数组类型
ARRAY_TYPE* arr_p2 = &arr;
printf("%p\n", arr_p2);
// 第三种类型,先定义数组指针类型,然后定义数组指针
typedef int (*ARRAY_POINTER)[5]; // 这是一个包含了5个int类型元素的数组指针类型
ARRAY_POINTER arr_p3 = &arr;
printf("%p\n", arr_p3);
}
注意:
&arr是整个数组的地址,类型为int (*)[数组长度],只能赋值给同类型数组指针;arr:首元素地址int *,不能直接赋值给int (*)[5],类型不匹配编译报错;arr_p1存储的是整个数组的首地址,arr_p1 + 1会跳过整个数组,不是跳过一个元素;