const char* 与 char* (C++)

Posted

技术标签:

【中文标题】const char* 与 char* (C++)【英文标题】:const char* vs char* (C++) 【发布时间】:2011-06-01 22:39:36 【问题描述】:

对于以下程序:

int DivZero(int, int, int);

int main()

    try 
        cout << DivZero(1,0,2) << endl;
    
    catch(char* e)
    
        cout << "Exception is thrown!" << endl;
        cout << e << endl;
        return 1;
    
    return 0;


int DivZero(int a, int b, int c)

    if( a <= 0 || b <= 0 || c <= 0)
        throw "All parameters must be greater than 0.";
    return b/c + a;

使用 char* e 会给出

在抛出一个之后调用终止 'char const*' 的实例

根据C++ Exception Handling,解决方法是改用const char*

来自function (const char *) vs. function (char *)的进一步阅读说

“字符串”的类型是char*', not const char*'

(我认为这是一个 C 讨论...)

Stack Overflow char* vs const char* as a parameter 上的附加阅读告诉我区别。但他们都没有解决我的问题:

    char*string* 似乎都对字符数有限制。我说的对吗? 将关键字 const 添加到 char* 如何消除该限制?我认为 const 的唯一目的是设置一个表示“不可修改”的标志。我理解 const char* e 的意思是“指向不可修改的 char 类型的指针”。

解决该错误的方法是使用 const char* e

即使是 const string* e 也不起作用。 (只是为了测试......)

谁能解释一下?谢谢!

顺便说一句,我在 Ubuntu 上,由 GCC 编译,在 Eclipse 上。

【问题讨论】:

【参考方案1】:

您链接到的关于“字符串”的电子邮件是错误的(并且令人困惑)。

基本上:

char* 是一个指向无限字符数组的指针。传统上我们认为这样的数组是一个 C 字符串,如果它包含一组有效字符,后跟一个\0。数组的大小没有限制。

const char* 是一个指向不可变字符的无限数组的指针。

string* 是指向std::string 对象的指针,完全不同。这是一个封装字符串的智能对象。使用std::string 代替 C 字符串可以让你的生活更轻松,即使它们有一些粗糙的边缘和很多讨厌的陷阱;它们非常值得研究,但与问题无关。

"String" 是一个特殊的表达式,它返回一个指向特定 C 字符串的 const char*(注意:这实际上不是真的,但它是一种简化,可以让我简洁地回答这个问题)。

char* 可以自动转换为const char*,反之则不行。请注意,旧的 C++ 编译器对类型规则有一个特殊例外,允许您这样做:

char* s = "String";

...不产生类型错误;这是为了 C 兼容性。现代 C++ 编译器不会让你这样做(比如最近的 gccs)。他们需要这个:

const char* s = "String";

所以。这里的问题是你有:

throw "All parameters must be greater than 0.";

...但是你试图抓住它:

catch(char* e)

这不起作用,因为 throw 是在抛出一个 const char*,它不能被强制转换为 catch 中指定的类型,所以它不会被捕获。

这就是为什么将 catch 更改为:

catch (const char* e)

...让它工作。

【讨论】:

+1,但我所知道的每个编译器(包括最近的 GCC)都可以让你在 char* s = "String"; 上运行而不会出错。另一方面,有些人可能会发出警告... (Demo) 很好解释。我希望我可以标记每个人,但我不能。他比你先回答。没关系,我猜。你的解释很有帮助。我很喜欢。谢谢,大卫。实际上,我在 const.... 上找到了更多名为“const-correctness”的 wiki 文章。 :] @ildjarn +1 感谢您的精彩评论和演示。 :] @JohnWong 很高兴能帮上忙(甜甜的声望点也不错,muhahaha)。 const 正确性非常值得学习; C++ 是一种非常挑剔且极其微妙的语言,正确地获得 const 的正确性有时可能会让人头疼,但在避免您以后失足时会非常有帮助。 C++ 不是我最喜欢的语言...【参考方案2】:

你为什么还要扔和接绳子?

您应该抛出和捕获异常,例如std::runtime_error

您的问题的答案是,每当您在代码中的引号中插入一个字符串时,它都会返回一个以 null 结尾的 const char*

您的代码无法按上述方式运行的原因是它的类型错误,因此 catch 并没有捕捉到您抛出的内容。你正在抛出一个 const char*。

char 数组中超出堆栈/堆大小的字符数没有限制。如果您指的是您发布的示例,则该人创建了一个固定大小的数组,因此它们受到限制。

【讨论】:

@Salgar 这是来自数据结构基础 (2ed) 一书的示例代码。所以如果我插入 int [] 它将返回为 const int* ???? (使用 const 关键字)? 同意,从 std::exception 派生所有异常。抛出基本类型会导致麻烦。确保所有内容都源自 std::exception 可以确保 catch(std::exception e) 将捕获所有内容。您想为最极端的情况(例如 DLL 边界)保留 catch(...)。经常抛出基本类型会导致经常需要catch(...)。使用throw std::runtime_error("All parameters must be greater than 0."); 是的,让您确保 catch(const std::exception& e) 将捕获所有内容。 @JongWong 没有,代码“foo”的类型是const char*,int[]的类型是int[],int*的类型是int* 我很确定字符串文字的类型为const char[N]N 是字符串长度+`(对于'\0'),而不是const char*,它只是衰减到那个。

以上是关于const char* 与 char* (C++)的主要内容,如果未能解决你的问题,请参考以下文章

C++ 函数形参里的const char作为返回值问题

c++关于const char*的问题

在 C++ 中将 const char * 与字符串连接的最干净的方法是啥?

C++标准库 如何连接两个const char *类型字符串,并返回const char * 类型结果?

c++ uint32 如何转 const char

c++错误:从不兼容的类型'const char *'分配给'char *'