当前位置: 首页 > news >正文

网站建站实训总结利用codeing做网站

网站建站实训总结,利用codeing做网站,摄影作品网站排行榜,阿里云服务器做网站安全吗三、基础语法2#xff08;30小时精通C和外挂实战#xff09; B-02内联函数B-04内联函数与宏B-05_constB-06引用B-07引用的本质B-08-汇编1-X86-X64汇编B-09-汇编2-内联汇编B-10-汇编3-MOV指令C-02-汇编5-其他常见指令C-05-汇编8-反汇编分析C-07-const引用、特点 B-02内联函数 … 三、基础语法230小时精通C和外挂实战 B-02内联函数B-04内联函数与宏B-05_constB-06引用B-07引用的本质B-08-汇编1-X86-X64汇编B-09-汇编2-内联汇编B-10-汇编3-MOV指令C-02-汇编5-其他常见指令C-05-汇编8-反汇编分析C-07-const引用、特点 B-02内联函数 内联函数 作用将函数调用展开成函数体代码说白了如果 #include iostream using namespace std;inline void func(){cout func() endl;cout func() endl;cout func() endl;}inline int sum(int v1, int v2){return v1 v2; }int main(){func();func();func();int c sum(10, 20);cout c endl;getchar();return 0; }如上代码调用func函数如果没有内联汇编很简单几句就是调用但如果是内联函数就相当于下方直接在函数调用展开称为函数体执行代码很多机器码也很多 int main(){cout func() endl;cout func() endl;cout func() endl;cout func() endl;cout func() endl;cout func() endl;cout func() endl;cout func() endl;cout func() endl;int c sum(10, 20);cout c endl;getchar();return 0; }从这个角度想这样是代码体积变大好像没有什么意义还不如不内联直接调用。 //开辟栈空间 void func(){cout func() endl;cout func() endl;cout func() endl;} //结束栈空间int sum(int v1, int v2){return v1 v2; }还是有意义的虽然函数调用的话可以减少体积平时封装函数就是减少体积、提高复用率但是函数调用是有代价的开辟栈空间我们每调用一次函数一个函数开始时开辟栈空间此函数结束时调用栈空间。 一旦内联函数就不存在函数调用了程序运行时直接执行函数体中的内容不存在调用函数也就是不存在函数栈空间的开辟也不存在回收栈空间这样其实执行效率变高了就不会去分配回收内存了就直接相加了 什么情况下使用内联函数呢 第一调用的函数代码体积不是很大只有几行 第二函数经常调用每隔几秒就调用一次 像体积小且调用次数高的函数建议将其声明为内联函数不是内联经常调用会频繁开辟、回收栈空间这个操作一旦内联就不存在这种内存操作了直接将代码拿来使用可以提高效率 Inline是建议编译器将函数内联不一定会执行的如果代码体积太大编译器优化时就不会将函数内联。 递归函数不会被内联如下 inline void run(){run(); }下面我们来窥探一下内联的本质 我们先不内联正常调用函数可以发现反汇编有call调用接着我们内联反汇编 注意当我们写入inline进行函数内联时进入反汇编并没有看到内联的效果因为这是debug调试模式下的而内联函数inline是优化时起作用的所以我们要进入release模式下看结果。 我们先进入release模式下将inline先去掉没有内联反汇编看一看我们运行后发现代码如下 20: int c sum(10, 20);21: cout c endl; 8B 0D 54 30 26 00 mov ecx,dword ptr ds:[263054h] 68 90 19 26 00 push 261990h 6A 1E push 1Eh FF 15 34 30 26 00 call dword ptr ds:[263034h] 8B C8 mov ecx,eax FF 15 5C 30 26 00 call dword ptr ds:[26305Ch] 即便编译器不是内联也会在release模式下进行优化直接就将30的值push进去了最终代码变成上面那样了直接代码 cout 30 endl;连加法都省掉了我们现在要证明inline的优化作用而这样编译器直接优化了会看不出来此时我们需要将其禁止优化 右击项目属性禁止优化此时无inline反汇编看到存在函数调用无优化 20: int c sum(10, 20); 6A 14 push 14h 6A 0A push 0Ah E8 DE FF FF FF call sum (09216A0h) 83 C4 08 add esp,8 89 45 FC mov dword ptr [c],eax 这时我们要加入inline刚刚在debug模式是不行的此时我们要在release模式禁用优化下看其作用但是还不行我们在属性的C下的优化下禁用优化还需要将内联函数扩展选为任何适用项此时就能看出了如下 20: int c sum(10, 20); B9 0A 00 00 00 mov ecx,0Ah 83 C1 14 add ecx,14h 19: 20: int c sum(10, 20); 89 4D FC mov dword ptr [c],ecx 就相当于int c v1 v2;这个是直接将函数体中的内容拿过来直接执行没有进行调用 递归函数就没必要加inline最终在汇编中还是调用函数 刚刚我们是在汇编的方式进行的现在我们将inline去掉另其运行生成exe在release模式下我们使用IDA这个工具 有func\sum这两个函数 当加入inline时发现内联的函数没了只有一个main函数是优化掉了将内联的函数体直接运行无调用相当于只有一个main函数执行。 B-04内联函数与宏 内联函数与宏都可以减少函数调用的开销 #define add(v1,v2) v1v2 #定义宏add这个宏将左边的东西替换成右边的东西int main(){int c add(10, 20); #宏替换变成int c v1v1; cout c endl;getchar();return 0; }像这种做这些数学运算的建议将其直接转换成函数代码就不要存在函数调用两种方式一种写成宏一种写成内联函数 推荐大家使用内联函数内联函数目前看来还是个函数看起来是个函数我们写代码时是有提示的在内联函数里在写宏的时候没有提示 函数有个特点传参 如果看别人写C代码表达式在左边将右边的值赋给表达式不要惊讶这是可以的但是C语言是不可以的这个了解一下 B-05_const Const这个知识点很重要我们要重视 #include iostream using namespace std;int main(){Const int age 10;age 20;getchar();return 0; }我们只在第一次定义的时候可以赋值使用const以后都不能更改这个值防止别人更改 Const必须在定义的时候使用 如果修饰的是类、结构体的指针其成员也不可以更改 在C/C中有结构体的概念如 #include iostream using namespace std;struct Date { #定义了一个结构体int year;int month;int day; };int main(){Date d { 2011, 2, 5 }; #定义一个结构体变量d并依次赋值在C语言中的定义需要struct Date d { 2011, 2, 5 }; d.year 2015;int age 10;age 20;getchar();return 0; }Const Date d { 2011, 2, 5 }; 我们在定义是加入const成员无法更改Date *p d1;//用一个指针指向d1这个结构体指针类型为date会执行date类型的//我们可以使用指针来修改所指向的d1的成员值p-year 2015;//这是使用指针简介去修改//结构体本身访问成员用点指向结构体的指针去访问结构体的成员使用的是-语法规定cout d1.year endl;const Date *p d1;/不能通过指针去修改d1的东西#include iostream using namespace std;struct Date {int year;int month;int day; };int main(){int age 10;const int *p1 age;//p2不是常量,*p2是常量int const *p2 age;//p3是常量,*p3不是常量int * const p3 age;//p4是常量,*p4是常量const int * const p4 age;//p5是常量,*p5是常量int const * const p5 age;*p4 20; //age 20p4 height;*p4 40; //height 40;getchar();return 0; }引用就下节课再讲引用这东西非常非常的关键 再下节课就将汇编讲完后大家对C汇编代码就可以自己去看了 我们这只是学语法学完后我们可以把别人的库拿来 B-06引用 在C语言中使用指针pointer可以间接获取、修改某个变量的值 int age 10; int *p age; *p 20; cout *p endl;age 是取一个地址值 p里面存放着age的地址 *p是取p里面存放的地址对应的age中的值 在C中使用引用reference可以起到跟指针类似的功能 int age 10; #定义了一个引用refagerefage相当于是age的别名使用refage就是使用ageint refage age; refage 20;cout age endl;指针可以修改指向引用不能修改指向 引用开始 定义指向某个变量以后就将其作为那个变量 可以利用引用初始化另一个引用相当于某个变量的多个别名 int age 10; int refage age; int refage1 refage; int refage2 refage1;引用的价值之一是比指针更安全 指针用的好的话很强大用的不好的话很危险指针可以随意修改指向它就有可能指向不该指向的地址如某些存放重要数据的地址引用只有定义时指向之后便不能修改指向要安全 void swap(int v1,int v2){int temp v1;v1 v2;v2 temp; }int main(){int a 10;int b 20;swap(a, b);cout aa,bb endl;getchar();return 0; }如上程序是无法将ab的值相互调换的传值是相当于swap(int v1a,int v2b)将变量a与b传给V1和V2在函数swap中没有a与b的值这不是全局变量所以调用此函数无法变换值 而使用地址传递时相当于swap(int *v1a,int *v2b)这个地址在全部空间都能找到可以直接访问地址内的值然后将其对换 正确写法如下 void swap(int *v1,int *v2){int temp *v1;*v1 *v2;*v2 temp; }int main(){int a 10;int b 20;swap(a, b);cout aa,bb endl;getchar();return 0; }这是指针然后发现会比较麻烦传递是需要些取值需要加*很麻烦但是有了引用我们就不需要这么做我们只需要在函数中定义引用即可如下 void swap(int v1,int v2){int temp v1;v1 v2;v2 temp; }int main(){int a 10;int b 20;swap(a, b);cout aa,bb endl;getchar();return 0; }这样是可以交换的相当于swap(int v1a,int v2b),V1引用AV2引用B别名可以作为外面的AB的值使用引用代码量减少简单之前指针的的效果也能达到在函数里面的V1能指向外面的A 函数每次被调用都要创建一个变量产生的V1和V2都是全新的存储空间也是全新的当调用完后V1和V2的存储空间就被销毁了再次调用swap又会创建新的存储空间所以和之前讲 的从一而终并不矛盾 void swap(int v1,int v2){int temp v1;v1 v2;v2 temp; }int main(){int a 10;int b 20;swap(a, b);cout aa,bb endl;int c 2;int d 3;swap(c, d);cout c c ,d d endl;getchar();return 0; }如果在同一个V1不能重新指向 一定要在定义引用的同时给其一个变量否则会报错 int v1a默认情况下引用变量的类型必须和指向的类型相同 引用所指向的变量与是否为全局变量无关下面也是可以引用的 Int abc 1; Int main(){ Int ref abc; }B-07引用的本质 引用的本质就是指针只是编译器削弱了它的功能 指针可以改变指向而引用不能改变可以间接修改其值 写法上引用比指针简单而本质上引用就是指针 一个指针多大与CPU架构有关 int main(){int age 10; // *p就是age的别名int *p age;*p 30;cout sizeof(p) endl;//看指针变量p占多少字节这个是看运行环境决定在64位环境中是8个字节X86的32位运行环境是4字节cout sizeof(age) endl;//整型变量一般就是4个字节和我们的CPU架构是没有什么关系的//ref就是age的别名定义好refage那一刻往后只要使用refage就是使用age它就是age所以refage占4个字节int refage age;refage 40;cout age endl;cout sizeof(refage) endl;//此处实际在此时age是多少个字节这样测引用占多少个字节是不标准的cout sizeof(refage) endl;//变成refage测也是不对的这个相当于取出refage的地址看地址占多少字节就是看指针多少自己与CPU架构相关这样无法证明引用占多少字节getchar();return 0; }我们现在使用汇编来看其本质我们打入断点进入调试状态接着转汇编这还不是最终的汇编里面的类似【P】之类像变量的是VS为了帮助我们理解生成的为了看到最终的汇编我们右击将显示符号名去掉 26: int *p age; 8D 45 F4 lea eax,[age] 89 45 E8 mov dword ptr [p],eax 27: *p 30; 8B 45 E8 mov eax,dword ptr [p] C7 00 1E 00 00 00 mov dword ptr [eax],1Eh 32: int refage age; 8D 45 F4 lea eax,[age] 89 45 DC mov dword ptr [refage],eax 33: refage 30; 8B 45 DC mov eax,dword ptr [refage] C7 00 1E 00 00 00 mov dword ptr [eax],1Eh 为了看到最终的汇编我们右击将显示符号名去掉 以去掉之后就发现不一样了 26: int *p age; 8D 45 F4 lea eax,[ebp-0Ch] 89 45 E8 mov dword ptr [ebp-18h],eax 27: *p 30; 8B 45 E8 mov eax,dword ptr [ebp-18h] 27: *p 30; C7 00 1E 00 00 00 mov dword ptr [eax],1Eh 32: int refage age; 8D 45 F4 lea eax,[ebp-0Ch] 89 45 DC mov dword ptr [ebp-24h],eax 33: refage 30; 8B 45 DC mov eax,dword ptr [ebp-24h] C7 00 1E 00 00 00 mov dword ptr [eax],1Eh 左边的地址值是右边机器码的地址值我们的机器码、代码都是载入内存的每一个机器码都有地址每次启动时代码地址值可能会变只要改变代码再启动地址都会变或者切换运行环境代码值也会变 每个应用都有起始地址如果每个应用的起始地址固定那么函数地址也固定但是如果起始地址随机那么函数地址也随机 我们现在转汇编看的不是内存条的真实的物理地址是虚拟地址是操作系统给的虚拟地址它会将虚拟地址映射到真正的内存条上去 我们发现两者一样引用的本质就是指针 为什么能通过引用间接访问age因为它的本质就是指针这样的写法简单了 int refage age; refage 30;本质上refage是个指针存储着age的地址将30赋值给refage所指向的age中 还是个弱化的指针这是编译器的特性编译器层面已经规定它的写法。 B-08-汇编1-X86-X64汇编 引用的本质是指针我们现在要读懂汇编代码 利用汇编挖掘编程语言本质免费课建议看课后有时间可以看完 汇编语言较多它是与CPU挂钩的 ARM汇编是嵌入式移动设备上的iPad、iPhone 、Android 我们现在着重看X64汇编X64汇编根据编译器不同有两种书写格式 Intel ATT 在我们windows平台在VS中使用的是Intel汇编如果是MAC平台一般格式为ATT汇编语言是不区分大小写的 学习汇编2大知识点 1汇编指令 2寄存器寄存器是在CPU里面的程序一启动载进内存A,B,C变量存储在内存CPU要对变量进行操作如进行±运算会借助寄存器先将内存中的数据放到寄存器在CPU计算好再将值放回内存。 先将数据放到寄存器离CPU更近来算更快 39: int a 3; C7 45 F8 03 00 00 00 mov dword ptr [a],3 40: int b a 1; 8B 45 F8 mov eax,dword ptr [a] #将A取出给寄存器 83 C0 01 add eax,1 #寄存器加1 89 45 EC mov dword ptr [b],eax #将寄存器给B寄存器非常重要没有寄存器就没法做很多运算 简单的两个变量间的计算就有寄存器的参与 不同的汇编寄存器是不一样的如X86,X64,ARM等寄存器不同汇编也不同 我们现在只学我们用的上的寄存器 Registers寄存器 RAX\RBX\RCX\RDX:通用寄存器在64位这些寄存器很常用剩下的是有特殊用途的寄存器RBP后的有机会讲 而在32位 EAX\EBX\ECX\EDX:通用寄存器更久一些 16bit AX\BX\CX\DX:通用寄存器一个寄存器存储多大和指针一样看CPU架构是什么 X64的一个寄存器如RAX能存8个字节的数据 虽然我们现在用的是X64汇编但还是兼容以前的寄存器的 EAX存在于RAX里面这样就兼容了 Mov eax,10 表面上将10给了eax32位的寄存器实际也对RAX改变AH H height 高字节 AL L low 低字节B-09-汇编2-内联汇编 我们写的C代码但我们能否将汇编代码嵌入其中这就是内联汇编 __asm{}在这其中就可以写汇编代码了 我们完全可以C代码和汇编代码混着用 5: int a10; C7 45 F4 0A 00 00 00 mov dword ptr [ebp-0Ch],0Ah 6: __asm{7: mov eax,a 表面上a是个实际上转的是Ad的地址值 8B 45 F4 mov eax,dword ptr [ebp-0Ch] 8: }我们给RAX赋值一样会影响到EAX的值 B-10-汇编3-MOV指令 Mov dest,src6: int a 3; C7 45 F8 03 00 00 00 mov dword ptr [ebp-0CH],3 #ebp-8是变量a的地址7: int b a 1; 8B 45 F8 mov eax,dword ptr [ebp-0CH] 83 C0 01 add eax,1 89 45 EC mov dword ptr [ebp-14h],eax int main(){ int a 3;int b a 1;getchar();return 0; }ebp的值010FFE58H a的地址010FFE4CH ebp-0CH a是局部变量每次使用都会重新分配地址给它它的地址是变化的所以最终生成的地址值不能是写死的006FFAB8H,每次调用函数的时候ebp都是新的值这样就能保证 函数调用分配空间函数调用完销毁空间 全局变量的地址值是写死的 18: age 3; 00E4506E C7 05 08 F0 E4 00 03 00 00 00 mov dword ptr ds:[0E4F008h],3 全局变量是程序一启动就会存在的不变的 如果想要弄懂可以看 利用汇编挖掘程序语言的本质 每一个字节都有自己的内存地址 Mov [1128h],3 将3放到1128h地址所对应的存储空间这里是使用一个字节存储3 int a 3; 这里使用4个字节存储3一般我们把3放到某个内存空间时都要指定一下单位 Ptr固定写法指定空间大小 Word表示2个字节 mov word ptr [1128h],3 这里3通过两个字节存储只知道一个地址值就一个字节如果给定一个地址 值一般来说是向高地址吞并自己 dword为4个字节mov eax,dword ptr [1128h] 从1128h内存地址开始取出4个字节1128h、1129h、112Ah、112Bh共4个字节的内容传给eax凡是看到【】里面放的都是地址值 凡是看到call 就是调用函数 17: test(); E8 B1 C3 FF FF call 00941424 18: func(); E8 B1 C3 FF FF call 00941429 一个字节是8位用四个字节存储3的话怎么存 4个字节存储3 16进制 00 00 00 03H2进制 000000000 000000000 000000000 000000011CPU大小端模式我们接触的大部分是小端模式高高低低高字节放高地址低字节放低地址 比较低字节的东西放到低地址的地方 int a 10;我们调试在下面监视窗口名称输入a可以看到a的地址值0x00EFF7B0 我们在调试-窗口-可以找到内存我们选一个可以窥探到内存而且精细到每一个字节 我们在内存中搜索0x00EFF7B0结果如下 0x00EFF7B0 0a 00 00 00 cc cc cc cc 08 f8 ef 00 ....????.??. 0x00EFF7BC f9 5b b4 00 01 00 00 00 20 64 12 01 ?[?..... d.. 0x00EFF7C8 20 74 12 01 ca cd cc 97 71 12 b4 00 t..????q.?. 0x00EFF7D4 71 12 b4 00 00 20 d5 00 00 00 00 00 q.?.. ?..... 0x00EFF7E0 00 00 00 00 00 00 00 00 00 00 f0 00 ..........?.我们可以让他们每一列显示一个字节 0x00EFF7B0 0a . 0x00EFF7B1 00 . 0x00EFF7B2 00 . 0x00EFF7B3 00 . 0x00EFF7B4 cc ? 0x00EFF7B5 cc ? 0x00EFF7B6 cc ? 0x00EFF7B7 cc ? 0x00EFF7B8 08 . 0x00EFF7B9 f8 ? 0x00EFF7BA ef ? 0x00EFF7BB 00 . 0x00EFF7BC f9 ? 0x00EFF7BD 5b [ 0x00EFF7BE b4 ?变量a占了4个字节如上又是小端模式所以读数从高像低读00 00 00 0a 就是10 我们平常编程是不关心大小端模式的 一个变量的地址值是它所有字节地址中的最小值 寄存器是独立存在的相对于内存相互独立存在的 汇编 1用在性能极致优化 2外挂 3软件破解 4嵌入式开发一些操作某个硬件的代码只能用汇编我们学汇编只是为了弄懂高级语言的的底层是干什么了 C-02-汇编5-其他常见指令 Lea dest,[地址值]Load effect address装载有效的地址值将地址值装载进来Lea eax,[1122H] 直接将地址值赋值给eax 相当于 eax 1122Hmov eax,dword ptr [1122H] 1122H地址对应的存储空间取出4字节的数据假设为4赋值给eaxeax 4//int a 10; //ebp-8是变量a的地址 00B0784E mov dword ptr [ebp-8],0Ah //int b 5; //ebp-14h是变量b的地址 00B07855 mov dword ptr [ebp-14h],5 //eax a 10 00B0785C mov eax,dword ptr [ebp-8] //cmp是compare的简称比较 //比较eax和b的值是否相等比较后会有结果结果会影响到下面jne 00B0785F cmp eax,dword ptr [ebp-14h] //jne:jump not equal比较结果不相等才跳转 00B07862 jne 00B0787D 24: printf(1111); 00B07864 mov esi,esp 00B07866 push 0B0CC70h 00B0786B call dword ptr ds:[00B10194h] 00B07871 add esp,4 00B07874 cmp esi,esp 00B07876 call 00B012D5 25: }26: else 00B0787B jmp 00B07894 27: {28: printf(2222); 00B0787D mov esi,esp 00B0787F push 0B0CCB8h 00B07884 call dword ptr ds:[00B10194h] 00B0788A add esp,4 00B0788D cmp esi,esp 00B0788F call 00B012D5 38: getchar(); 00B07894 mov esi,esp 00B07896 call dword ptr ds:[00B1017Ch] 00B0789C cmp esi,esp 00B0789E call 00B012D5 39: return 0; 00B078A3 xor eax,eax 40: }直接看汇编是不容易看出来的在VS中我们可以显示符号名会在函数地址的左边显示函数名对比着看 汇编金手指 权威参考Intel白皮书 函数的返回值一般放到EAX 函数调用过程中ESP,EBP牵扯到栈 Call之前的push是传参 跳转指令很多只需掌握使用的即可不懂的可以在网上查 C-05-汇编8-反汇编分析 21: int a 1; 003E784E mov dword ptr [a],1 22: int b 2; 003E7855 mov dword ptr [b],2 23: int c a b; 003E785C mov eax,dword ptr [a] 003E785F add eax,dword ptr [b] 003E7862 mov dword ptr [c],eax 为什么要借助寄存器EAX中转一下为什么不能内存加内存再赋给内存不行这是有CPU架构指令的CPU架构决定有些操作只能针对寄存器不能直接对内存进行操作 dword ptr [b] 从b内存地址对应的存储空间取值Mov dword ptr [b] dword ptr [a] 此操作错误mov指令不支持此操作不能内存到内存Intel白皮书已经规定了没有这样的操作优化分不同程度不同编译器有不同优化有的没有用途的代码在汇编中直接就会消失 指针变量和句部变量是一样的都在内存中都有内存地址 //int age 3; 00DA7CA8 mov dword ptr [ebp-0Ch],3 //eax ebp-0Ch,存放着age的地址值 00DA7CAF lea eax,[ebp-0Ch] //ebp-18h是指针变量p的地址值 //将age的地址值存放到指针变量p所在的存储空间 //int *p age; 00DA7CB2 mov dword ptr [ebp-18h],eax //*p 5; //将age的地址值存放到eax 00DA7CB5 mov eax,dword ptr [ebp-18h] //age 5; 00DA7CB8 mov dword ptr [eax],5 上面两个通过指针简介修改age的值 Mov是带单位的取数据是取多少个字节 Lea不要取数据所以地址值左边不用写单位的如dword Mov eax,ebp-0Ch 错误mov不支持运算但在中括号中可以进行简单的地址运算所以要使用lea不使用mov将地址传给某个人 如果要改的话得 Sub ebp0Ch Mov eax,ebp但这样ebp的值就改变了使用lea的话ebp的值不会发生改变也能运算 只要将地址给某个就leamov是不可以的就不深究了 引用的汇编代码和指针是一样的引用的本质就是汇编。 00DA7CAF lea eax,[ebp-0Ch] 00DA7CB2 mov dword ptr [ebp-18h],eax 我们以后看到上面两段代码可以知道 1ebp-18h是指针的地址值ebp-0Ch是另一个变量的地址值 C-07-const引用、特点 常引用 引用被const修饰后就变成了长引用就不能再被修改了可以访问但不能改 int const ref age;ref 30;为什么这里ref可以被修改这个表面上看确实不太容易但按照指针的方式看的话如下 int * const p age; p30; 此处不能被修改const修饰的是右边修饰的是指针变量里面存储的是地址所以指针变量不能被修改而指针所指向的存储空间时可以修改的 *p30; 但这可以修改指针所指向的存储空间时可以修改的*p就是age相对于引用来说ref就是age与指针相对比就可以看出了 int age 10; int height 120; //指向变量P1不能修改指向可以利用指向变量P1间接修改所指向的变量 int * const p1 age; //p1 height; *p1 30;//指向变量P2可以修改指向不可以利用指向变量P2间接修改所指向的变量 int const *p2 age; p2 height; //*p230;注意引用是有限制的它本身不能修改指向 引用的本质就是指针所以两者写法一样时两者const所在位置相同时看指针指针什么行为它就什么行为 //ref1不能修改指向但是可以通过ref1间接修改所指向的变量 int const ref1 age; //注意此处引用本身不能修改指向故此处相当于int ref1 age; ref1 30;//ref2不能修改指向此处不可以通过ref1间接修改所指向的变量 int const ref2 age; //ref2 40; 此处报错无法修改Const引用特点可以指向临时数据 作为函数参数时可以接受const和非const实参 int sum(const int v1, const int v2){return v1 v2; }int main(){//非cost实参int a 10;int b 20;sum(a,b);//const实参const int c 10;const int d 20;sum(c, d);很多语法不是很懂没关系到时候看汇编就能验证了 当常引用指向不同类型的数据时会产生临时变量即引用指向的并不是初始化时的那个变量 此处为int类型本身的 int age 10;const int ref age;age 30; 00FC5F34 mov dword ptr [ebp-3Ch],0Ah 00FC5F3B lea eax,[ebp-3Ch] 00FC5F3E mov dword ptr [ebp-48h],eax 00FC5F41 mov dword ptr [ebp-3Ch],1Eh cout age is age endl; #结果过30cout ref is ref endl; #结果30当const为另一种数据类型long时 int age 10;const long ref age;age 30; 00515F34 mov dword ptr [ebp-3Ch],0Ah 00515F3B mov eax,dword ptr [ebp-3Ch] 00515F3E mov dword ptr [ebp-54h],eax 00515F41 lea ecx,[ebp-54h] 00515F44 mov dword ptr [ebp-48h],ecx 00515F47 mov dword ptr [ebp-3Ch],1Eh cout age is age endl; #结果过30cout ref is ref endl; #结果10我们发现这两个结果是不一样的因为变为另一种数据类型时从汇编代码可以看出产生了一个临时变量临时产生了一个地址ebp-54h所以我们指向的是临时变量的地址所以结果为10 不同编程语言转成的汇编是一样的吗 Java、C、OC、swift写代码 --》汇编\机器码取决于CPU架构 编译器不同产生的汇编可能是不同的如将其生成X86架构或者X64的汇编、机器码 最终生成什么汇编和你最终运行的平台有关汇编、机器指令是有CPU定好的CPU支持哪些汇编指令哪些机器指令由CPU架构决定 CPU决定支持哪些汇编机器码 Imm 表示立即数就是直接写出来的值如3等不是变量a等数 m内存允许立即数赋给内存在白皮书是找不到左边内存右边内存的即mov [],[]不存在
http://www.pierceye.com/news/777033/

