C++乱码从入门到放弃

本文最后更新于:3 个月前

(本文采用C++11标准) (本文使用到的库文件:iostream)

话说前几天,我在一篇文章中看见一个加了两对大括号的main函数 (大概长下面这样)

1
2
3
4
5
6
7
//一些必要的预处理代码...吧啦吧啦吧啦...
int main()
{
{
//代码主体...吧啦吧啦吧啦...
}
}

当时我一脸懵哔,这是神马语法,能通过编译?于是乎我把这段代码COPY进Dev-Cpp编译器,Amazing!居然 编译顺利过,运行也没出错!我突发奇想,如果能在代码中放一段乱码 还不出错,这多是一件装哔的美事,于是便有了下面这段代码

1
2
3
4
5
6
7
8
//此处省略一些预处理代码
int main()
{
//我是一段用脸滚的乱码
'\*';{1\=='\\\\'+'\`'?('$'):1;/\*\*\*/~~~!!!((+-+-0001/'\\''|1/0x9));};;qbz:///0=d\\e%(
//我是一段用手敲的代码
cout << "新年快乐呀!" << endl;
}

把上面的代码COPY进你的编译器里运行,你会发现它不仅顺利通过了编译,还成功输出了”新年快乐呀!”,这说明上面那段乱码是符合C++语法的,那到底怎样才能写出符合语法的乱码呢,经过我十多分钟的测试,这里来做一个总结(如果发现错误或有补充请通过下方评论区或通过公告栏中的邮箱告诉我,阿里嘎多!)

首先是最简单的注释,/***/和///都是常见的注释美化小技巧,其中/***/中的第二个*和///中的最后一个/都是注释内容,被编译器自动省略,所以不会引起任何错误,我们可以像下面这样写注释

1
2
3
4
5
6
///////////////////////////////
/// /* ///
/// /*编辑 at 2020年1月14日 ///
/// /*编辑 by Space Time ///
/// /* ///
///////////////////////////////

接下来便是块和语句的开始和结束符了,开篇那段故事讲得便是它,{是块的开始符,}是块的结束符,块中可以写入代码,也可以不写任何东西(空块),例如int main(){return 0;}中的{}就是一个写入了return 0;的块,而int main(){}中的{}就是一个空块,块可以在代码中套无数层,所以下面这段代码是符合语法的

1
2
int main()
{ { { {} } } }

但值得注意的是,{}不可以在全局作用域中出现,如下面这段代码是错误的

1
2
3
{
int main(){}
} //报错

语句的结束符;也可以单独出现(空语句),所以下面这段代码也是符合语法的

1
2
3
4
5
6
7
int main()
{
;
;;;;
;;;;;;;
;;;;;;;;;;
}

再接下来是字面量,字面量可以作为一个语句单独出现,另外用于提高优先级的()也是可以套无数层的,所以下面这段代码还是符合语法的

1
2
3
4
5
6
7
8
int main()
{
"C++是世界上最好的语言!"; 3.14159;
(((3.14159)));
1 + 1;
true + false;
"你大爷" == "你大爷";
}

切记不要出现++1这样的错误(因为1是右值),看懂了上面这段代码,我们再看看下面这段奇葩的代码

1
2
3
4
int main()
{
+-1;
}

这既不+又不-的玩意到底是个什么鬼啊!But actually,它还是符合语法的,这里的+和-可以理解为正和负,所以+-1其实就是-1,但是由于两个+连在一起就变成了++1(会报错),两个-连在一起就变成了–1(也会报错),所以在写这种字面量时必须一+一-地交替写,还弄不清楚可以参考下面这段代码

1
2
3
4
5
6
7
8
9
10
11
int main()
{
+1; //通过
-1; //通过
+-1; //通过
++1; //报错
--1; //报错
--+1 //报错
+-+-1; //通过
-+-+-+1; //通过
}

最后一个也是最奇葩的,先来看下面这段代码

1
2
3
4
5
int main()
{
CppJump:
123;
}

注意CppJump后面的结束符是:而不是;,没想到吧,这段代码又双叒叕是符合语法的(不用怀疑,我瞎敲得代码永远是符合语法的),这是因为goto语句的标记是以:结尾的,所以只要你在:前敲的乱码符合goto标记的命名规范,它就不会报错(其实goto标记的命名规范和变量的命名规范是一样的),但要注意的是,标记后边必须有代码,像下面这样就是错误的

1
2
3
4
int main()
{
CppJump: //报错
}

看到这里你大概已经能够看懂开头那段我用脸滚的代码了,如果你还是看不懂,那可能是因为你不知道下面这些:

  1. C++中以0开头的字面量是八进制数

  2. C++中以0x开头的字面量是十六进制数

  3. /是÷的意思

  4. |是逻辑运算符 或

  5. !是逻辑运算符 非

  6. ~是位运算符 按位取反

  7. \\是转义字符 \

  8. \‘是转义字符 ‘

  9. ‘可以隐式转换为它对应的ASCLL码(我记得好像是39)

  10. 三目运算符语法是 判断我是true还是false?是true取我:是false取我; (具体请自行gulugulu)

  11. •ᴗ•