@C语言基础复习
C语言基础复习
数组和指针
在C语言中,数组名就是指向数组首元素地址的指针,因此可以有两种方式
操作数组元素,你也可以通过新创建的指针指向数组首元素,可以起到与数组名相同的作用,但是二者不完全相同。当你是使用sizeof 对二者进行运算时,数组名将会输出数组 长度 * 数组元素所占字节数(例子中是5*int = 20),而新创建的指针p则会输出指针所占字节大小(即4个字节)
int arr[5] = {1, 2, 3, 4, 5};
//arr是数组名,实际上也是指向首元素的指针
//因此可以通过两种方式来操作数组
//1. 通过方括号
printf("通过[]操作数组:\n");
for(int i = 0; i < 5; i++){
printf("%d ", arr[i]);
}
//2.通过指针偏移
printf("\n通过指针操作数组:\n");
for(int j = 0; j < 5; j++){
printf("%d ", *(arr + j));
}
//同样的,用另一个指针指向数组首地址,也能达到同样效果
int* p = arr;
printf("\n通过另外一个指针操作数组:\n");
for(int j = 0; j < 5; j++){
printf("%d ", *(p + j));
}
printf("\n");
但其实这两种方式的本质是相相同的,即 arr[i] 是一种“语法糖”,其本质和
*(arr + i)是相同的,下面这个例子即可说明
void test2(){
int arr[5] = {1, 2, 3, 4, 5};
printf("这是一种奇怪的方式: %d\n", 1[arr]);
}
很神奇,但到底为什么呢。
原因是, arr[i] = *(arr + i) 所以 *(i + arr) = i[arr], 简单的加法交换律
手动滑稽233
最后在来看一道经典题目
void test3(){
int arr[5] = {1, 2, 3, 4, 5};
int* p = arr;
printf("A: %d\n", *p++);
printf("B: %d\n", (*p)++);
printf("C: %d\n", *(p++));
}
先来结果
A:p指向了arr[0]这个元素, 也就是1, 因为后置的++运是在语句运行之后才执行,而且是对p进行++,而不是p所指的元素,因此相当于先取了p指向的元素打印,然后把指针向后挪一位,这条语句执行完之后,p指向了a[1]
B:p目前在a[1] = 2的位置,先运算*p = 2,然后再++,因此相当于打印a[1]然后把a[1]处改成3
C:这里p++即使带了括号也不会先算,因此这里打印的还是a[1]位置的元素,也就是刚修改过的3。++相当于指针向后移动一位,指向a[2] = 3。此时如果再填一句printf("%d", *p); 输出结果还是3(a[2])
运行后, 数组变成了{1, 3, 3, 4, 5}