函数重载,引用,内联函数,c++新关键字

函数重载的概念是指形参类型不同,个数不同,参数不同

c语言为什么不支持重载?c++为什么支持呢

首先c++的编译过程和c语言是一样的,会生成一个汇编代码

test.cpp中预处理首先是头文件展开,宏替换,去掉注释,条件编译

test.i中编译先检查语法,生成汇编代码(指令级别的代码)

test.s表示生成汇编代码,将汇编代码生成机器码

test.o表示链接 合并链接,生成可以执行程序

test.out//xxx.exe

只有声明没有定义就可能找不到,c语言直接用函数名去,c++用的修饰名

首先编译器里面有一个叫符号表的东西去存储函数名,本质是同样的函数名转换成两句指令,如果类型不同修饰出来的名不同,

返回值不同也不能构成函数重载,先不谈编译能否通过,在符号表翻译成的代码就不一样,名字不一样自然不能构成函数重载了

引用

引用实际就是给一个已经定义的变量取别名,使用&去引用,并不开辟额外的空间,从  汇编层来看引用就是指针     

#include<iostream>
using namespace std;

int main() {

	int a = 1;
	int& b = a;
	cout << &a << endl;
	cout << &b << endl;
}

在传参中的意义非常重要

交换

void swap(int& a, int& b) {
	int tmp = a;
	a = b;
	b = a;
}

单链表中的引用

链表为空的情况下如果没有使用引用的话,需要取地址然后传二级指针取地址

#include<iostream>
using namespace std;

typedef struct ListNode {
	int val;
	struct ListNode* next;
}ListNode;

ListNode* initNode(int val) {
	ListNode* phead = (ListNode*)malloc(sizeof(ListNode));
	phead->next = NULL;
	phead->val = val;
	return phead;
}
void PushBack(ListNode** phead,int x) {
	ListNode* newnode = initNode(x);
	if (*phead == NULL) {
		*phead = newnode;
	}
	else {
		ListNode* tail=*phead;
		while (tail->next!=NULL) {
				tail = tail->next;
		}
		tail->next = newnode;

	}
}
int main() {
	ListNode* plist = NULL;
	PushBack(&plist, 1);
	PushBack(&plist, 2);
	PushBack(&plist, 3);
	ListNode* phead = plist;
	while (phead!=NULL) {
		cout << phead->val << endl;
		phead = phead->next;
	}

	
}

在使用了引用的情况下,相当于给原链表娶了给别名,不需要取地址了,看上去更加简单

#include<iostream>
using namespace std;

typedef struct ListNode {
	int val;
	struct ListNode* next;
}ListNode;

ListNode* initNode(int val) {
	ListNode* phead = (ListNode*)malloc(sizeof(ListNode));
	phead->next = NULL;
	phead->val = val;
	return phead;
}
void PushBack(ListNode*& phead,int x) {
	ListNode* newnode = initNode(x);
	if (phead == NULL) {
		phead = newnode;
	}
	else {
		ListNode* tail=phead;
		while (tail->next!=NULL) {
				tail = tail->next;
		}
		tail->next = newnode;

	}
}
int main() {
	ListNode* plist = NULL;
	PushBack(plist, 1);
	PushBack(plist, 2);
	PushBack(plist, 3);
	ListNode* phead = plist;
	while (phead!=NULL) {
		cout << phead->val << endl;
		phead = phead->next;
	}

	
}

 在结构体定义的时候,我们也可以定义了一个*PListNode的指针直接引用到函数内

#include<iostream>
using namespace std;

typedef struct ListNode {
	int val;
	struct ListNode* next;
}ListNode,*PListNode;

ListNode* initNode(int val) {
	ListNode* phead = (ListNode*)malloc(sizeof(ListNode));
	phead->next = NULL;
	phead->val = val;
	return phead;
}
void PushBack(PListNode& phead,int x) {
	ListNode* newnode = initNode(x);
	if (phead == NULL) {
		phead = newnode;
	}
	else {
		ListNode* tail=phead;
		while (tail->next!=NULL) {
				tail = tail->next;
		}
		tail->next = newnode;

	}
}
int main() {
	ListNode* plist = NULL;
	PushBack(plist, 1);
	PushBack(plist, 2);
	PushBack(plist, 3);
	ListNode* phead = plist;
	while (phead!=NULL) {
		cout << phead->val << endl;
		phead = phead->next;
	}

传引用返回传的是n的别名,返回局部变量或者临时变量的地址,销毁后是返回的野指针,可能会置随机值,也可能值会不变

此时打印的是1,1,1

int& count() {
	int a[1000];
	int n = 0;
	return n;
}
int test() {
	int a[1000];
	int n = 1;

	return n;
}
int main() {
	int& ret = count();
	test();
	cout << ret << endl; 
	cout << ret << endl;
	cout << ret << endl;
	
	
}

什么时候传引用返回?

全局对象or静态对象or堆上动态,出了作用域还在,提高效率,

coust引用

权限不能放大,但可以缩小和平移

int main() {
	
	const int x = 0;
	int& b = x;//权限的放大

	const int& c = x;//权限的平移

	int y = 0;
	const int& d = y;//权限的缩小
	
}
int main() {
	
	double x = 1.1;
	 const int& b = x;//权限的放大
	cout << b << endl;//结果为1

	
}

宏函数

宏的缺点是什么?一种叫宏常量,一种叫宏函数,宏的优点是替换强,

宏函数

缺点:1是容易出错,语法坑多

           2不能调试

           3没有类型安全的检查

优点:1没有类型的严格限制

           2针对小函数频繁调用,不用再建立栈帧

#define ADD(X,Y) ((X)+(Y))//不能不加括号(a|b+b&a)优先级会有问题
int main() {
	
	int x=ADD(1, 2);
	cout << x << endl;

}

内联函数inline

1、在调用的地方直接展开,不用建立栈帧

2、但是内联函数不能大量嵌套递归 直接展开系统会判定会不会为内联函数,假设100行的代码递归100次总共10000行,而普通函数只需要200行,一般10行左右可以内联函数展开

3、内联函数不能声明定义分离(不能分布在两个文件中)

inline int	ADD(int x, int y) {
	return x + y;
}
int main() {
	
	int x=ADD(1, 2);
	cout << x << endl;

}

 关键字

auto

	int a = 0;
	auto b = a;//自动转换为int
	auto c = &a;//自动转换为指针

注:auto不能作为函数的参数和定义数组

typeid.name()

cout << endl;
	cout <<typeid(a).name() << endl;

for新规则

基于范围自动迭代

int arry[] = { 1.2,4,5 };
for (auto e : arry) {
		cout << e << " ";
	}
	cout << endl;
	for (auto& e : arry) {//不加引用代表的就是e不代表数组里的值
		e *= 2;
	}
	for (auto e : arry) {
		cout << e << " ";
	}

不能在函数中形参使用指针的情况下使用auto

int fun(int array[]) {
	for (auto e : arry) {
		cout << e << " ";
	}
}

nullptr

c++语法设计缺陷

NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:

#ifndef NULL
#ifdef __cplusplus
#define NULL  0
#else
#define NULL  ((void *)0)
#endif
#endif

void fun(int n) {
	cout << "f(int)" << endl;
}
void fun(int* n) {
	cout << "f*(int)" << endl;
}
int main() {
	
	fun(0);//f(int)
	fun(NULL);//f(int)
	fun(((int*) NULL));//f*(int)
	fun(nullptr);//f*(int)
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值