C/C++的区别
1,函数值的默认值
2,函数重载
3,inline函数
4,C和C++的相互调用
5,引用
6,const
7,new/delete
8,namespace
一,函数值的默认值
int Sum(int a,int b,int c)
{
return a+b+c;
}
int Sum(int a,int b)
{
return a+b+10;
}
1,C的函数符号生成规则——函数名(重复)
#include<iostream>
int Sum(int a,int b,int c=10)
{
cout << “c:" << c<<endl;
return a+b+c;
}
int main()
{
Sum(10,20);//没有实参,形参有默认值
Sum(10,20,30);//有实参,也有默认值
return 0;
}
函数默认值(形参有默认值无实参——>默认值)
没有实参,形参有默认值
有实参,形参也有默认值
(实参和形参匹配顺序自左向右)
默认值赋予规则:
1,函数的默认值赋予必须自右向左赋予(最右边的形参没有默认值时,前面不能有默认值)
2,默认值不能重复赋予
3,一般默认值加在声明上
二,函数重载
1,两个数求和(和类型无关)
a,C语言泛型,void*(不安全)
b,预定义函数(不安全)
bool Sum(int a,int b)
bool Sum(double a,double b)
bool Sum(char* a,char* b)
C++支持函数重载,C语言不支持函数重载
函数重载:
1,是一种同名函数的关系
2,函数返回值不能为函数重载提供支持
函数的重载是根据函数的参数不同(只和参数有关)
1,函数符号生成规则与函数重载有关:
C:
函数名相关
C++
函数原型
函数原型
函数值的返回值 函数名 (函数的形式参数数列表)
{
}
2,C++的函数符号规则
3,函数的参数列表不同
1,参数顺序不同
2,参数个数不同
3,参数不同
bool Compare(int,double );
bool Compare(double,int )
int main()
{
Compare(10,20.1);
Compare(20.1,32);
return 0;
}
函数重载的三要素:
1,同名
2,不同参
3,同作用域(例:main函数里面和全局作用域不同)
三, inline函数 内联函数
作用:函数调用点直接代码展开
①,inline函数和宏的区别?
----->inline函数在编译阶段,类型检查和安全检查
宏在预编译阶段,是文本替换,没有检查,所以inline更安全
②,inline函数和普通函数的区别
------>inline没有开栈和清栈的开销
普通函数有开栈和清栈的开销
③inline函数和static修饰的函数的区别
------->inline将函数体放在符号表中,不生成函数符号
static 开栈清栈的开销 将g换成l,只有局部可见
④为什么不把所有函数都设置为内联函数?
缺陷:代码膨胀为代价,目标代码的指令冗杂,重复,
总结
1,堆栈的开销 >函数执行的开销 ----函数体小-----建议设为内联
2,堆栈的开销<函数执行的开销-----函数体较大------不建议设为内联
inline函数的注意事项
普通函数:
-------函数声明 .h
-------函数定义 ,c/.cpp
-------函数调用 .c/.cpp
1,定义 .h文件
2,只在release版本生效
3,给编译器的一个建议 ( 循环 ,递归不处理成内联)
4,内联是基于实现的,不是基于声明的(内联要加载到定义点)
四, C和C++相互调用
项目------>c/.cpp
1,C的代码以C++规则处理
2,C++的代码以C规则处理
应该选第二种(扩好扩,不好缩)
方法一:extern “C”(允许修改代码时)
方法二:加一个中间层(不允许修改代码)
(计算机任何问题都可以用加一个中间层来解决-----程序员的自我修养)
文本文件:
1,C编译器编译 C规则
2,C++编译器编译 C++规则
1,文件 .c
无extern“C”(不应该出现extern)
C编译器中没有_cplusplus这个宏
2,文件 .cpp
有extern“C”
C++编译器一定有_cplusplus这个宏
判断是否有_cplusplus
#ifdef __cplusplus
extern "C"
{
#endif
int Sum(int a,int b)
{
return 0;
)
#ifdef __cplusplus
}
#endif
总结;
1,C++调用C语言:将extern “C”
2,C调用C++语言:
①extern “C”(允许修改)
②加中间层(不允许修改)
③文本编译 ------C调用C++ ----- 用_cplusplus宏解决
五,引用
void Swap(int *a,int *b)
{
int tmp=*a;
*a=*b;
*b=tmp;
}
int main()
{
int a=10;
int b=20;
Swap(&a,&b);//实参传递(有歧义)
cout << "a:" << a <<endl;
cout << "b:" << b <<endl;
return 0;
}
void Swap(int& a,int& b)
{
int tmp=*a;
*a=*b;
*b=tmp;
}
int main()
{
int a=10;
int b=20;
Swap(&a,&b);//实参传递(有歧义)
cout << "a:" << a <<endl;
cout << "b:" << b <<endl;
return 0;
}
引用符:&
引用-------别名
底层是指针处理,是对引用做处理支撑
形参和实参指向同一个内存单元,因此可以修改实参的值
底层:
b有自己的内存单元,是以指针方式来处理
使用引用变量,系统自带解引用的过程
特点:
1,一定要初始化
2,不能引用不能取地址的数据
3,别名被用,不能改变
4,引用变量,只能访问其引用的变量,不能访问它本身的
int main()
{
int a;
int &b=a;
b=10;
return 0;
}
六,const(C++的语法)
C
const修饰的量为常变量
常变量----编译阶段------查看常变量是否做左值
是------error
否——其他处理和变量相同
C++
const修饰的量为常量
常量-----编译阶段-------(用常量的地方替换成常量初始值的值)
常量特点:
①一定要初始化
②不允许修改
a,直接访问(a=20)
b,不允许间接访问(不允许指针指向)—杜绝间接修改常量的风险
const int a;
int*p=&a;//const int*p=&a;
int*q=p;//const int*q=p;
/*
直接访问:a
间接访问:*p *q
*/
int a=10;
const int* p=&a;
int*q =p;//const int*q=p;
/*
直接访问:*p a
间接访问:*p *q
*/
int a=10;
int *p=&a;
const int*q=p;//出现const,从这个点看
/*
const *q a
直接访问:*q a
间接访问:*q*
*/
const和引用的结合
&不参与类型
指针转引用:( int& b=a;-------->int* b= &a;)
const int a=10;
int& b=a;//const int& b=a;
常引用的优化策略:
常引用能引用不能取地址的数据
不能取地址的数据放在临时量
常引用引用该临时量
const int& c=10;//正确
const int* c=&10;//错误
七,new/delete(malloc/free)
malloc
void* malloc(size_t size);//viod*
void*[)
1,返回值类型不安全
int main()
{
int* p = (int*)malloc(sizeof(int));
*p = 20;
free(p);
return 0;
}
C++(new/delete)
int main()
{
int* p=new int;
*p =20;
delete p;
return 0;
}
1,new动态开辟
----------不仅可以开辟内存,还能初始化
2,new动态开辟数组
---------new[]----->可以零初始化
3,new内存开辟失败
--------抛出异常,异常处理机制
4,new开辟常量内存块
5,new开辟的内存位置
-------自由存储区
int main()
{
//动态开辟内存
int *p = new int(10);//赋值并初始化
cout << *p << endl;
//动态开辟数组
//一维数组
int*p = (int*)malloc(sizeof(int)*20);//数组
free(p);
int *q =new int [20]();//数组,零初始化
delete[] q;
//二维数组
int**p =(int**)malloc(sizeof(int*)*10);
for(int i =0;i<10;i++)
{
p[I] =(int*)malloc(sizeof(int)*10);
}
int** q =new int*[10]();
for(int i =0;i<10;i++)
{
p[I] =(int*)malloc(sizeof(int)*10);
}
//开辟常量内存
const int* p = new const int(10);
delete p;
//重定位new
int a;
char* pb =new (&a) char('a');//大的内存中获取内存单元供其他变量使用
return 0;
}
new和malloc的区别
1,new是关键字,malloc是函数
2,new 返回值类型安全,malloc返回值类型不安全
3.new系统计算机开辟的大小,malloc程序人员计算
4,new能做初始化,malloc只能开辟内存
5,new[]开辟数组
6,内存开辟失败
new抛出异常,malloc 返回值NULL
7,new开辟常量内存
8,存储位置
new自由存储区,malloc在堆
namespace
C
全局作用域,局部作用域
C++
namespace 名字空间作用域(解决C语言命名冲突问题)
class
namespace Sa
int Sum(int a,int b)
{
return a+b;
}
int a+b;
}
int main()
{
Sa::a;
Sa::Sum(10,20);
using Sa::a;//using声明(将a暴露在using声明当前所在的作用域)
//名字作用域中所用成员都暴漏在当前using指示符所在的作用域
using namespace Sa;
int b=a;
Sum(10,20);
using namespace std;//std,C++的标准名字作用域
std::cout << "hello world!" << std :: endl;
return 0;
}
同名名字作用域--------合并
总结
1,函数的默认值
2,函数重载(重点)
3,inline(中等)
4,C和C++的调用
5,引用(重重点)
6,const(重点)
7,new/delete
主要是new/malloc(重点)
8,namespace