char* 和 int* 数据类型有什么区别,可以在C++中创建指针数组
What is difference between char* and int* data type to create array of pointers in C++?
在为int
数据类型创建指针数组时,以下代码有效:
int var[] = {10, 100, 200, 1000};
int *ptr[] = {&var[0], &var[1], &var[2], &var[3]};
在为char
数据类型创建指针数组时,以下内容是合法的:
char *names[] = {"Mathew Emerson", "Bob Jackson"};
但是,如果我为数据类型创建一个指针数组int
如下所示:
int var[] = {10, 100, 200, 1000};
int *ptr[] = {var[0], var[1], var[2], var[3]};
我收到编译器错误。我理解为什么我在上述声明int
数据类型数组的方法中出现编译错误,因为 var[i] 不是对指针必须指向的变量的引用,即它的地址,但我不应该也通过相同的逻辑在我的 char
指针数组的声明中得到错误。
它在指针数组中可接受的原因是什么char
?
"字符串值"是指针可以指向的某物的地址,还是只是一个常量字符串值。
char *names[] = {"Mathew Emerson", "Bob Jackson"};
在C++是不合法的。 字符串文本具有const char[]
的类型,因此将其存储为char*
是非法的,因为它违反了常量正确性。 一些编译器允许它仍然编译为 C 的遗留版本,因为字符串文本具有 char[]
类型,但它不是标准C++。 如果你打开编译器上的警告,你应该得到一些类似于
main.cpp: In function 'int main()':
main.cpp:5:53: warning: ISO C++ forbids converting a string constant to 'char*' [-Wpedantic]
char *names[] = {"Mathew Emerson", "Bob Jackson"};
如果你想要一个字符串数组,那么我建议你使用像这样的std::string
std::string names[] = {"Mathew Emerson", "Bob Jackson"};
原因
char *names[] = {"Mathew Emerson", "Bob Jackson"};
"works"是,由于字符串文字是数组,它们隐式衰减到指针,所以
{"Mathew Emerson", "Bob Jackson"}
成为
{ address_of_first_string_literal, address_of_second_string_literal}
然后这些用于初始化数组中的指针。
int *ptr[] = {var[0], var[1], var[2], var[3]};
无法工作,因为var[N]
是对数组中int
的引用,而不是指针。
"Mathew Emerson" 属于 const char*
型 - 它已经是一个指针,因此您可以直接将其存储在指针数组中。您需要为 int 大小写&
的原因是将int
"转换"为 int*
.
(忽略其他答案中提到的常量问题...
您编写的每个字符串文本("Mathew Emerson"
、"Bob Jackson"
、...)都需要稍后在编译的代码中放置一些存储位置。
就好像你在某处写过
一样char const[] MathewEmerson = { 'M', 'a', /*...*/, 'o', 'n', 0 };
因此,您可以将char const*数组构造为:
char const* names[] = { &MathewEmerson[0], /*...*/ };
至于数组,数组本身的地址和它的第一个元素是相同的,数组被隐式转换为指针,你可以改写
char const* names[] = { MathewEmerson, /*...*/ };
如果您使用字符串文字,所有这些都是为您隐式完成的。
同样,你可以写:
int *ptr[] = {var, &var[1], &var[2], &var[3]};
(注意:var
,第一项不&var[0]
),如果我们更进一步,甚至:
int *ptr[] = {var, var + 1, var + 2, var + 3};
结果总是相同的。可读性,一种变体与另一种变体的可理解性?好吧,另一个话题...
你的误解被包裹在你对以下代表内容的解释中: "Mathew Emerson"
这是一个字符数组,将在只读内存中实例化,作为程序引导的一部分。此字符数组称为字符串文本,特别是:
窄多字节字符串文本。不带前缀的字符串文本的类型是
const char[]
NathanOliver的回答正确地描述了您的编译器没有将警告级别调得足够高,因此它允许const char[]
衰减成char*
。这是非常糟糕的,因为:
尝试修改字符串文字会导致未定义的行为:它们可能存储在只读存储(如.rodata)中或与其他字符串文字组合[1]
但是,这样做是完全合法和合乎逻辑的: const char *names[] = {"Mathew Emerson", "Bob Jackson"}
希望这能为您澄清正在发生的事情,足以让您了解使用字符串文本就是使用指针。你的代码:int *ptr[] = {var[0], var[1], var[2], var[3]}
是非法的,因为var[0]
是int&
而不是int*
。这样做同样是非法的: char* ptr = {names[0][0], names[0][1], names[0][2], names[0][3]}
这里的问题是我使用的是char&
而不是char*
。
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 使用std::multimap迭代器创建std::list
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 使用CMake创建QML插件
- 如何在c++中为模板函数实例创建快捷方式
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 试图在visual studio上用C++创建一个桌面应用程序
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- 如何在C++20中创建模板别名的推导指南
- 如何为模板化对象创建模板向量?VS正在投掷C3203
- 如何创建一个空的全局类并在启动时实例化它
- 无法创建抽象类的实例
- 链接到自行创建的dll失败
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- 有没有一种方法可以创建一个带有哈希表的数据库,该哈希表具有恒定时间查找功能
- 如何在C++类内存结构中创建"spacer"?
- 终端不会为C++文件创建.exe文件吗
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息