在 C 和 C++ 中将 int 值转换为 char 指针差异
Posted
技术标签:
【中文标题】在 C 和 C++ 中将 int 值转换为 char 指针差异【英文标题】:Converting int value to char pointer difference in C and C++ 【发布时间】:2019-01-05 14:04:17 【问题描述】:我编写了以下代码将 int 值转换为 char 指针,这在 C 中有效。
int i = 54;
char *ii;
ii = &i;
printf("%d\n", *ii);
输出是:
54
当我用 C++ 编写相同的代码时,它不起作用。
int i = 54;
char *ii;
ii = (char *)&i;
cout<<*ii;
输出是:
6
谁能解释一下为什么会发生这种情况以及我应该如何让它在 C++ 中工作。
提前致谢。
【问题讨论】:
查看ASCII table 可能会很有帮助。 复制不是完美复制,但基本问题和解决方法是一样的:在C++中打印char
会打印char
,即编码值所代表的字符。
另请注意,您通过没有big-endian 系统躲过了一个子弹。
@ShubhamYadav - 你只是走运(或不走运,取决于观点)。在 C 和 C++ 示例中,评估 *ii
(为了打印它)会给出未定义的行为。不要求您分配的值打印。唯一的区别是必须强制 C++ 编译器允许初始化 aii
(即使用显式类型转换),但 C 编译器不允许。最终结果是无法保证您的代码以任何一种语言打印的值。
这不是那个问题的重复。第一部分的行为是这样的:reinterpret_cast<int&>(*reinterpret_cast<char*>(&i))
(这是合法的,因为char*
是对象表示,如果它显式转换则需要打印54
),第二部分只是*reinterpret_cast<char*>(&i)
(在这种情况下,第一个字节是(char) 54
,ASCII 是'6'
。在具有相反字节序的平台上,它会打印空字节'\x00'
)
【参考方案1】:
当您像这样拨打printf
时:
printf("%d\n", *ii);
%d
格式说明符意味着给定的int
参数将打印为int
。即使您传递的是char
,因为printf
是一个可变参数函数,它被提升为int
,因此它与格式说明符匹配。
当你使用cout
输出时:
cout<<*ii;
<<
运算符有一个 char
的重载。由于右侧的类型为char
,这就是使用的重载。 <<
的特定实例将参数打印为char
。由于 ASCII 码 54 对应于字符 '6'
,因此会打印出来。
如果在printf
格式中使用%c
,并且如果在cout
调用中将*ii
转换为int
,则会得到相反的结果。
【讨论】:
【参考方案2】:不同不一样。试试这个:
#include <cstdio>
#include <iostream>
int main()
int i = '6';
char *ii = reinterpret_cast<char*>(&i);
std::printf("%c\n", *ii);
std::printf("%d\n", *ii);
std::cout << *ii << '\n';
std::cout << (int)*ii << '\n';
将i
初始化为'6'
只是一个说明。
在对printf
的调用中,*ii
指向的char
值在函数调用中被提升为int
。小于int
的类型在作为接受可变参数列表的函数的可变部分的参数时会得到提升(例如printf
)。
第一个printf
语句将*ii
的值打印为字符值;你会得到“6”。第二个将其打印为整数值;你会得到代表字符 '6'
的任何值(在 ASCII 中是 54,这可能是你会看到的)。
第一次插入std::cout
插入char
值;流插入器对整数类型进行了重载,因此您将获得接受 char
类型参数的插入器,并显示该值所代表的字符,就像第一个 printf
调用一样。
第二次插入std::cout
插入*ii
的整数值,就像第二次调用printf
。
【讨论】:
以上是关于在 C 和 C++ 中将 int 值转换为 char 指针差异的主要内容,如果未能解决你的问题,请参考以下文章
在 C / C++ 中将 int* 转换为 int(*)[n]
如何在目标 C 中将 NSInteger 值转换为 int 值? [复制]