目录
关键字
命名空间
使用命名空间的目的是对标识符的名称进行本地化, 以避免命名冲突或名字污染。
命名空间定义
namespace hello
{
int a = 0;
struct node
{
int val;
struct node* next;
};
namespace world//嵌套定义
{
int b = 0;
struct Node
{
int val;
struct Node* next;
};
}
}
命名空间使用
1.加命名空间名称及作用域限定符
//1.加命名空间名称及作用域限定符
int main()
{
printf("%d ", hello::a);
printf("%d ", hello::world::b);
}
2.使用using将命名空间中某个成员引入
//2.使用using将命名空间中某个成员引入
using hello::a;
int main()
{
printf("%d ",a);
printf("%d ", hello::world::b);
}
3.使用using展开整个命名空间
//3.使用using展开整个命名空间
using namespace hello;
using namespace world;
int main()
{
printf("%d ", a);
printf("%d", b);
}
注:直接展开整个命名空间会失去原有隔离功能。
C++输入&输出
std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中。
cout输出流 打印到屏幕
cin输入流 从屏幕输入数据
endl;\n换行cout和cin输出输入流可以自动识别类型!
include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
cout<<"Hello world!"<<endl;
int a;
double b;
char c;
// 可以自动识别变量的类型
cin>>a;
cin>>b>>c;
cout<<a<<endl;
cout<<b<<" "<<c<<endl;
return 0;
}
缺省参数
要点:1.从右往左 2.连续! 3.头文件和源文件只能出现一次缺省参数 4.c语言不支持
缺省参数本质就是默认值,若不传参,则默认值担当实参。
若传参,则覆盖默认值!
所有参数均为缺省参数 则成为全缺省,否则为半缺省。
int add1(int x=20, int y = 40)//全缺省
{
return x + y;
}
int add2(int x, int y = 40)//半缺省
{
return x + y;
}
int main()
{
printf("%d", add1());//60
printf("%d", add2(10));//50
}
函数重载
函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数。
构成重载三个条件!1.参数类型不同 2.参数个数不同 3.参数顺序不同
注意:函数重载与返回值无关
//1.参数类型不同
int add(int x , int y)
{
return x + y;
}
double add(double x, double y)
{
return x + y;
}
//2.参数个数不同
int add(int x, int y)
{
return x + y;
}
int add(int x,int y,int z)
{
return x + y + z;
}
//3.参数顺序不同
void print(int x, char y)
{
cout << x << ' ' << y << endl;
}
void print(char y,int x)
{
cout << y << ' ' << x << endl;
}
注:c语言不支持函数重载,因为c语言同名函数没办法区分.
而c++函数命名规则:_Z+函数名长度+函数名+类型名,防止函数重名!
引用
引用相当于起别名,对引用的操作就是对实体的操作!
引用规则:1.引用要初始化 2.一个变量可以有多个引用 3.引用一个实体后,无法引用其他实体。
常引用
常量不能被更改,若被引用,要加const修饰。
void test()
{
const int a = 10;
//int& ra = a; // 该语句编译时会出错,a为常量
const int& ra = a;
// int& b = 10; // 该语句编译时会出错,b为常量
const int& b = 10;
double d = 12.34;
//int& rd = d; // 该语句编译时会出错,类型不同
const int& rd = d;
//为什么这里成功了?
// 因为double类型的d赋给int型rd要发生隐式类型转换
//这当中要生成临时变量,本质是临时变量值赋给rd
//而临时变量具有常量性,无法被更改!所以加const就能成功!
}
传参
void swap(int x, int y)//传值调用
{
int tmp = x;
x = y;
y = tmp;
}
void swap(int* x, int* y)//传址调用
{
int tmp = *x;
*x = *y;
*y = tmp;
}
//传值和引用构成函数重载,但是!无法根据实参判断到底调用哪个,所以运行会报错
//相当于:void f(); void f(int x=10);若传空值,则调用不明确
void swap(int& x, int& y)//引用
{
int tmp = x;
x = y;
y = tmp;
}
传返回值
传返回值一定不能传临时变量 !会造成非法访问!引用传返回值一定要选择静态变量。
下面介绍错误案例:
//传返回值
int& add(int x, int y)
{
int c = x + y;
return c;
}
int main()
{
int& ret = add(10, 20);
add(20, 40);
printf("%d", ret);
//输出60
}
因为ret是临时变量c的别名,当add函数执行完毕后,add函数栈帧销毁,变量c的空间也被销毁, 第二次执行add,在原来位置再次建立栈帧,变量c值改变,ret也改变。
内联函数
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调 用建立栈帧的开销,内联函数提升程序运行的效率。
宏的优缺点? 优点: 1.增强代码的复用性。 2.提高性能。 缺点: 1.不方便调试宏。(因为预编译阶段进行了替换) 2.导致代码可读性差,可维护性差,容易误用。 3.没有类型安全的检查 。
内联函数与宏相比,解决了宏的缺点,又具有提高性能的效用。
1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会 用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运 行效率。
2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建 议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不 是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。
3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址 了,链接就会找不到。
inline int add(int x, int y)
{
return x + y;
}
int main()
{
int c = add(1, 2);
printf("%d", c);
}
未内联:
内联后: