C++基础知识点(一-基础概念)

目录

一、命名空间

1.1 命名空间的定义

1.2 使用命名空间的目的

1.3 命名空间的使用方法

二、C++输入和输出 

三、缺省参数 

3.1 缺省参数概念

3.2 缺省参数的分类

3. 注意事项

四、函数重载 

4.1 函数重载概念

五、引用 

5.1 引用的概念

5.2 引用的使用方法

 5.3 引用特性

5.4 引用的使用场景

5.5 引用和指针的不同点

5.6 引用的本质

六、内联函数

6.1 内联函数概念

6.2 内联函数特性

八、auto关键字

7.1 auto简介

7.2 auto的使用规则

九、范围for

9.1 范围for简介

2. 范围for的使用条件


一、命名空间

1.1 命名空间的定义

定义命名空间需要使用到namespace关键字,后面跟命名空间的名称,然后接一对{}即可,{}中即为命名空间的成员。

​namespace my_namespace
{
    int a = 0;
}

需要注意以下几点:

① 命名空间可以定义变量/函数/类型。

② 命名空间可以嵌套。

③ 同一个工程中允许存在多个相同名称的命名空间,编译器最后会自动合并成同一个命名空间。

1.2 使用命名空间的目的

对标识符的名称进行本地化,以避免命名冲突或名字污染。

1.3 命名空间的使用方法

1) 加命名空间名称及作用域限定符"::"

2) 使用using将命名空间中某个成员引入;using N::b;(局部展开)

3) 使用using namespace 命名空间名称引入;using namespace N;(完全展开)

using N::b
using namespace K         //K命名空间中有变量c,d
int main()
{
    printf("%d\n", N::a); //加命名空间名称::变量
    printf("%d\n", b);    //使用using将命名空间某个成员引入(局部展开)
    printf("%d\n", c);    //使用using namespace将命名空间引入(完全展开)
    printf("%d\n", d); 
    return 0;
}

二、C++输入和输出 

  • 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含<iostream>头文件以及按命名空间使用方法使用std。
  • coutcin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream>头文件中。

  • "<<"是流插入运算符,">>"是流提取运算符。

  • 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型。

  • coutcin分别是ostreamistream类型的对象。

#include <iostream>

using std::cout;
using std::endl;

int main()
{
    cout << "hello world!" << endl;
    return 0;
}

三、缺省参数 

3.1 缺省参数概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

#include <iostream>
using namespace std;

void Func(int a = 0)
{
    cout << a << endl;
}

int main()
{
    Func();          // 没有传参时,使用函数定义时参数默认值,a = 0
    Func(10);        // 传参时,使用指定的实参,a = 10
    return 0;
}

3.2 缺省参数的分类

1) 全缺省参数(所有参数都有缺省值)

void Func(int a = 10, int b = 20, int c = 30) 
{
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
}

2) 半缺省参数(部分参数有缺省值) 

void Func(int a, int b = 20, int c = 30) 
{
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
}

3. 注意事项

1) 半缺省参数必须从右往左依次给出缺省值,不能出现一个参数左边参数有缺省值而右边没有的情况。如void Func(int a = 10, int b, int c = 30);

2) 缺省参数不能在函数声明(.h)定义(.cpp)中同时出现。

3) 缺省值必须是常量或则全局变量

4) C语言不支持缺省参数

四、函数重载 

4.1 函数重载概念

C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数类型类型顺序)不同,常用来处理实现功能类型数据类型不同的问题。注意:函数重载与函数返回值相不相同没有任何关系!!!

#include <iostream>
using namespace std;

// 以下函数都构成函数重载
int Func(int a, double b){}        // 参照函数
double Func(double a, double b){}  // 参数类型不同
char Func(int a){}                 // 参数个数不同
int Func(double a, int b){}        // 参数顺序不同

int main()
{
    int a = Func(1, 1.2);          // 调用int Func(int a, double b)函数
    int b = Func(1.2, 1);          // 调用int Func(double a, int b)函数
    char c = Func(3);              // 调用char Func(int a)函数
}

五、引用 

5.1 引用的概念

引用不是新定义一个变量,而是给已存在的变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它的引用变量共用同一块内存空间。 

5.2 引用的使用方法

类型& 引用变量名 = 引用实体;注意:引用类型必须和引用实体同种类型

void TestRef()
{
    int a = 10;
    int& ra = a;           // 定义引用类型
    printf("%p\n", &a);    // 打印出来a与ra的地址是相同的
    printf("%p\n", &ra);
}

 5.3 引用特性

1) 引用变量在定义式必须初始化

2) 一个变量可以有多个引用。

