此行存储什么值 char c = str[sizeof(int*)] ;?

What value does this line store char c = str[sizeof(int*)] ;?

char str[] = "Stanford University";
char a = str[1];
char b = *(char *)((int *)str + 3);
char c = str[sizeof(int *)];
 

abc 的字符值是多少?

a = 't' 

b 的值是 'v'c' ' (space)。但是c怎么会是space呢? int * 的大小是 4 个字节或 8 个字节。在这两种情况下我们会有不同的价值观。此外,在 b 中它指向 s[12] 但整行是如何执行的,我的意思是首先它由 int * 类型转换,然后由 char * 类型转换,然后我们取消引用或者我们在做其他事情?

第一个值始终是 't',因为它是存储在 str.

中的 C 字符串中的第二个字符

第二个值取决于 int 在目标平台上的大小。提示:大多数现代平台使用 32 位 int 和 8 位 char.

第三个值取决于指向 int 的指针的大小。提示:指针的大小可以不同于 int,在现代平台上它们通常有 64 位。

您在平台上观察到的值与大小为 4 字节(32 位)的 int 和大小为 8 字节(64 位)的 int * 一致。当前的64位系统就是这种情况。

第二个表达式的解释如下:

为了计算 *(char *)((int *)str + 3),编译器首先将 str 转换为指向 int 的指针,这可能是未对齐的 (*),然后计算 (int *)str 指向的数组中第四个 int 的地址,因此从该数组的开头算起 12 个字节,然后将此地址转换回 char *,保持不变地址。最后,* 读取后者指向的字符,因此 str[3 * 4] 即。字母 'v'.

第三个表达式的行为更容易解释:

char c = str[sizeof(int *)]; 只是读取偏移量 sizeof(int *) 处的字符,即 8 或您的系统,因此 c 包含 ' ',space 在 StanfordUniversity 之间。

请记住,第二个和第三个表达式都是实现定义的:

  • 在使用小型模型的旧 MS/DOS 系统上,您将有 b = 'r'c = 'a',而在使用中型和大型模型时,您将有 b = 'r'c = 'f' ;
  • 在旧的 32 位 Windows、Mac 和 linux 系统上,您将有 b = 'v'c = 'f'
  • 在某些具有 64 位 int 的奇特 Cray 系统上,计算 b 会出现未定义的行为;
  • 在某些嵌入式 DSP 处理器上,您甚至可以有 b = 'n'c = 't'

(*) 未对齐的指针将不会作为 int * 取消引用,但即使只是计算无效地址也会有未定义的行为,所以有些东西怪异的系统可能会发生奇怪的事情。如果您的目标是个人计算机 运行 Windows、macOS 或 linux,这种有风险的地址计算应该不会造成问题。