大佬教程收集整理的这篇文章主要介绍了C++学习笔记之基础语法,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
先看一下switch和if汇编代码的区别:
int a = 3;
00007FF6A1831B4C mov dword ptr [a],3
if (a == 1)
00007FF6A1831B56 cmp dword ptr [a],1
00007FF6A1831B5D jne main+164h (07FF6A1831B74h)
{
cout << a;
00007FF6A1831B5F mov edx,dword ptr [a]
00007FF6A1831B65 mov rcx,qword ptr [__imp_std::cout (07FF6A1841150h)]
00007FF6A1831B6C call qword ptr [__imp_std::basic_ostream<char,std::char_Traits<char> >::operator<< (07FF6A18411E0h)]
00007FF6A1831B72 jmp main+195h (07FF6A1831BA5h)
}
else if (a == 2)
00007FF6A1831B74 cmp dword ptr [a],2
00007FF6A1831B7B jne main+182h (07FF6A1831B92h)
{
cout << a;
00007FF6A1831B7D mov edx,dword ptr [a]
00007FF6A1831B83 mov rcx,qword ptr [__imp_std::cout (07FF6A1841150h)]
00007FF6A1831B8A call qword ptr [__imp_std::basic_ostream<char,std::char_Traits<char> >::operator<< (07FF6A18411E0h)]
}
else
00007FF6A1831B90 jmp main+195h (07FF6A1831BA5h)
{
cout << a;
00007FF6A1831B92 mov edx,dword ptr [a]
00007FF6A1831B98 mov rcx,qword ptr [__imp_std::cout (07FF6A1841150h)]
00007FF6A1831B9F call qword ptr [__imp_std::basic_ostream<char,std::char_Traits<char> >::operator<< (07FF6A18411E0h)]
}
switch (a)
00007FF6A1831BA5 mov eax,dword ptr [a]
00007FF6A1831BAB mov dword ptr [rbp+154h],eax
00007FF6A1831BB1 cmp dword ptr [rbp+154h],1
00007FF6A1831BB8 je main+1B5h (07FF6A1831BC5h)
00007FF6A1831BBA cmp dword ptr [rbp+154h],2
00007FF6A1831BC1 je main+1CAh (07FF6A1831BDAh)
00007FF6A1831BC3 jmp main+1DFh (07FF6A1831BEFh)
{
case 1:
cout << a;
00007FF6A1831BC5 mov edx,dword ptr [a]
00007FF6A1831BCB mov rcx,qword ptr [__imp_std::cout (07FF6A1841150h)]
00007FF6A1831BD2 call qword ptr [__imp_std::basic_ostream<char,std::char_Traits<char> >::operator<< (07FF6A18411E0h)]
break;
00007FF6A1831BD8 jmp main+1F2h (07FF6A1831C02h)
case 2:
cout << a;
00007FF6A1831BDA mov edx,dword ptr [a]
00007FF6A1831BE0 mov rcx,qword ptr [__imp_std::cout (07FF6A1841150h)]
00007FF6A1831BE7 call qword ptr [__imp_std::basic_ostream<char,std::char_Traits<char> >::operator<< (07FF6A18411E0h)]
break;
00007FF6A1831BED jmp main+1F2h (07FF6A1831C02h)
default:
cout << a;
00007FF6A1831BEF mov edx,dword ptr [a]
00007FF6A1831BF5 mov rcx,qword ptr [__imp_std::cout (07FF6A1841150h)]
00007FF6A1831BFC call qword ptr [__imp_std::basic_ostream<char,std::char_Traits<char> >::operator<< (07FF6A18411E0h)]
break;
}
从上面的代码可以看出,正常情况下switch和if的性能没什么区别:
其实,编译器实现switch语句有三种方式:逐条件判断、跳转表、二分查找法,具体情况参考C++性能switch语句
枚举使用时注意作用域的问题:
@H_450_53@enum MONTH // 不限定作用域 { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER }; const int nOVEMBER = 1; //重定义错误
上面的代码会由于枚举作用域的问题出现重定义错误,参考 C++11 Enum枚举使用心得 使用限定作用域的枚举类型:
@H_450_53@enum class DAY // 限定作用域 { MONDAY, TUESDAY, Wednesday, THURSDAY, FRIDAY, SATURDAY, SUNDAY }; DAY day = DAY::SUNDAY; // OK int day = DAY::SUNDAY; //错误,限定作用域的枚举类型无法通过隐式转换到其他类型
注:由于枚举成员是const,因此建议用定义枚举成员用大写。
字节对齐的细节和具体编译器实现相关,参考32、64位编译器各类型大小和字节对齐,一般满足三个准则:
结构体作为数据成员的对齐规则:在一个struct中包含另一个struct,内部struct应该以它的最大数据成员大小的整数倍开始存储。
@H_450_53@struct S1 { char x; int z; short y; }; struct S2 { char x; short y; int z; }; cout << sizeof(S1) << endl; // 12 cout << sizeof(S2) << endl; // 8
在编码时,可以动态修改字节对齐方式,参考关于字节对齐、设置编译器的内存对齐方式(C++):
Visual C++:
g++:
可以使用undname工具查看函数的真实名称,代码如下:
@H_450_53@int test(int a) { return a; } int test(double a) { return int(a); }
使用Notepad++打开编译后的obj文件,搜索“test”得到如下内容:
?test@@YAHH@Z
?test@@YAHN@Z
在cmd中进入undname.exe所在的路径(系统内会有多个undname.exe,根据IDE的情况选择即可),我使用的是下面的路径:
cd C:\Program Files (x86)\Microsoft Visual studio\2019\Community\VC\Tools\MSVC\14.28.29333\bin\Hostx86\x64\
调用undname.exe,输入以下命令:
undname ?test@@YAHH@Z
得到函数的真实名称:
Undecoration of :- "?test@@YAHH@Z"
is :- "int __cdecl test(int)"
同理,可得到:
Undecoration of :- "?test@@YAHN@Z"
is :- "int __cdecl test(doublE)"
每一个函数都占用一段内存单元,它们有一个起始地址,指向函数入口地址的指针称为函数指针。
形式:数据类型(*指针变量名)(参数表);
举例:int (*p)(int);
与返回指针的函数之间区别:
以上是大佬教程为你收集整理的C++学习笔记之基础语法全部内容,希望文章能够帮你解决C++学习笔记之基础语法所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。