3) 引用变量一旦引用一个实体,不能再引用其他实体

4) 引用变量在引用常量时必须带const

void TestRef()
{
    int a = 10;
    const int b = 10;
    int c = 30;
    // int& ra;            定义是未初始化,编译器报错         
    int& ra = a;
    //ra = c;              已经引用过不能再引用其他实体
    int& rra = a;       // 一个变量可以有多个引用 
    const int& rb = b;  // 引用常量时需要加const
    const int& rc = 10; // 引用常量时需要加const    
}

5.4 引用的使用场景

1) 做参数:输出型参数,大对象传参,提高效率。

2) 做返回值:输出型返回对象,调用者可以修改返回对象。注意:在使用引用返回时,返回对象不能是临时变量的引用(临时对象在函数运行结束时会被系统自动回收,返回的是一块已经被释放的地址),如果想返回临时对象的值,则必须使用传值返回

int& Add(int a,int b)
{
    int c = a + b;
    return c;           // c为临时变量,不能通过引用返回,只能通过传值返回。
}

5.5 引用和指针的不同点

1) 引用概念上是一个变量的别名,指针则是存储一个变量的地址

2) 引用在定义时必须初始化,指针没有要求。

3) 引用在初始化引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类的实体。

4) 没有NULL引用,但有NULL指针。

5) 在sizeof中含义不同:引用为引用类型的大小,指针为地址空间所占字节个数(32位平台下占4字节,64位平台占8字节)。

6) 引用自加1即引用实体的值加1,指针自加1即指针向后偏移一个类型的大小

7) 有多级指针,但没有多级引用

8) 访问实体方式不同,指针需要显示解引用,引用编译器自己处理。

9) 引用比指针使用起来相对更安全,因为引用必须初始化且不能指向NULL。

5.6 引用的本质

语法概念上引用就是一个别名,没有独立空间,和其引用的实体共用同一块空间,在底层实现上,引用实际是有空间的,因为引用是按照指针的方式来实现的

#include <iostream>

int main()
{
	int a = 10;
	int& ra = a;
	int* pa = &a;
	ra = 5;
	*pa = 5;

	return 0;
}

从反汇编可以看出来,引用和指针变量定义时执行的汇编代码是相同的,而引用和指针进行赋值时执行的汇编代码也是相同的。 

六、内联函数

6.1 内联函数概念

inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数能够提升程序的运行效率。

6.2 内联函数特性

1) inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。

2) inline对于编译器而言只是一个建议(编译器可以采取也可以不采取),不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小、非递归、频繁调用的函数采用inline修饰,否则编译器会忽视inline的请求。

八、auto关键字

7.1 auto简介

在早期C/C++中auto的含义为:使用auto修饰的变量,具有自动存储器的局部变量,但遗憾的是一直没有人区使用它,在C++11中,标准委员会赋予auto全新的含义:auto不再作为一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推到而得

7.2 auto的使用规则

1) 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加"&"

2) 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

3) auto不能作为函数的参数,也不能直接用来声明数组

4) 使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非一种类型的声明,而是一个类型声明时的占位符,编译器在编译期间会将auto替换为变量实际的类型。

int main()
{
    int x = 10;
    auto a = &x;
    auto* b = &x;              // auto和auto*没有区别
    auto& c = x;               // 引用必须带"&"
    auto a = 1, b = 2;
    // auto c = 3, d = 4.0;       该行代码会编译失败,因为c和d类型不同
}

九、范围for

9.1 范围for简介

范围for是用来代替传统for循环的,对于一个有范围的集合而言,由程序员来说明循环的范围是多余的。因此C++11中引入基于范围的for循环。for循环后的括号由冒号" : "分为两部分,第一部分是范围内用于迭代的变量,第二部分则是表示被迭代的范围。

void TestFor()
{
    int array[] = { 1, 2, 3, 4, 5, 6 };
    for(int i = 0;i < sizeof(array/array[0]);i++) //传统for循环
    {
        array[i] += 1;
    }
    
    for(auto& e : array)                          //范围for,与上面for循环等效
    {
        e += 1;
    }    
}

2. 范围for的使用条件

1) for循环迭代的范围必须是确定的,对于数组而言,就是数组第一个元素和最后一个元素的范围;对于类而言,应该提供begin()和end()的方法,范围for会自动调用begin()和end()方法来确定迭代范围。

2) 迭代的对象要实现++和==的操作(需要在迭代器类中重载operate++和operate==),范围for迭代的本质是对迭代器进行自加操作,而迭代器为非内置类型,其运算操作是未定义的,所以需要用户自行实现。

PS:笔者水平有限,如有错漏,欢迎指正。

  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值