字符串类型

Type of strings

我对什么是什么感到很困惑。你能告诉我每个变量类型是什么吗?

char foo[] = "bar";
char *bar = nullptr;
char const *qux = nullptr;

另外,"bar"的类型是什么?

The type of foo is char[4], i.e. a character array containing 4 chars (including the trailing null character '[=16=]'.)

String literals can be used to initialize character arrays. If an array is initialized like char str[] = "foo";, str will contain a copy of the string "foo".

The type of bar is char *, qux is char const *, just as you declared.

"bar" is string literal with type const char[4], i.e. an array containing 4 const chars (also including the trailing null character '[=16=]'.)

The null character ('[=16=]', L'[=30=]', char16_t(), etc) is always appended to the string literal: thus, a string literal "Hello" is a const char[6] holding the characters 'H', 'e', 'l', 'l', 'o', and '[=16=]'.

Here's a helper class which could give the exact type at compile-time (the idea is borrowed from Effective.Modern.C++ written by Scott Meyers).

template <typename>
struct TD;

then use it like

TD<decltype(foo)> td1;
TD<decltype("bar")> td2;
TD<decltype(bar)> td3;
TD<decltype(qux)> td4;

例如from clang you'll get error message containing type information like:

prog.cc:12:23: error: implicit instantiation of undefined template 'TD<char [4]>'
    TD<decltype(foo)> td1;
                      ^
prog.cc:13:25: error: implicit instantiation of undefined template 'TD<char const (&)[4]>'
    TD<decltype("bar")> td2;
                        ^
prog.cc:14:23: error: implicit instantiation of undefined template 'TD<char *>'
    TD<decltype(bar)> td3;
                      ^
prog.cc:15:23: error: implicit instantiation of undefined template 'TD<const char *>'
    TD<decltype(qux)> td4;
                      ^    

BTW: Because string literals are treated as lvalues, and decltype yields type of T& for lvalues, so the above message from clang gives the type of "bar" as an lvalue-reference to array, i.e. char const (&)[4].

变量foo是一个字符数组。有点。

编译器在您计算机内存中的某处组织了一些东西,因此它包含字节 [ 0x62, 0x61, 0x72, 0x00 ] "bar[=13=]"。编译器为您添加了尾随 [=14=] (0x00),以标记字符串的结尾。假设编译器将这些字节放在内存地址 0x00001000 - 第 4096 个字节。

所以虽然我们认为foo是一个字符数组,但是变量foo其实就是那四个字节的第一个元素的地址,所以foo = 0x00001000.

变量bar是一个指针,它只是一个数字。它保存的数字是它在内存中的地址 "pointing at"。最初您将 bar 设置为 nullptr,因此(可能)bar = 0x00000000

说的还算可以:

bar = foo;

这意味着 bar 现在 指向 foo。由于我们说 foo 的字节存储在内存中的某个位置("address"),因此该数字只是复制到 bar 中。所以现在 bar = 0x00001000 也是。

变量qux是一个指向常量变量的指针。这是一个特殊的编译器说明,因此如果您尝试修改它所指向的内容,它可能会产生错误。

打码即可:

qux = foo;
qux = bar;

因为所有这些都是指向字符的指针。