字符串文字和字符文字可以连接吗?

为什么name在以下C ++代码中出现exception?

 string name = "ab"+'c'; 

等效代码在Java / C#中的行为如何?

尝试

 std::string name = "ab" "c"; 

要么

 std::string name = std::string("ab") + c; 

在C ++中,“ab”不是std::string ,而是指向字符串的指针。 向指针添加整数值时,会得到一个新指针,指向字符串的下方:

 char *foo = "012345678910121416182022242628303234"; std::string name = foo + ' '; 

name被设置为“3234”,因为”的整数值是32,并且在foo开头之后的32个字符是字符串结尾之前的四个字符。 如果字符串较短,您将尝试访问未定义内存区域中的内容。

解决方法是从字符数组中生成一个std:字符串。 std:strings允许您按预期将字符附加到它们:

 std::string foo = "012345678910121416182022242628303234"; std::string name = foo + ' '; 

name设置为“012345678910121416182022242628303234”

问题是“ab”不是C ++ std::string ,而是const char[3] 。 所以它正在寻找的+运算符是operator+ (const char[3], char) 。 这不存在,因此编译器尝试让数组衰减到指针,因此它查找operator+ (const char*, char) 。 这是存在的,所以编译器会选择它,但它做错了。 将一个整数值(char)添加到指针(const char *)是一个很常见的操作,显然,这就是这个operator +的作用。 理解这一点的关键是要意识到第一个参数是1)一个数组,2)一个指针,只要数组没有意义。 它在C中也被用作字符串,是的,但它不是字符串。 它是一个指针(或偶尔,一个数组)。

有一个operator+ (const std::string&, char)连接,但编译器甚至不会查找它,因为第一个参数不是std :: string。

所以解决方案是手动创建字符串:

 string name = std::string("ab")+'c'; 

现在编译器可以找出正确的operator +来调用。

在C ++中,编译器正在寻找具有此原型的函数:

 T operator+ (const char*, char); 

由于没有一个,它无法弄清楚T是什么并且无法解析operator<< call,因此它回退到唯一的解决方案:指针添加。 在Josh的答案中连接到字符串没有问题,因为它存在一个函数。

鉴于C ++代码:

 std::string name = "ab"+'c'; 

Java中的等价物是:

 String name = "ab".substring('c'); 

两者都将char提升为int。 当然,在Java中,它会进行范围检查,因此会引发exception。 在C ++中,你只是得到了未定义的行为(或者某些)。

Java的:

 public class Main { public static void main(String[] args) { System.out.println("AB" + 'c'); } } 

输出是:

ABC

编辑:

实际上编译器硬编码String ABc …

如果你做“AB”+ argv [0] .charAt(0); 为了使它使用变量然后编译器这样做(基本上):

 StringBuilder b = new StringBuilder; b.append("AB"); b.append(argv[0].charAt(0)); System.out.println(b.toString()); 

您可以在C#中连接字符串和字符 – 它不像C ++那样严格。

这在C#中运行得很好:

 string test = "foo" + 'b'; 

C ++编译器不会自动将字符串文字与字符文字连接起来。 但它会将字符串文字相互连接起来。 语法是这样的:

 const char * cs = "ab" "c"; // append string-literals 

正如其他人所提到的, string不是内置的 C ++语言类型。 但是C ++标准库中有一个string类型。 以下是一些用法示例:

 #include  const char * cs = "ab" "c"; std::string s1( cs ); std::string s2( "ab" "c" ); std::string s3 = "ab" "c"; 

好吧,我通常在C ++中会做的是

string name = string(“ab”)+’c’;

请记住,文字“ab” 不是字符串类型。 你在做什么是希望char数组和字符之间没有“+”,然后希望编译器能以某种方式注意到你真的希望结果是一个std :: string,然后解析你的表达式隐藏转换的某些组合的右侧,可以与运算符组合以生成该类型的结果。 对我来说似乎是一个相当高的命令。

无论如何,没关系。 你看,在C中,数组和指针之间的唯一区别是它们的内存是如何分配的。 一旦你有了,你基本上有一个“数组/指针的东西”。 因此,“+”是在所有数组和指针上定义的运算符,它接受任何整数类型的另一个参数并执行指针数学运算,返回指向该点之后的许多元素的指针。 另外,在C中,“char”实际上只是另一种整数类型。 这些C设计决策都是有用的黑客攻击 ,但正如黑客经常发生的那样,它们与直观的意外结果相结合。 因此,所有“ab”+“c”为你做的是返回一个99字节的地址,而“ab”字面值恰好存储在内存中。

有时你可以依赖隐式转换,但你真的必须准备好在其他时候帮助你的编译器。