C++发展史
1.命名空间
#include <iostream>
int main()
{
std::cout << "123" << std::endl;
return 0;
}
作用:对标识符的名称进行本地化,防止命名冲突和命名污染,因此C++中可以有重名变量
使用:using A:Add using namespace A; 使用A命名空间
一般情况下,不会展开命名空间,只会用A::Add这种形式
例如:
namespace A
{
int a;
int Add(int x, int y);
}
2.输入和输出
说明:(1)使用cout和cin时,必须包<iostream>头文件和std命名空间
(2)编译器可自动识别输出类型,不用"%s","%c"等等
int main()
{
int a;
double b;
std::cin >> a >> b;
std::cout << a << "-" << b << std::endl;
}
3.缺省参数
定义:在声明函数时为函数参数指定一个默认值。在函数调用时,如果没有指定对应参数,则使用默认值
void Test(int a = 0)
{
std::cout << a << std::endl;
}
int main()
{
Test(); //没有传参,a为0Test(10); //传参了,a为10
}
注意:
(1)半缺省参数必须从右往左依次给出,不能间隔着给,因为调用的时候,(函数传参依次从左到右赋值)
void test(int a, int b = 20, int c = 30); 这样合法
void test(int a = 10, int b = 20, int c); 这样不合法
(2)缺省值必须是全局变量和常量
(3)C语言编译器不支持
4.函数重载
C++允许在同一个作用域里面声明几个同名函数,这些同名函数的形参列表必须不同
int Add(int x, int y);
double Add(double x, double y);
编译器可根据不同的参数类型或个数,调用对应的函数可以在函数前面加extern "C"
int Add(int x,int y); 意思是告诉编译器按照C的风格来编译该函数
5.引用
就是给一个已经存在的变量取一个别名,它和它引用的变量共用一块内存空间
特性:(1)在定义的时候必须初始化
(2)一个变量可以有多个引用
(3)引用一旦引用一个实体,就不能再引用其他实体
const int a = 10;
int& ra = a; //限定符丢弃,不行
const int& ra = a;
int& b = 10; //b会被改变,不能赋常量
const int& b = 10; //b不能被改变,因此可以赋常量
double d = 12.8;
const int& rd = d; //rd不会被改变,因此可以编译通过
使用场景:
(1)做参数,就相当于操作实参
void swap(int& x, int& y)
swap(a, b);
(2)做返回值
如果函数返回时,出了函数作用域,引用的对象已经不存在了,就不能返回对象的引用。
否则会出现非法访问问题。反之,就可以。
int& T1(int& a)
{
a += 10;return a;
}
分析:正确!a本来就是一个实参的引用,函数调用完后,a没了,但函数内部就相当于在操作实参。
int& Add(int a, int b)
{
int c = a + b;
return c;
}
分析:错误!函数一旦调完了,c就没了,c的引用当然也就不存在了
引用和指针的区别:
(1)引用在定义的时必须初始化,指针没有要求
(2)引用只能引用一个实体,指针可以在任何时候指向任何一个同类型的实体
(3)没有NULL引用,但有NULL指针
(4)在sizeof下引用结果为引用类型的大小,但指针始终是4个字节
(5)引用自加1,就是引用实体加1,指针自加1,即指针向后偏移一个类型的大小
(6)指针需要显示解引用,引用是编译器自己处理
(7)引用比指针更安全
注意:在底层,引用其实是按照指针的方式实现的
6.内联函数
以inline修饰的函数叫内联函数。
1.在编译期间编译器会用函数体替换函数的调用,没有函数的压栈开销,提高程序的运行效率。
2.代码很长的或有循环/递归的函数不适宜用内联函数。
3.inline对于编译器而言只是一个建议,编译器会自动优化。