从C++探究汇编.02

默认参数

  • C++允许函数设置默认参数,调用时根据情况省略实参:
  • 默认函数只能按照右到左的顺序
  • 如果函数同时有声明、实现,默认参数是能放在函数声明中
  • 默认参数的值可以是常量、全局符号(全局变量,函数名)
int age = 33;

void test() {
  cout  << "test()" << endl;
}

void display(int a = 11, int b = 22, int c = age, void (*func)() = test) {
  cout << "a is " << a << endl;
  cout << "b is " << b << endl;
  cout << "c is " << c << endl;
}

int main() {
  display()
  return 0;
}
  • 函数重载、默认参数可能会产生冲突、二义性(建议优先选择使用默认参数)


  • 底层分析:
    1.没有默认参数情况查看汇编:

int sum(int v1, int v2) {
  return v1 + v2;
}

int main() {
  sum(1, 2);
  sum(3, 4);
}
汇编代码

函数汇编

2.有默认参数:



两种猜测:
猜测1:

sum(1, 4)

猜测2:

int sum(int v1, int v2) {
   v2 = 4 ; return v1+v2; 
}

汇编:


两个写法完全等价

对比机器码
  • E8 : 函数调用
  • 为什么后面机器码不一样
    后面这个是根据地址算出来的值, 所以机器码有一点点不一样 (只是机器指令的位置不一样 ,也可以认为是返回值地址)不用纠结

extern “C”

  • 被 extern “C” 修饰的代码会按照C语言的方式去编译

报错
  • 两种写法
extern “C” void func() {
  cout << "func()" << endl;
}
extern “C” void func(int age) {
  cout << "func(int age)" << age << endl;
}
extern “C” {
  void func() {
    cout << "func()" << endl;
  }
  void func(int age) {
    cout << "func(int age)" << age << endl;
  }
}
  • 如果函数同时有声明和实现,要让函数声明被extern ”C“修饰,函数实现可以不修饰

最终编译时函数名不同,所以不报错,可以同时存在

  • 用于C、C++混合开发:
    1.编译方式不一样,没法直接找到调用:


2.声明上加上extern “C”: 告诉编译器 用C语言方式编译的对应的函数


3.第三方库:函数声明.h文件, 函数实现.c文件


4.把头文件包含进去就可以了,include相当于把文件内容拷贝进去


5.直接加.h里面,这样更方便


6.如果C语言也要调用呢? 报错: 因为C语言环境 不认识 extern “C”


7.希望C++环境自动加上extern c, C语言环境不加:
C++ 环境编译器默认有个宏定义 :可以用这个宏判断是否是C++环境



利用这个宏 条件编译:


8.重复包含头文件造成浪费


利用宏判断:如果没定义过ABC 定义ABC

#ifndef ABC
#define ABC
...
#endif ABC

万一其他文件也用到相同的宏定义会出问题:



故为保证每个头文件里面的宏都是唯一的,用文件名:__MATH, __OTHER

9.自动防止头文件被重复包含:


  • 防止文件被重复包含
  • 常使用#ifndef、#define、#endif 防止头文件被重复包含

  • pragma once 可以防止整个文件内容被重复包含

区别:

1.#ifndef、#define、#endif 受C,C++标准支持,不受编译器的限制
2.有些编译器不支持 pragma once,较老的编译器不支持,兼容性不够好
3.#ifndef、#define、#endif 可以针对一个文件中的部分代码,而pragma once只能针对整个文件

内联函数(inline function):

  • 使用inline修饰函数的声明或者实现,可以使变为内联函数
  • 特点
  • 编译器会将函数调用直接展开为函数体代码
  • 可以减少函数调用开销
  • 会增大代码吗的体积
  • 尽量不要内联超过10行代码的函数
  • 有些函数即使声明了,也不定会被编译器内联,比如递归函数
  • 调用函数代价:开启栈空间,回收栈空间
    一旦变为内联函数: 到时候执行这个代码的时候不存在函数操作,不存在栈空间开辟,直接执行代码

  • 什么时候使用内联函数提高效率:1.代码体积小 2.频繁调用

  • 窥探内联函数本质:
    1.普通函数:进行汇编调试


2.内联函数:
还是有函数调用,debug模式是不会有内联优化的


3.变成release模式:
调试:直接调用
由于编译器优化 连 + 操作都没有了 直接出现了30 (1E)

4.为窥探内联:
release模式开启禁止优化:
内联函数扩展:




不加内联:


  • 内联函数和宏:


推荐使用内联函数:写代码的时候有语法检测和提示, 函数特性(传参)


表达式

  • C++有些表达式是可以被赋值的


Const

  • const是常量的意思,被其修饰的变量不可修改

如果修饰的是类,结构体(的指针),其成员也不可以更改

  • 下面五个指针分别是什么含义:


p3:


p1,p2:


p4,p5:


const修饰的是其右边的内容


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容

  • 学习C++的必要性 得益于它的高效性、稳定性、跨平台性,所以应用范围广泛; 是很多语言的老祖宗,理解C++相当理解...
    Stago阅读 194评论 0 0
  • C、C++、数据结构 1、编译系统的四个步骤: 预处理,编译,汇编,链接 2、整型和长整型的区别? 早期的计算机,...
    飞扬code阅读 1,703评论 0 20
  • 写在前面: 犹豫了一下,不知道该不该发这么多。毕竟题目虽全,但是其实很多人看了不到一半,估计就会默默的收藏保存,等...
    Yt_cc阅读 14,633评论 1 6
  • 汇编与机器代码一一对应,但是汇编代码却与高级语言不是一一对应的。 上述为两串代码所对应的机器代码和汇编语言,从其中...
    空城难入_d569阅读 135评论 0 0
  • 搬运自牛客网大神总结 extern关键字 extern修饰变量是个声明,此变量/函数是在别处定义的,要在此处引用 ...
    leon4ever阅读 3,647评论 0 9