1,一个星号操作并一定代表一次内存寻址操作。指针指向的内存大小是指针指向的整个内存块大小,而数组变量指向的内存大小是其某个成员所占内存大小,数组变量的大小才是整个数组占用内存大小。
1
2
3
4
5
6
7
| // in x64 mode
int a[][2] = { 5, 4, 3, 2, 1, 6 };
int i1 = sizeof(a); // i1 is 24
int i11 = sizeof(*a); // i11 is 8
int i2 = **(a + 1); // i2 is 3
int i3 = **a + 1; // i3 is 6
int i4 = *((int*)a + 1); // i4 is 4 |
// in x64 mode
int a[][2] = { 5, 4, 3, 2, 1, 6 };
int i1 = sizeof(a); // i1 is 24
int i11 = sizeof(*a); // i11 is 8
int i2 = **(a + 1); // i2 is 3
int i3 = **a + 1; // i3 is 6
int i4 = *((int*)a + 1); // i4 is 4
对于某类型的指针p,p+1后的地址值是增加了sizeof(*p)。
对于数组a,a+1后的地址值是增加了sizeof(*a)。
2,++操作符不参入算术式内操作符之间的优化级打架,即使++操作符在括号操作符内,是不是很反直觉?
1
2
3
4
| int a[] = { 1, 2, 3, 4, 5 };
int *p = a;
int j = *p++; // j is 1
int k = *(p++); // k is 2 |
int a[] = { 1, 2, 3, 4, 5 };
int *p = a;
int j = *p++; // j is 1
int k = *(p++); // k is 2
3,关于字节对齐
1
2
3
4
5
6
| struct Diamond {
int a1;
char a2;
int64_t a3;
char a4;
}; |
struct Diamond {
int a1;
char a2;
int64_t a3;
char a4;
};
vc2019 x64和x86下都输出
1
2
3
4
5
6
7
| 1>class Diamond size(24):
1> 0 | a1
1> 4 | a2
1> | <alignment member> (size=3)
1> 8 | a3
1>16 | a4
1> | <alignment member> (size=7) |
1>class Diamond size(24):
1> 0 | a1
1> 4 | a2
1> | <alignment member> (size=3)
1> 8 | a3
1>16 | a4
1> | <alignment member> (size=7)
1
2
3
4
5
| struct Diamond {
char a1;
short a2;
char a3;
}; |
struct Diamond {
char a1;
short a2;
char a3;
};
vc2019 x64和x86下都输出
1
2
3
4
5
6
| 1>class Diamond size(6):
1> 0 | a1
1> | <alignment member> (size=1)
1> 2 | a2
1> 4 | a3
1> | <alignment member> (size=1) |
1>class Diamond size(6):
1> 0 | a1
1> | <alignment member> (size=1)
1> 2 | a2
1> 4 | a3
1> | <alignment member> (size=1)