你说过:
C++ 在表达式中将 char 隐式类型转换为 int(比 char 更大的数据类型),这意味着以下运行不会出现编译时错误:
char a = 'a';
int b = a;
cout << b << endl;
输出:
97
然后你问:
为什么下面会抛出编译时错误:
char a = 'a';
char* str = &a;
int* ptr;
ptr = str;
在您的第一个示例中,您声明了一个名为 a 的 char 变量,并为其分配了字符 'a'。然后声明一个名为b 的int 变量并将其赋值为a。然后你打电话给coutb。这给出了预期的值97。
这里发生的是编译器会将 char a 的值隐式转换为整数。您看到值97 的原因是因为这是为小写a 分配的ASCII 代码。这里的可变大小无关紧要。
在您开始询问编译器错误的第二个示例中,如下所示:
您声明与上面相同的char 变量,并为其分配相同的字符值a。
这一次您创建一个pointer 到一个char 并将其命名为str 并将其分配给a 的地址。 str 现在指向 a。接下来,您为名为@987654347@ 的int 创建了一个pointer,然后您尝试将str 分配给ptr。是的,所有指针在内存中的大小都相同,但是您在这里无法理解的是指针寻址的工作原理。由于您没有分别使用new 和delete,因此这些指针位于堆栈上。所以在我的机器上我运行了这段代码:
#include <iostream>
int main() {
char a = 'a';
char* str = &a;
std::cout << &str << '\n'; // print str's address
int* ptr; // don't assign ptr to anything...
std::cout << &ptr << '\n'; // print ptr's address
}
在我的机器上输出是:
003BFC34 // this is the stack address of str
003BFC28 // this is the stack address of ptr
是的,两个指针本身通常在 32 位机器上占用 4 个字节的内存。但是,str 指向 1 字节的 char 类型,ptr 指向 32 位机器上的 4 字节 int 类型。
因此,当您尝试将一个指针分配给另一个时;这仅在指针类型为相同类型时才有效!否则,您将遇到编译器错误或UB。
您在第一种情况下的假设是char 变成了int,但事实并非如此。在第一种情况下发生的情况是,它采用1 byte 表示的值,并将其隐式转换为采用4 bytes 的整数类型,而小写a 的整数表示是ASCII 的值@ 987654363@.
因此您的第二种情况将无法编译:
int main() {
char a = 'a';
char* str = &a;
int* ptr = str; // fails to compile.
return 0;
}
但是,有一种方法可以将指针从一种类型转换为另一种类型
int main() {
char a = 'a';
char* str = &a;
int* ptr = (int*)(str); // C Style Cast - Will Compile!
int* ptr = reinterpret_cast<int*>( str ); // This will compile!
return 0;
}