在一个相关的问题之后,我想问一下C++ 11中的新字符和字符串文字类型.看来我们现在有四种字符和五种字符串文字.角色类型:
char a = '\x30'; // character, no semantics
wchar_t b = L'\xFFEF'; // wide character, no semantics
char16_t c = u'\u00F6'; // 16-bit, assumed UTF16?
char32_t d = U'\U0010FFFF'; // 32-bit, assumed UCS-4
Run Code Online (Sandbox Code Playgroud)
和字符串文字:
char A[] = "Hello\x0A"; // byte string, "narrow encoding"
wchar_t B[] = L"Hell\xF6\x0A"; // wide string, impl-def'd encoding
char16_t C[] = u"Hell\u00F6"; // (1)
char32_t D[] = U"Hell\U000000F6\U0010FFFF"; // (2)
auto E[] = u8"\u00F6\U0010FFFF"; // (3)
Run Code Online (Sandbox Code Playgroud)
问题是:\x/ \u/ \U …
我试图弄清楚如何编写一个宏,将一个变量名称的字符串文字表示与变量本身一起传递给一个函数.
例如,给出以下功能.
void do_something(string name, int val)
{
cout << name << ": " << val << endl;
}
Run Code Online (Sandbox Code Playgroud)
我想写一个宏,所以我可以这样做:
int my_val = 5;
CALL_DO_SOMETHING(my_val);
Run Code Online (Sandbox Code Playgroud)
哪个会打印出来: my_val: 5
我尝试过以下操作:
#define CALL_DO_SOMETHING(VAR) do_something("VAR", VAR);
Run Code Online (Sandbox Code Playgroud)
但是,正如您可能猜到的那样,引号内的VAR不会被替换,而只是作为字符串文字"VAR"传递.所以我想知道是否有办法让宏参数变成字符串文字本身.
C++ 11中引入了一个非常方便的特性,称为原始字符串文字,它是没有转义字符的字符串.而不是写这个:
regex mask("\\t[0-9]+\\.[0-9]+\\t\\\\SUB");
Run Code Online (Sandbox Code Playgroud)
你可以简单地写一下:
regex mask(R"(\t[0-9]+\.[0-9]+\t\\SUB)");
Run Code Online (Sandbox Code Playgroud)
更具可读性.但是,请注意字符串周围的额外括号,以定义原始字符串文字.
我的问题是,为什么我们甚至需要这些呢?对我来说,它看起来很丑陋和不合逻辑.以下是我看到的缺点:
这就是我所说的难以区分的意思:
"good old usual string literal"
^- body inside quotes -^
R"(new strange raw string literal)"
^- body inside parenthesis -^
Run Code Online (Sandbox Code Playgroud)
以下是专业人士:
"delim( can use "()" here )delim"但是,嘿,如果你需要更多的灵活性,你有旧的好逃脱字符串文字.为什么标准委员会决定用这些绝对不必要的括号来污染每个原始字符串文字的内容?那背后的理由是什么?我没有提到的专业是什么?
UPD Kerrek的答案很棒,但不幸的是,这不是一个答案.因为我已经描述过我理解它是如何工作的,它给了什么好处.自从我提出这个问题五年过去了,仍然没有答案.我仍然对这个决定感到沮丧.可以说这是一个品味问题,但我不同意.你使用了多少个空格,你如何命名你的变量,是这个SomeFunction()还是some_function()- 这是品味问题.而且我可以轻松地从一种风格切换到另一种风格.
但是这个?经过这么多年后仍然感到尴尬和笨拙.不,这不是味道.这是关于我们如何想要涵盖所有可能的情况,无论如何.每当我们需要编写特定于Windows的路径,或正则表达式或多行字符串文字时,我们注定要编写这些丑陋的parens.为了什么?..对于那些我们实际需要放入"字符串的罕见情况?我希望我参加委员会会议,他们决定这样做.我强烈反对这个非常糟糕的决定.我希望.现在我们注定了.
感谢您阅读此内容.现在我觉得好一点.
UPD2以下是我的备选方案,我认为两者都比现有方案好很多.
提案1.灵感来自python.不能使用三引号支持字符串文字:R"""Here is a string literal with any content, except for triple quotes, which you don't actually use that often."""
提案2.受常识的启发.支持所有可能的字符串文字,就像当前的一样:R"delim"content of string"delim".用空分隔符:R""Looks …
我是一个c ++新手(只是oldschool c).我的儿子请求帮助,我无法解释.如果他问我"我如何比较字符串"我会告诉他使用strcmp(),但这并不是让我感到困惑的原因.以下是他的问题:
int main()
{
cout << ("A"< "Z");
}
Run Code Online (Sandbox Code Playgroud)
将打印1
int main()
{
cout << ("Z"< "A");
}
Run Code Online (Sandbox Code Playgroud)
也会打印1,但是
int main()
{
cout << ("Z"< "A");
cout << ("A"< "Z");
}
Run Code Online (Sandbox Code Playgroud)
然后将打印10.单独两个cout语句打印1,但连续执行我得到一个不同的答案?
我注意到字符串文字在内存中的地址与其他常量和变量(Linux OS)的地址非常不同:它们有许多前导零(不打印).
例:
const char *h = "Hi";
int i = 1;
printf ("%p\n", (void *) h);
printf ("%p\n", (void *) &i);
Run Code Online (Sandbox Code Playgroud)
输出:
0x400634
0x7fffc1ef1a4c
Run Code Online (Sandbox Code Playgroud)
我知道它们存储在.rodata可执行文件的一部分中.操作系统之后是否有一种特殊的方式处理它,所以文字最终会出现在一个特殊的内存区域(带有前导零)?这个内存位置有什么优点还是有什么特别之处呢?
在以下示例中:
cout<<"\n"[a==N];
Run Code Online (Sandbox Code Playgroud)
我不知道该[]选项的作用cout,但是当值a等于时,它不会打印换行符N.
我正在使用 Microsoft Visual C++ 将以下程序编译为 C++20 程序:
#include <iostream>
#include <tuple>
int main()
{
auto t1 = std::make_tuple("one", "two", "three");
auto t2 = std::make_tuple("one", "two", "three");
std::cout << "(t1 == t2) is " << std::boolalpha << (t1 == t2) << "\n";
std::cout << "(t1 != t2) is " << std::boolalpha << (t1 != t2) << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我看到以下输出:
(t1 == t2) is false
(t1 != t2) is true
Run Code Online (Sandbox Code Playgroud)
元组是相同的,那么为什么它的比较结果是错误的呢?我该如何解决?
#include <stdio.h>
int main() {
char a = 5;
char b[2] = "hi"; // No explicit room for `\0`.
char c = 6;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
每当我们编写一个用双引号括起来的字符串时,C 都会自动为我们创建一个字符数组,其中包含该字符串,并以 \0 字符结尾 http://www.eskimo.com/~scs/cclass/notes/sx8。 html
在上面的示例中,b只有 2 个字符的空间,因此空终止字符没有位置可放置,但编译器正在重新组织内存存储指令,以便将a和c存储b在内存中,以便为 a 腾出\0空间数组的末尾。
这是预期的还是我遇到了未定义的行为?
C++ 03 5.1主要表达式
§2:
文字是主要表达方式.它的类型取决于它的形式(2.13).字符串文字是左值; 所有其他文字都是右值.
这背后的理由是什么?
据我所知,字符串文字是对象,而所有其他文字都不是.并且l值总是指对象.
但问题是为什么字符串文字是对象,而所有其他文字都不是?
这个理由在我看来更像是鸡蛋或鸡肉问题.
我理解这个问题的答案可能与硬件架构有关,而不是C/C++作为编程语言,但我想听到同样的看法.
注意:我将此问题标记为c&c ++,因为C99标准也有类似的引用,特别是§6.5.1.4
在c#和ruby以及许多其他语言中,您可以表示不需要转义的字符串.
在c#中它是这样的
string s = @"\whatever\this\is";
Run Code Online (Sandbox Code Playgroud)
打印时的结果
\whatever\this\is
Run Code Online (Sandbox Code Playgroud)
我的问题是,这是否支持任何形式的JavaScript?