数组索引和指针运算#

数组索引和指针运算都会根据元素的类型宽度进行调整。数组索引语法在 C 编译器内部也会自动转换成指针运算。

数组索引#

数组索引会根据数据大小自动调整位置,地址值实际增加 index * sizeof(<typename>)

int arr[] = {101, 102, 103};
printf("\d", arr[1]);        // 102
printf("\d", arr[2]);        // 103
           arr[0] arr[1] arr[2]
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│     │     │ 101 │ 102 │ 103 │     │     │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘
low     0xe364 0xe368 0xe36c             high

指针运算#

指针的加减运算并不是以字节为单位,而是以数据类型的宽度,地址值实际增加 n * sizeof(<typename>)

int arr[] = {101, 102, 103};
int* p = arr;            
int* p1 = p + 1;         
int* p2 = p + 2;         

int offset = p2 - p;     // 2
     *p    *p1   *p2    p         p1         p2
┌─────┬─────┬─────┬─────┬─────────┬──────────┬──────────┐
│     │ 101 │ 102 │ 103 │  0xe364 │  0xe368  │  0xe36c  │
└─────┴─────┴─────┴─────┴─────────┴──────────┴──────────┘
low 0xe364 0xe368 0xe36c                              high

为什么指针能够判断数据类型宽度?

虽然在语法上,我们没有明确指定指针加减的类型宽度,但是这一切都是由 C 编译器内部确定的。

在编译时,C 会先计算不同数据类型的宽度,然后再对指针进行合适的偏移操作,例如:

arr + i * sizeof(long)

编译器行为#

数组索引语法在 C 编译器内部会自动转换成指针运算:

char* str = "apple";

char thirdLetter = str[2];  
// the same
char thirdLetter = *(str + 2);