相关文章:

  • 中企动力网站建设合同中天建设招标网站
  • 湖南手机版建站系统开发wordpress获取用户角色
  • 南皮网站建设价格泰安房产信息网官网首页
  • 网页制作与网站建设实战大全重庆房产信息网官网
  • 上海的网站建设公司app对接网站登录要怎么做
  • 江苏省备案网站现在什么网站做外贸的最好
  • 如何知道网站是否被k蓝山网站建设
  • 网站维护服务公司免费的网站推广渠道
  • 网站建设方案应该怎么写asp网站无法上传图片
  • 建个网站多少钱app企业关键词排名优化公司
  • 电子商务他们的代表网站代码网站怎么做的
  • 如何做网站卖东西长春互联网公司排名
  • 怎样拥有自己的网站制作网站的步骤和方法
  • 北京电子商务app网站建设大兴小程序源码如何部署到服务器
  • 设计找图网站网站用什么构建
  • 做微信的网站叫什么软件湛江网站建设制作维护
  • 做网站商城多少钱wordpress链接公众号
  • 数码产品销售网站建设策划书金融类网站模板
  • 档案网站建设视频网络软营销的案例
  • 德州市建设局质监站网站织梦做的网站打包在dw修改
  • 做那个男女的视频网站湖南响应式网站公司
  • 1个ip可以做几个网站电商网站建设阿里云
  • 网站做seo需要些什么wordpress虎嗅破解版
  • 网站开发按钮图片素材巩义自助建站优化
  • 石家庄网站建设接单常见的网络直接营销有哪些
  • 上海网站建设技术托管找合伙人做网站
  • 网站和自媒体都可以做东莞专业营销网站建设推广
  • 毕业设计网站怎么做校园网二手书交易网站建设
  • 网站运营托管协议凡科建设网站还用买服务器吗
  • 黑龙江省建设网官方网站erp系统软件免费版