C# 字符串文字和字符文字可以连接起来吗? > 为什么在下面的C++代码中出现错误?< /P> string name = "ab"+'c'; C++中的等效代码是如何运行的?

C# 字符串文字和字符文字可以连接起来吗? > 为什么在下面的C++代码中出现错误?< /P> string name = "ab"+'c'; C++中的等效代码是如何运行的?,c#,java,c++,string,char,C#,Java,C++,String,Char,,你可以在C语言中连接字符串和字符,它没有C++的严格。 这在C#中非常有效: 试一试 或 在C++中,“ab”不是 STD::String ,而是指向字符串的指针。将整数值添加到指针时,将得到一个指向字符串更下方的新指针: char *foo = "012345678910121416182022242628303234"; std::string name = foo + ' '; string name = std::string("ab")+'c'; name设置为“3234”,因

,你可以在C语言中连接字符串和字符,它没有C++的严格。 这在C#中非常有效:

试一试

在C++中,“ab”不是<代码> STD::String ,而是指向字符串的指针。将整数值添加到指针时,将得到一个指向字符串更下方的新指针:

char *foo = "012345678910121416182022242628303234";
std::string name = foo + ' '; 
string name = std::string("ab")+'c';
name
设置为“3234”,因为“”的整数值是32个字符,超过foo开头的32个字符是字符串结尾之前的四个字符。如果字符串较短,您将尝试访问未定义内存区域中的某些内容

解决方法是从字符数组中生成std:string。std:strings允许您按预期向其添加字符:

std::string foo = "012345678910121416182022242628303234";
std::string name = foo + ' '; 
name
设置为“0123456789101214161820222422628303234”

Java:

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

ABc

编辑:

实际上,编译器硬编码字符串ABc

如果执行“AB”+argv[0],字符(0);要使其使用变量,编译器将执行以下操作(基本上):


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

T operator+ (const char*, char);

因为没有一个,它不能计算出什么是T,不能解决<代码>操作符> P。问题是“ab”不是C++ <代码> STD::String ,而是<代码> const char [3 ] < /Cord>。 所以它要寻找的+操作符是

操作符+(const char[3],char)
。这是不存在的,因此编译器尝试让数组衰减为指针,因此它查找
运算符+(const char*,char)
。这是存在的,所以编译器选择它,但它做了错误的事情。向指针(const char*)添加整数值(char)是一种非常常见的操作,显然,这就是这个操作符+的作用。理解这一点的关键是要认识到,第一个参数是1)数组,2)数组没有意义时是指针。它在C中也用作字符串,是的,但它不是字符串。它是一个指针(或者偶尔是一个数组)

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

因此,解决方案是手动创建字符串:

char *foo = "012345678910121416182022242628303234";
std::string name = foo + ' '; 
string name = std::string("ab")+'c';

<>现在编译器可以找到正确的操作符+调用。< /p> < P> C++编译器不会自动将字符串文字与字符文字连接起来。但它会将字符串文本彼此连接起来。语法如下所示:

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

正如其他人提到的,字符串 >不是内置C++语言类型。但是C++标准库中有一个<代码>字符串类型。下面是一些用法示例:

#include <string>
const char * cs = "ab" "c";
std::string s1( cs );
std::string s2( "ab" "c" );
std::string s3 = "ab" "c";
#包括
const char*cs=“ab”“c”;
std::字符串s1(cs);
std::字符串s2(“ab”“c”);
std::string s3=“ab”“c”;
给出C++代码:

std::string name =  "ab"+'c';
Java中的等价物是:

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

两者都将char升级为int。当然,在Java中,它会检查范围,因此会引发异常。在C++中,你只会得到不明确的行为(或一些行为)。

< P> >我通常在C++中做的是

字符串名称=字符串(“ab”)+“c”

请记住,文字“ab”不是string类型。您所做的是希望char数组和char之间没有“+”可以工作,然后希望编译器能够以某种方式注意到您确实希望结果是std::string,然后在右侧解析表达式,以进行一些隐式转换组合,这些转换组合可以与运算符组合在一起产生那种类型的结果。对我来说,这似乎是一个相当高的要求

不管怎样,这都没关系。你看,在C语言中,数组和指针之间唯一的区别就是它们的内存分配方式。一旦你有了一个,你基本上就有了一个“数组/指针的东西”。因此“+”是一个在所有数组和指针上定义的运算符,它接受任何整数类型的另一个参数并进行指针数学运算,返回一个指向经过该点的那么多元素的指针。而且,在C中,“char”实际上只是另一种整数类型。这些C设计决策都是有用的黑客行为,但正如经常发生的黑客行为一样,它们与直觉上意想不到的结果结合在一起。因此,“ab”+“c”为您所做的就是返回一个地址,该地址超过了“ab”文本存储在内存中的99字节


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

为什么不做STD::因为java和C++都不使用CUT,它们的行为是通过抛出编译错误“AB”不是一个字符串,而是C++中的一个字符。它们不能用+运算符连接。我只是想知道发生了什么事,你想知道C++还是C?你在C++中加了标签,但在这个问题中提到了C,它找到了一个,它并不是你希望的那个。最终得到的是指针算术,而不是字符串连接。这一点很好。但是现在这个问题已经改变了很多次,我不知道他在问什么。这不是严格的问题,只是字符串在C++中技术上不存在,你忘记了输出中的“\n”。这是println()而不是print():),这里实际发生的是在+操作之前将char文本转换为string literal,然后+操作从“AB”和(string)“c”字符串文本生成一个新字符串。@OTisler朋友之间的一些额外换行是什么?:-为了包含换行符:-P并显示编译时发生的情况,删除了我先前的误导性评论。它不是未定义的。它只是将整数值'c'添加到指向静态分配的字符数组{'a','b'}的指针上。当然,结果是未定义的,但这仅仅是因为最终指向数组。我相信有一个指针的行为是完全正确的
std::string name =  "ab"+'c';
String name = "ab".substring('c');