本帖最后由 john_lee 于 2020-8-16 11:18 编辑
C的变量,不论是“标量类型(scalar type)”还是“聚合类型(aggregate type)”,对其取地址得到的指针,都是该变量本身类型的指针,那么对该指针做算数加减运算,单位就是sizeof(变量类型)。
例如:// 1 ------
char a; // char变量,标量类型
char* p = &a + 2; // 指针类型为char,值为a的地址+偏移量sizeof(char) * 2
// 2 ------
struct a_t {
char x[2];
};
struct a_t a; // struct变量,聚合类型
struct a_t* p = &a + 1; // 指针类型为a_t,值为a的地址+偏移量sizeof(struct a_t) * 2
// 3 ------
char a[4]; // 数组变量,聚合类型
char (*p)[4] = &a + 2; // 指针类型为char[4],值为a的地址+偏移量sizeof(char[4]) * 2
上面所说的聚合类型不包括“未指定边界的数组(array with unspecified bounds)”,未指定边界的数组也可以取地址,由于数字大小未知,所以其指针不允许做加减运算,只能用作访问数组元素。
例如上面的例子3就是一个已指定数组边界的数组,如果紧接着写:p++; // 合法,指针值为a的地址+偏移量sizeof(char[4]) * 3
而:char a[4];
char (*p)[] = &a + 2; // 指针类型为char[],是未指定数组边界的数组指针,值为a的地址+偏移量sizeof(char[4]) * 2
(*p)[1] = 1; // 合法,访问数组元素,赋值地址为a的地址+偏移量(sizeof(char[4]) * 2) + sizeof(char),注意:访问的地址已越界
p++; // 非法
|