在C++中将int*转换为char*

3
  • 第1行打印“X”
  • 第2行打印“c”
  • 第3行打印11
  • 第4行打印5。

我理解这些内容,但是为什么

  • 第5行会打印20

难道不应该打印11而不是20吗,因为第1行和第2行分别打印'X'和'c'。

非常感谢您的帮助。

#include "iostream"
using namespace std;
int main()
{
int arr[] = {88, 20, 30, 40, 50, 99};
int *ptr1 = arr;
int *ptr2 = arr + 5;
cout<<(char*)ptr1<<endl;//line 1
cout<<(char*)ptr2<<endl;//line2
cout<<('c'-'X')<<endl;//line3
cout<<ptr2-ptr1<<endl;//line4
cout<<(char*)ptr2-(char*)ptr1<<endl;//line5

return 0;
}

1
int *ptr2 ... cout<<(char*)ptr2 是什么意思?! - reader
2
5个元素,每个4字节,5*4=20。因此它会打印20! - thang
应该可以投票支持合适的名称 :) - Markus Kull
5个回答

4
在程序编译的环境中,sizeof(int)等于4。也就是说,每个int类型的对象占用4个字节(字符)。在ptr2和ptr1之间有5个整数。指向同一数组元素的两个指针之间的差值是它们之间的元素数量,这被称为指针算术。因此,ptr2 - ptr1得到5。但是,如果你将这些指针强制转换为char *类型,那么在这些指针之间有5 * sizeof(int)个字符,即20个。

1
由于 (char*)ptr2-(char*)ptr1 表示地址之间的差异。所以在您(我猜测)的 32 位平台上,5*sizeof(int) = 20

你从哪里得到32位平台的信息的? - thang
由于int是平台相关的。 - LPs
这取决于各种因素:例如,在Unix世界中,您可以拥有不同的标准:采用64位int的ILP64,采用32位int的LP64和LLP64。最后,我的意思是,并不保证8/16/64位平台具有“sizeof(int)= 4”。顺便说一句,我不明白谁踩了我的答案.... - LPs

1
要获得您期望的输出,请使用:(char)*ptr2-(char)*ptr1

0

第一个指针ptr1指向内存中的这些字节:88,0,0,0 - 这是数组中的第一个索引。
指针ptr2指向内存中的这些字节:99,0,0,0。
因此,前两行输出了两个空终止字符串:X和c。

第三行输出字符c和X之间的差异,这是一个int值。

第四个值是两个指针之间的差异,与它们指向的位置有关(在数组中的相对位置)。这是一个int数字。

最后一个是char*类型,其中char为1个字节,比int(int为4个字节)小4倍。因此,差异为(数组位置差异)*(int大小)= 5 * 4 = 20。这个值是int类型,所以你看到数字20。

尝试将所有这些int更改为char并查看差异:

char arr[] = { 88, 20, 30, 40, 50, 99 };
char *ptr1 = arr;
char *ptr2 = arr + 5;

突然,这前两行不再是一个字符,因为(char*)字符串不再有0终止符。

X¶▲(2c╠╠╠╠╠╠╬H@▼ñ¸4
c╠╠╠╠╠╠╬H@▼ñ¸4
11
5
5

这将在调试和发布之间有所不同。


0

答案是绝对正确的,让我根据代码逐步解释您的答案:

cout<<(char*)ptr1<<endl;//line1

由于ptr1 = arr,因此第一个字符是88,因此打印X

cout<<(char*)ptr2<<endl;//line2

由于ptr1 = arr + 5,因此第五个字符是99,因此打印c

cout<<('c'-'X')<<endl;//line3

由于 'c' 的值为99,'X' 的值为88,因此答案为11

cout<<ptr2-ptr1<<endl;//line4

由于arr是一个数组,第5个元素和第0个元素之间的距离为5-0 = 5

cout<<(char*)ptr2-(char*)ptr1<<endl;//line5

这里发生的情况是您正在减去两个地址,并将答案提供为两个地址的差异,例如

 (char *)ptr1 --- Address = 10
 (char *)ptr2 --- Address = 30

如果我们将两者相减,则30-10=20。为什么是20,因为它取决于void *的大小。

32 bit sizeof void* = 4
64 bit sizeof void* = 8

因此,在32位系统上,答案将是4*5=20,在64位系统上,答案将是8*5=40。

不,如果在64位系统上,int的大小为4,那么结果仍然是20。 - alk
@alk 内存或强制转换是通过 Void 指针而不是 Int 进行的。Int 的大小可能为 4 字节,但由于通过 void 指针进行强制转换,分配的地址间隔为 8 字节。即使 int 的大小为 4,左侧字节也会填充。 - Vineet1982
这是基本的指针算术(与平台无关):指针之间的字节差为<指针所指元素计数的距离> * sizeof(<指针所指类型>),无论指针/地址的大小如何。对于16位、32位、64位等都是相同的。 - alk
在64位系统上检查sizeof(char *)的大小;指针的大小取决于处理器的位数。 - Vineet1982
让我们在聊天室中继续这个讨论 - Vineet1982
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接