(一)引用与指针区别 宏 内联函数 const

目录

值和引用的作为返回值类型的性能比较

引用 与 指针的转化

// 宏常量的优势// 1、可以达到一次性一改全改的效果,提高了程序的复用性// 2、可以提高程序的可读性

缺点:1.不方便调试宏。(因为预编译阶段进行了替换)(报错位置不准确)2.导致代码可读性差,可维护性差,容易误用。3.没有类型安全的检查 。​编辑

 因为宏常量有缺陷,我们在c++的时候用const常量对宏进行了取代

小结:

2、const常量的替换发生在编译阶段

 在所有读取a常量中内容的位置,比如打印常量 都会使用使用常量本身替换

内联函数


值和引用的作为返回值类型的性能比较

这里我们创建了三个函数 分别对传值 传指针 传引用,做以比较

代码如下 :

#include<time.h>
struct SeqList
{
	int array[10000];
	int size;
};

void TestValue(SeqList s)
{}

void TestPtr(SeqList* ps)
{}

void TestRef(SeqList& s)
{}

void TestTime(int n)
{
	SeqList s;
	size_t beginVal = clock();
	for (int i = 0; i < n; i++)
	{
		TestValue(s);
	}
	size_t endVal = clock();
	cout << "  TestValue :" << endVal - beginVal;

	size_t beginPtr = clock();
	for (int i = 0; i < n; i++)
	{
		TestPtr(&s);
	}
	size_t endPtr = clock();
	cout << "  TestPtr :" << endPtr - beginPtr;

	size_t beginRef = clock();
	for (int i = 0; i < n; i++)
	{
		TestRef(s);
	}
	size_t endRef = clock();
	cout << "  TestRef :" << endRef - beginRef << endl;
}

int main()
{
	for (int i = 0; i < 10; i++)
	{
		TestTime(1000000);
	}
	return 0;
}

 结果如下:

我们可以看到值传递与指针和引用传值效率上有很大的差异,在传值的方式体现上,我们必须对实参进行一份拷贝,如果实参非常大,那么拷贝所需要的时间和空间也会是比较大的。

传地址和传指针的效率上差不多

但是传引用更安全,代码可读性更高。

 引用初识:引用只是对变量的别名,编译器不会给引用变量重新开辟内存空间,引用与其引用的实体共用一份内存空间

发现:引用实际是有空间的,空间中放的是其引用实体的地址

语法概念:引用就是别名。编译器不会给引用变量开辟空间-->这样方便用户理解

底层实现:要实现引用的技术,底层又把引用换成指针---引用是语法层面的概念。在底层实际没有引用的概念。

指针通过某个指针变量指向一个对象后,对它所指向的变量间接操作。程序中使用指针,程序的可读性差;而引用本身就是目标变量的别名,对引用的操作就是对目标变量的操作

引用 与 指针的转化

定义了int* const cpaa; 在定义时就必须进行初始化,因为指针cpaa的指向在后面将无法修改。

 1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
2. 引用在定义时必须初始化,指针没有要求
3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
4. 没有NULL引用,但有NULL指针
5. 在sizeof中含义不同引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(程序按32位编译环境下编译出来时占4个字节,按64位编译环境编译下来时占8个字节)

	char ch = 'A';
	char& rc = ch;
	char* pc = &ch;

	cout << sizeof(rc) << endl; // 结果为1
	cout << sizeof(pc) << endl; // 结果为4 


6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
7. 有多级指针,但是没有多级引用


8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理

指针需要用户自己解引用,引用在底层都被编译器直接转化为指针的方式进行处理
9. 引用比指针使用起来相对更安全

 10.对NULL进行传递

// 宏常量的优势
// 1、可以达到一次性一改全改的效果,提高了程序的复用性
// 2、可以提高程序的可读性

#define MAXSIZE 100
#define PI 3.14
// 宏常量的优势
// 1、可以达到一次性一改全改的效果,提高了程序的可扩展性
// 2、可以提高程序的可读性

int main()
{
	int array[MAXSIZE];
	for (int i = 0; i < MAXSIZE; ++i)
	{
		array[i] = i * 10;
	}
	for (int i = 0; i < MAXSIZE; ++i)
	{
		cout << array[i] << " ";
	}
	cout << endl;

	double r = 2.0;
	cout << PI * r * r << endl;
	cout << 2 * PI * r << endl;
	return 0;
}

缺点:
1.不方便调试宏。(因为预编译阶段进行了替换)(报错位置不准确)
2.导致代码可读性差,可维护性差,容易误用。
3.没有类型安全的检查 。

 因为宏常量有缺陷,我们在c++的时候用const常量对宏进行了取代

// 注意:
    // 在C++中,被const修饰的变量不在是变量,而是一个常量
    // 在C语言中,被const修饰的变量是一个不能被修改的变量

int array[MAXSIZE];
	const int num = 100;
	scanf_s("%d", &num);						//输入 5
	int b[num];
	cout << sizeof(b) / sizeof(b[0]) << endl;	//输出100
	
	const int n = 100;
	int a[n];

小结:

1、宏常量的替换发生在预处理阶段

2、const常量的替换发生在编译阶段

 在所有读取a常量中内容的位置,比如打印常量 都会使用使用常量本身替换

int main()
{
	const int a = 10;

	int* pa = (int*)&a;
	*pa = 100;

	cout << a << " " << *pa << endl;
	cout << 10 << " " << *pa << endl;
}

宏函数

 

// 宏函数

// 优点:在预处理阶段会展开,(展开:就是用宏体替换宏使用的位置)少了函数调用的开销

// 缺陷:

// 1. 不会进行类型检测

// 2. 不能调试

// 3. 有副作用

// 4. 会造成代码膨胀

#define Add(x,y) (x)*(y)

#define MAX(x,y) (x)>(y)?(x):(y)

int main()

{

cout << Add(1, 2) << endl;

//cout << Add(1, "2") << endl;

cout << Add(1 + 2, 2 + 3) << endl; // (1+2)*(2+3)

int a = 20;

int b = 10;

int ret = MAX(++a, b); // (++a)>(b)?(++a):(b) ++a被执行了俩次

return 0;

}

内联函数

1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用

缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。
2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。


3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数入口地址了,链接就会找不到。inline函数要再当前文件里面展开并使用。(链接报错)

inline int Add(int x, int y)
{
	return x + y;
}
int main()
{
	int a = 10;
	int b = 20;
	int ret = Add(a, b);
	printf("%d\n", ret);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值