C++基础知识点(一)

**************************原创,转载请标明出处。**********************************

目录

一、C与C++区别

1. 函数区别

1.2 inline与内联函数

1.3 函数重载

2 .c 与 .cpp 相互调用

3. 补充,符号

4. 问答:


一、C与C++区别

1. 函数区别

概念:在函数声明或者定义的时候,给参数一个默认值。调用该函数的时候,实参不传值,就会按照之前的默认值传参。(特点里的作用域指的是单文件,单文件是不包含.h的文件,就是单纯的cpp

特点一:函数参数的默认值,是在编译阶段生成指令的时候,直接生成入参指令

特点二:函数参数的默认值只能传递常量

void fun1(int a, int b, int c = 20)
{
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;
}
int main()
{
	fun1(12,23);

	return 0;
}

特点三:函数参数的默认值,只能从左向右依次赋值,不能反着也不能跳过

特点四:函数的默认值参数在同一作用域只能赋值一次,不能重复赋值。

void fun1(int a, int b, int c = 10);
void fun1(int a, int b, int c = 20)
{
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;
}
int main()
{
	fun1(12,23);

	return 0;
}  //报错:重定义默认参数

特点五:因为函数参数的默认值是在编译时期带入的,所以函数参数的默认值只在本文件有效(当申明和实现,默认值不一样,作用域则是本文件)

1.2 inline与内联函数

概念:realse版本里,调用内联函数时候,该函数会在调用点展开,展开的阶段是编译阶段。展开可以理解为这里没有开辟新的函数栈帧(没开辟空间),然后入参等调用该函数;而是直接用代码替换了这里的函数调用语句。(一种理解方式)
在debug版本,内联函数和正常函数调用方式一致。

特点一:由于内联函数在编译阶段展开,编译阶段无法获取变量的值,而递归函数的终止条件一定需要有变量参与,所以,递归函数不可能被处理成内联函数(什么函数不能被处理成内联函数?)

特点二:inline 只是对系统的建议,建议将该函数处理为内联。(具体根据编译器来确定,一般简短的代码可以处理成内联函数)

特点三:inline函数在debug版本生成的是local的符号。如果成功建议成内联,在release版本
将不生成符号,直接在调用点展开。

函数对比
宏函数  static函数  内联函数普通函数
展开的阶段预编译时期在调用点展开不展开debug版本不展开,release版本在调用点展开不展开
是否可以调试无法调试可以调试可以调试可以调试
安全校验没有类型安全校验有类型安全校验有类型安全校验有类型安全校验
开辟空间没有栈帧的开辟有栈帧开辟debug版本有栈帧开辟,release版本没有栈帧开辟有栈帧开辟
作用域单文件可见单文件可见单文件可见多文件可见
符号不生成符号

生成local的符号

debug版本生产local符号,release版本不生成符号生成global符号

1.3 函数重载

概念:函数名相同,参数列表不同(返回值类型无影响

特点一:C语言生成函数符号依赖函数名,C++产生函数符号依赖函数名和参数列表(返回值不受影响)

特点二:函数重载在编译时期决定调用哪个函数——静多态的一种

2 .c 与 .cpp 相互调用

C++调用C:  (下面都是没有引入头文件,在几个.cpp、.c之间使用) 

方法:  Extern关键字:使用c语言方式编译代码

.cpp文件:

extern "C"
{
	void fun_C()//fun_C
    {
	    printf("void fun_C()");
    }
}
//这里面也可以包含 .c的头文件
//extern "C" 
//{
//    #include "add.h"  // 由add.h和add.c组成
//}

main()
{
    //c++ 代码,调用上面函数
}

C调用C++:

方法: 需要一个中间的函数,衔接C++代码 到 C的调用

fun.cpp:

int fun_CPP(int a)//fun_CPP_void
{
	cout << "void fun_CPP()" << endl;
	return 0;
}
temp.cpp:

int fun_CPP(int a);//fun_CPP_int

extern "C"
{
	int fun_CPP_tmp(int a)//fun_CPP_tmp
	{
		return fun_CPP(a);//fun_CPP_int
	}
}
main.c:

int fun_CPP_tmp(int a);//fun_CPP_tmp

int main()
{
	int a = 10;
	fun_CPP_tmp(a);//fun_CPP_tmp

	return 0;
}

3. 补充,符号

概念:符号由数据指令组成。 数据:全局的变量,静态的变量。除了前面两个,其他的都叫指令。(比如调用函数的语句,就叫指令)。

特点一:所有的数据都会生成符号,指令中只有函数名会生成符号。

特点二:符号:全局符号(global)- 所有文件可见

                         局部符号(local)- 只有本文件可见

特点三: Inline函数在debug版本生成的是local符号,如果处理为内联之后在Release版本不生成符号,直接在调用点展开。

4. 问答:

为什么函数默认参数只能是常量?

函数默认参数的入参在编译阶段,编译时期可以得到常量的值,无法得到变量的值。所以函数默认参数只能是变量。

什么函数不能成为内联函数?

内联是在编译期间展开,编译生成指令。内联在这儿生成展开的指令,函数指令。递归不能内联,编译时期拿不到变量的值,运行才能时期拿到递归的终止条件是变量。

为什么内联函数release不生成符号?

因为在调试点展开了。

为什么内联函数debug生成的local符号?

因为需要调试,看该函数的代码是否正确,所以生成符号。   

又因为其本质是内联的,在编译期就要看到函数的定义(便于debug调试),所以它省去了und状态的函数声明符号寻找global函数定义符号这一步骤。所以它是local。即只在本文件有效。

函数的编译链接:

函数声明,在编译之后生成und状态的符号,und是未定义的意思。【编译阶段,生成可重定向文件】。

然后寻找全局global符号,即函数定义(函数实现)经过编译所生成的globa符号,进行链接。找到了,脱离und状态。没找到,报错,【链接阶段,生成可执行文件】

为什么static只在本文件有效?

因为他生成局部符号,局部符号(local)- 只有本文件可见。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值