指针与字符串


在〈字符数组与字符串〉谈过 C 风格字符串,本质上就是个字符数组,而数组名称具有指针性质,那可以如下创建字符串吗?

char *text = "hello";

以前可以,不过使用MinGW-w64,GNU 编译器版本 8.1.0 编译的话,会有以下警讯:

warning: ISO C++ forbids converting a string constant to 'char*'

text存储了字符串常量的地址值,然而字符串常量创建的内容是只读的,必须如下才不会有警讯:

const char *text = "hello";

上述方式中,text只是个类型为const char*的指针,是与以下不同的,底下创建的text内容并不是只读的,因为text是个数组,text是将"hello"复制至各索引处:

char text[] = "hello";

对于wchar_t等其他为了支持 Unicode 的类型,都有这类特性。

然而,无论是哪个形式,都可以传递地址,例如:

char text1[] = "hello";
const char *text2 = "hello";

const char *text = text1; // OK
text = text2;             // OK

不过,底下不行:

char text1[] = "hello";
const char *text2 = "hello";

char *text = text1; // OK
text = text2;       // error: invalid conversion from 'const char*' to 'char*'

错误该行如果真的想通过编译,就必须明确告诉编译器,你要去除const修饰,也就是使用const_cast

char text1[] = "hello";
const char *text2 = "hello";

char *text = text1;               // OK
text = const_cast<char*>(text2);  // OK

会需要这么做的情况,可能是在使用一些旧的函数,它们在参数上定义的是char*,而不是const char*

那么,如何创建字符串数组呢?

#include <iostream> 
#include <cstring>
using namespace std; 

int main() {
    const char *names[] = {"Justin", "Monica", "Irene"};

    for(auto name : names) {
        cout << name << endl;
    }

    return 0; 
}

留意一下底下的不同:

const char *names1[] = {"Justin", "Monica", "Irene"};
char names2[][10] = {"Justin", "Monica", "Irene"};

name1的每个元素,存储了各个字符串常量的地址值;然而,name2是有三个长度为 10 的char数组,并复制了各个字符串常量的char

在 C++ 中使用 C 风格字符串是比较麻烦的,可以的话建议使用string


展开阅读全文