赞
踩
欢迎来到Harper·Lee的学习笔记!
博主主页传送门:Harper·Lee博客主页!
欢迎交流学习!
内联函数:用** inline 修饰的函数叫做内联函数,编译时C++编译器会在调用的地方展开内联函数**,这样调用内联函数就需要创建栈桢,就提高效率了。
主要目的就是为了替代C语言中的宏。先回顾一下什么是宏:
#include<iostream>
using namespace std;
//right
#define ADD(x,y) ((x)+(y))//括起来
int main()
{
int ret = ADD(1,2);//替换后:int ret = ((1)+(2));
cout << ADD(1,2) << endl;
return 0;
}
#include<iostream>
using namespace std;
//如果加了分号
#define ADD(x,y) ((x)+(y));
int main()
{
int ret = ADD(1,2);//替换后:int ret = ((1)+(2));
cout << ADD(1,2); << endl;//error
return 0;
}
C语言中宏的缺点:
//right
#define ADD(x,y) ((x)+(y))//括起来
int main()
{
int ret = ADD(1,2);//替换后:int ret = ((1)+(2));
return 0;
}
//error
#define ADD(x,y) (x+y)
#define ADD(x,y) (x)+(y)
#define ADD(x,y) (x+y)
#define ADD(x,y) ((x)+(y));//不能加分号
#define ADD(int x,int y) return x+y;//不能加分号;
根据上面的回顾可知,宏的问题缺陷很多,因此C++将它改进为一种函数——内联函数。
C语言实现宏函数时,也会在预处理是替换展开,但是宏函数实现很复杂很容易出错,而且不方便调试,C++设计实现 inline 的目的就是替代C的宏函数。
#include<iostream>
using namespace std;
inline int Add(int a, int b)
{
int ret = a + b;
return ret;
}
int main()
{
int ret = Add(1, 2);
cout << Add(1, 2) * 5 << endl;
cout << ret << endl;
return 0;
}
a.
b.
// F.h #include <iostream> using namespace std; inline void f(int i);//声明 // F.cpp #include "F.h" void f(int i)//定义 { cout << i << endl; } // main.cpp #include "F.h" int main() { // 链接错误:⽆法解析的外部符号 f(10);//链接:但是.h文件中函数的声明被inline修饰了,就没有函数地址 return 0; }
NULL实际上是一个宏NULL,在传统C语言文件stddef.h中,可以看到如下代码:
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
由上面的代码可以看出,NULL可能被定义为是字面常量0,或者被定义为是无类型指针(void)的常量。这两种定义在使用空值指针时,就会出现歧义。比如下面:*
#include<iostream> using namespace std; void f(int x) { cout << "f(int x)" << endl; } void f(int* ptr) { cout << "f(int* ptr)" << endl; } int main() { f(0); // 本想通过f(NULL)调⽤指针版本的f(int*)函数,但是由于NULL被定义成0,调⽤了f(intx),因此与程序的初衷相悖。 f(NULL); f((int*)NULL);//NULL写成0也可以 // f((void*)NULL);//强转成void*,编译报错:error C2665: “f”: 2 个重载中没有⼀个可以转换所有参数类型 f(nullptr); return 0; }
运行结果:
根据运行结果可知,NULL被定义为0,就没有调用指针版本的 f(int*) 函数。
为了解决这个问题,C++11中引入了一个特殊的关键字——nullptr,这样就可以调用该函数了。
nullptr有以下几个特点:
int* p1 = nullptr; //right
int i = nullptr; //error
上面的例子代码中,f(void*) NULL;会报错,报错原因分析:C语言中 void 指针是一个垃圾桶,什么类型的指针都可以接受;C++中 void 指针需要进行强制类型转换。**
//test.c
void* p1 = NULL; //p1表示空指针
void* p2 = p1; //right,不用强转
//test.cpp
void* p3 = NULL;
int* p4 = p3; //error
int* p5 = (int*)p3;//right,需要强转
喜欢的uu记得三连支持一下哦!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。