为什么打印字符串数组输出十六进制?

waz*_*eer 7 c++ string c++11

为什么以下程序将"0x2ffee4"打印到控制台?

#include <string>
#include <iostream>

using namespace std;

int main() {
    string city1[] = "toronto";
    cout << city1;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

T.C*_*.C. 18

第一行不应该编译,但是有一个GCC错误使它编译和行为等同于类似的东西

std::string city1[] = {"toronto", "toronto", "toronto", "toronto",
                       "toronto", "toronto", "toronto", "toronto"};
Run Code Online (Sandbox Code Playgroud)

(8,因为"toronto"是8个字符,包括终止空.是的,这意味着如果你使用"Chargoggagoggmanchauggagoggchaubunagungamaugg"它,它将创建一个包含46个字符串的数组,每个字符串存储"Chargoggagoggmanchauggagoggchaubunagungamaugg".)

不用说,你不应该依赖编译器错误.

根据海湾合作委员会的马车行为,city1将是一系列std::string的; 没有操作员<<超载支持打印这样的东西.相反,在std::cout << city1数组中,数组衰减到指向其第一个元素的指针,而是打印存储在指针中的地址.

你可能想写std::string city1 = "toronto";.一个字符串,而不是它的数组.


Fra*_*ler 2

TC 给出的答案是正确的,我还想提一下,如果您希望使用 cout 将“toronto”打印到控制台,那么您需要这样做:

include <string>
include <iostream>

int main() {
    using namespace std;

    // string city1[] = "toronto"; // Compiler Error - Do Next Line Instead
    string city1[] = { "toronto" };
    cout << city1[0];

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

任何时候你想在声明期间初始化任何类型的数组,你都需要使用 = { }; 设置每个数组的元素以逗号分隔。看一下这个代码示例:

#include <string>
#include <iostream>

int main() {
    using namespace std;

    string cities[] = { "New York", "Philadelphia", "Chicago", "Boston" };

    // Same As Above Except Size Of Array Is Defined First Then The Elements
    string cities[4];
    cities[0] = "New York";
    cities[1] = "Philadelphia";
    cities[2] = "Chicago";
    cities[3] = "Boston";

    unsigned index = 0;
    for ( ; index < 4; index++ ) {
        cout << cities[index] << endl;
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果在声明数组时没有初始化数组,则必须指定数组的大小。

int main() {
    int iArray[]; // Compiler Error
    int iArray[] = { 4, 3, 2, 1, 6 }; // Okay and is the same as

    int iArray[5];  // Okay
    iArray[0] = 4;
    iArray[1] = 3;
    iArray[2] = 2;
    iArray[3] = 1;
    iArray[4] = 6;

    return 0;
Run Code Online (Sandbox Code Playgroud)

}

如果您没有使用带有索引值的括号运算符来发送到控制台输出流 std::cout ,那么您获得的十六进制值是正确的,正如 TC 已经声明的那样;它返回第一个索引的地址。这就是为什么在 c / c++ 中数组和指针是相似的(它们不一样,但行为几乎相似)。与数组的主要区别在于它们的大小是恒定的,大小必须在编译时已知,并且不能动态更改大小,而无需在创建具有更大大小的新数组时将内容存储到临时变量中然后将所有数据复制到新数组中,然后清理旧数组。对于指针,它们不会以这种方式运行,可以使用 new 在堆上动态分配指针,但当该变量不再使用时也必须删除以防止内存泄漏,如果指针事先被删除并且有东西试图访问它该内存地址不再有效并且不属于调用者,这些通常被视为未处理的异常、堆损坏等,并且会使您的程序崩溃。当您尝试对超出其范围的数组进行索引时,情况也是如此。

#include <iostream>

int main() {
    // Arrays Are 0 Indexed
    int iArray[3] = { 1, 2, 3 };

    // If you try to do this to access the last element
    std::cout << iArray[3] << std::endl; // Program Will Crash

    // Since Arrays Are 0 Indexed And The Size Of The Array Is 3
    // The 3rd Value Is Indexed At 2, And By Trying To Index Location Of Array
    // At 3, This Memory Doesn't Belong To You, And It Is Undefined Behavior.
    // This Memory Could Contain Nothing, Random Data, Or Even Data That Belongs To 
    // Something Else Which If Changed Can Even Cause System Failure          

    return 0;
} 
Run Code Online (Sandbox Code Playgroud)