C++ 入门篇
创始人
2024-06-02 08:34:25
0

目录

    • 一. 命名空间
      • 1. 介绍
      • 2. 定义命名空间
      • 3. 使用
      • 4. cin与cout
    • 二. 缺省参数
      • 1. 介绍
      • 2. 全缺省参数
      • 3. 半缺省参数
      • 4. 其他
    • 三. 函数重载
      • 1. 介绍
      • 2. 使用
      • 3. name Mangling(名字修饰)
      • 4. extern "C"
    • 四. 引用
      • 1. 介绍
      • 2.特点
      • 3.常引用
      • 4.使用
      • 5.引用与指针
    • 五. inline函数
      • 1. 介绍
      • 2. 特性
    • 六. auto
      • 1. 介绍
      • 2. 细节
    • 七.范围for循环
      • 1.介绍
      • 2. 使用
    • 八.空指针
      • 1. NULL
      • 2.nullptr

从c语言进阶到c++的必备基础知识

一. 命名空间

1. 介绍

对于类、函数或变量的在同一作用域中时,可能会因为相同标识符冲突。因此使用命名空间的目的是:对标识符的名称进行本地化,避免命名冲突或名字污染

2. 定义命名空间

定义一个命名空间,就定义了一个作用域,命名空间中的内容都局限于该命名空间

使用关键字:namespace

//1.普通命名空间
namespace N1//N1是命名空间的名称
{static int times = 0;int add(int n1, int n2){return n1 + n2;}
}//2.嵌套的命名空间
namespace N2
{int sub(int n1, int n2){return n1 - n2;}namespace N3{int sub(int n1, int n2){return abs(n1 -n2);}}
}//3. 同名命名空间
//同一个项目中的多个同名命名空间,在编译的时候
//会合并为同一个命名空间
namespace N1
{int sub(int n1, int n2){return n1 - n2;}
}

3. 使用

以上述的三个命名空间举例,命名空间的使用主要有三种方式:

//1.使用其中某个函数、变量或类时,
//前面加 命名空间名 和 作用域限定符
int main()
{printf("%d\n", N1::times);int ret1 = N2::sub(1, 9);int ret2 = N2::N3::sub(1, 9);return 0;
}
//2. 使用using引入命名空间中成员
using N1::times;//sub函数会发生命名冲突
//using N2::sub;
//using N2::N3::sub;int main()
{printf("%d\n",times);//int ret1 = sub(1, 9);//int ret2 = sub(1, 9);return 0;
}
//3. using namespace + 命名空间 
using namespace N1;
int main()
{printf("%d\n",times);int ret1 = add(1, 1);int ret2 = sub(1, 1);return 0;
}

对于方法3,因为会将命名空间的内容全部展开(就相当于放在全局域中),就无法起到它的作用了。因此,在实际项目中建议使用方法2展开常用的,能更好的避免命名冲突。

4. cin与cout

#include int main()
{int a;double b;char c;std::cin >> a >> b >> c;std::cout << "---------\n";std::cout << " a = " << a;std::cout << " b = " << b;std::cout << " c = " << c << std::endl;return 0;
}

在这里插入图片描述

其中cin 不会记录空格和换行符,cout会自动识别类型,endl的作用相当于\n


二. 缺省参数

1. 介绍

在声明或定义函数时,为其参数指定默认值。则可以在没有实参的情况下,使用该的默认值。

int add(int a = 0, int b = 0)
{return a + b;
}
int main()
{add();   //没有传参,会使用默认值add(1, 1);//传入实参 1,1return 0;
}

2. 全缺省参数

int add(int a = 0, int b = 0, int c = 0)
{return a + b + c;
}
int main()
{add();		 // a=0,b=0,c=0add(1);	     // a=1,b=0,c=0add(1, 2);   //a=1,b=2,c=0add(1, 2, 3);//a=1,b=2,c=3return 0;
}

3. 半缺省参数

int add(int a , int b = 0, int c = 0)
{return a + b + c;
}
int main()
{//add();// a不是缺省参数所有必须传参add(1);	     // a=1,b=0,c=0add(1, 2);   //a=1,b=2,c=0add(1, 2, 3);//a=1,b=2,c=3return 0;
}

函数的参数列表中,半缺省参数必须从右→左依次定义没有默认值的参数,不能间隔

4. 其他

函数的定义和声明不能同时出现缺省参数
在这里插入图片描述
同时使用默认参数时,如果给定的默认值不同也会造成冲突。

因此只用在声明或定义时使用缺省参数。

int add(int a , int b = 0, int c = 0);int add(int a, int b, int c )
{return a + b + c;
}

缺省值必须是常量或者全局变量


三. 函数重载

1. 介绍

c++允许在同一作用域下,有多个参数列表不同,函数名相同的函数,称为函数重载,用于处理数据类型不同但是功能相似的问题。

2. 使用

#include using namespace std;int Add(int n1, int n2)
{return n1 + n2;
}
double Add(double n1, double n2)
{return n1 + n2;
}int main()
{int a = 1;double b = 1;cout << Add(a, a) << endl;cout << Add(b, b) << endl;return 0;
}

调用函数时,会根据参数类型自动匹配到对应的函数。

3. name Mangling(名字修饰)

c语言不能支持函数重载,如果想要实现上述函数,只能命名如Add1(),Add2(),来区分不同函数。

那么为什么C++可以支持函数重载呢?

从写好的.cpp———>可以运行的 .exe文件,需要经历预处理,编译,汇编,链接几个过程。

在链接阶段,链接器会将调用的Add的地址找到,然后链接起来,其中链接器也是通过名字去找到的,而且不同编译器对函数名都有自己的修饰规则。

因为Linux下gcc/g++对函数的命名规则比较简单,以下示例:
在这里插入图片描述

test.c文件,经过c语言编译器gcc编译后,我们可以发现其汇编语言中,调用的分别对应Add()——< Add >,Sub()——< Sub >


在这里插入图片描述
test.cpp文件,经过c++编译器g++编译后,其汇编语言中g++将函数名修饰后变成**{_Z+函数名长度+函数名+参数类型首字母}**

由此可以看出,是因为c++的编译器会对函数名进行修饰,因此可以支持函数重载。

值得一提的是,返回值不同不是函数重载的要素。

4. extern “C”

​ 由于c和c++编译器对函数名的修饰规则不同,因此c++中调用c语言实现的静态库或者动态库时会出现问题。因此就需要在函数前加extern “C”,来告诉编译器,将该函数按照c语言的规则来编译。

参考链接:创建与使用静态库
在这里插入图片描述

在c++程序中,包含Add.h后,经过extern "C"修饰,就可以成功使用c语言的静态库了。

四. 引用

1. 介绍

  • 语法:类型& 引用名 = 引用实体;

    相当于给一个已经存在的变量,起一个别名,可以通过这个引用名访问到该变量本身
    在这里插入图片描述

2.特点

  • 引用类型必须和引用实体是同种类型
  • 引用在定义时必须初始化
  • 一个变量可以有多个引用,但是一个引用只能有一个实体,且不能再更改。

3.常引用

  • 对于const修饰的变量,需要使用const修饰的引用,即为常引用
  • 若常引用和实体是不同的基本类型,常引用所引用的实际上是实体的拷贝
    在这里插入图片描述

常量a 需要常引用c 来引用

d作为int型的常引用来引用double型的变量b,是因为常引用d实际上引用的是b转换为int型的拷贝(地址不同)

4.使用

  • 通常使用引用做返回值或参数时,主要因为其类似于指针,即可以节省空间又可以节省时间
  1. 参数
void Swap(int& a, int& b)
{int temp = a;a = b;b = temp;
}

a,b都是引用类型,因此在Swap内的交换可以改变其引用的实体

适用场景:输出行参数(如上例),大对象传参

  1. 返回值
int& Add(int a, int b)
{static int sum = a+b;return sum;
}

由于sum是静态变量,因此其作用域为全局,可以返回其引用。

适用场景:修改返回对象,大对象返回

下例为一个错误示范 :
在这里插入图片描述

由于调用完Add()函数后不久,系统会回收其所占用的栈空间,其中就包括sum,因此对于a最后会变成随机值。

5.引用与指针

在语法概念上引用就是一个别名,和其引用实体共用一块空间;指针有固定大小的空间(4/8),存放的是所指向空间的首地址

在底层实现中,引用实际有自己的空间,因为引用是按照指针的方式来实现的。
在这里插入图片描述

如图,指针和引用的操作,其汇编代码相同

不同点:

1.引用在定义时必须初始化,指针无此要求

2.引用不能再更改为其它引用实体,指针可以指向任意同类型实体

3.没有NULL的引用,有NULL的指针

4.在sizeof下含义不同,引用结果为引用类型的大小,指针结果为自身(地址空间,32位平台下占4个字节)的大小

5.引用++即实体增1,指针++即指针指向向后偏移一个类型的大小

6.没有多级引用,有多级指针

7.访问实体时,引用时编译器会自动处理,指针需要显示解引用

8.引用比指针使用更安全

五. inline函数

1. 介绍

​ 以inline修饰的函数叫做内联函数。编译时,编译器会在调用内联函数的地方将函数展开,来减少函数调用所建立和销毁栈帧的开销,提高程序的运行效率。
在这里插入图片描述
在这里插入图片描述

当使用inline后,可以看见没有调用函数call了,而是直接执行函数的语句。


c语言中,对于类似问题的解决,提供宏函数来提高效率#define Add(a+b) ((a)+(b))

宏的优点:1.复用性强 2.提高效率

宏的缺点:1.可读性差 2.没有类型安全检查 3.不方便调试(因为预处理阶段进行了替换)

C++中基本不再建议使用宏,尽量使用const、enum、inline来代替宏

2. 特性

  • 内联函数是一种以空间换时间的做法,会用函数体来替换函数调用,多次调用,会使目标文件变大(参考上图所示)。因此代码很长 或者 递归的函数不适用
  • inline对于编译器而言只是一个建议,编译器会自动优化。一般将函数规模较小、不是递归、频繁调用的函数,采用inline修饰,否则会忽略inline特性。
  • 内联函数不建议定义和声明分离(分别放在.cpp与.h,对于使用该函数的其他.cpp文件,因为是单独编译的,所有是找不到函数体的。)

六. auto

1. 介绍

auto的作用是自动推导类型,用于解决类型难拼写、类型不明确
在这里插入图片描述

使用auto定义变量时,必须初始化。编译时编译器根据初始化表达式来推导auto的实际类型,将auto替换为变量实际的类型。因此auto是声明类型时的"占位符"。

2. 细节

  1. 指针与引用

    用auto声明指针类型时,使用autoauto*没有区别,但是声明引用类型 时必须加&
    在这里插入图片描述

  2. 同一行定义多个变量

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

auto a = 1, b = 2, c = 3;

  1. auto不能作为函数的参数

    编译阶段无法推导实际类型

  2. auto不能直接声明数组

七.范围for循环

1.介绍

对于有范围的集合的整体遍历,可以不用像for(;;)来说明循环的范围。

int a[] = { 1,2,3,4,5 };
for (int t : a)
{cout << t << " ";
}

for()内用:来分隔成两部分,int t表示用于迭代的变量,a表示被迭代的范围。

循环从开始到结束,会依次取数组a的值赋值给局部变量t,然后输出。

2. 使用

  1. auto
int a[] = { 1,2,3,4,5 };
for (auto t : a)
{cout << t << " ";
}

当不清楚集合a的类型时,可以直接使用auto来推导

  1. 引用
int a[] = { 1,2,3,4,5 };
for (auto& t : a)
{t++;cout << t << " ";
}

使用引用后,t就是a元素的别名,因此可以通过t来改变a中元素的内容

  1. 和普通循环一样,也可以使用continue,break
  2. 底层实际上是迭代器,需要确定范围的begin和end
//void test(int a[])
//{
//	for (auot& t : a)
//	{
//		cout << t << " ";
//	}
//}

对于上例中,函数参数a接收的是一个指针,因此数组的范围不能明确,会报错。

八.空指针

1. NULL

在c语言里,我们使用的是NULL来表示空指针。NULL实际上是一个宏,底层实现下:

#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif
#endif

因此NULL可能被定义为字面常量0或者是无类型指针(void*)的常量,而字面常量0,编译器默认看作为整型常量。

因此会出现下例问题:
在这里插入图片描述

语法中NULL应该表示空值指针,程序却没有调用fun(int* a),相悖 。

2.nullptr

建议使用nullptr来表示空指针。

  • nullptr是c++11作为关键字引入的,不需要包含头文件。
    在这里插入图片描述

🦀🦀观看~

相关内容

热门资讯

婚礼开场白主持词 婚礼开场白主持词  利用在中国拥有几千年文化的诗词能够有效提高主持词的感染力。随着社会一步步向前发展...
会主持人开场白台词 会主持人开场白台词2013年会主持人开场白台词    甲:新年的钟声即将敲响,时光的车轮又留下了一道...
领导主持词 领导主持词三篇  主持词已成为各种演出活动和集会中不可或缺的一部分。在现今人们越来越重视活动氛围的社...
升学宴致辞 升学宴致辞(精选15篇)  在现实生活或工作学习中,大家一定都接触过致辞吧,致辞具有“礼仪性”或“仪...
农村白事的主持词开场白 农村白事的主持词开场白(精选10篇)  在发展不断提速的社会中,越来越多的人会用到开场白,好的开场白...
生日主持词的开场白   生日主持词开场白(一)  各位同事和寿星们,各人晚顶好!在这天高气爽、丹桂飘喷鼻的夸姣季候,咱们...
旅游文化节主持词 旅游文化节主持词  主持词的写作需要将主题贯穿于所有节目之中。现今社会在不断向前发展,主持人参与的事...
主持人串词 主持人串词  一、串词的语言特征  (串词的语言,可以说是用尽了所有的修辞手法,我们不可能去全讲,因...
浪漫婚礼司仪主持词 浪漫婚礼司仪主持词  主持词是主持人在台上表演的灵魂之所在。在现在的社会生活中,很多场合都需要主持人...
公司迎春晚会的主持词 公司迎春晚会的主持词  主持词的写作需要将主题贯穿于所有节目之中。在当今不断发展的世界,主持人在活动...
少儿节目主持词 精选少儿节目主持词4篇  主持词已成为各种演出活动和集会中不可或缺的一部分。随着社会一步步向前发展,...
王家卫电影经典台词 王家卫电影经典台词(精选50句)  我们爱看王家卫的电影,不止爱他所创造的那个光影世界,更爱他电影中...
演唱会主持台词 演唱会主持台词  (甲)尊敬的各位领导,  (乙)各位来宾,  (甲)敬爱的老师,  (乙)亲爱的同...
《你的名字》经典台词 《你的名字》经典台词  你的名字,是谁的心事,还记得你的名字里面的经典台词吗?以下是小编为你精心整理...
教研活动主持词 教研活动主持词  主持人在台上表演的灵魂就表现在主持词中。在当下的中国社会,主持成为很多活动不可或缺...
艺术节主持词开场白 艺术节主持词开场白  什么是艺术节  艺术节是文艺工作者及艺术家、艺术爱好者之间学术交流与学习的重要...
老板在公司年会致辞 老板在公司年会致辞15篇  在平平淡淡的学习、工作、生活中,大家最不陌生的就是致辞了吧,致辞具有针对...
央视春晚主持词台词 央视春晚主持词台词  主持词是主持人在节目进行过程中用于串联节目的串联词。在各种集会、活动不断增多的...
教师节朗诵晚会串词 教师节朗诵晚会串词  主持词需要富有情感,充满热情,才能有效地吸引到观众。在当今不断发展的世界,越来...
趣味运动会主持稿 趣味运动会主持稿(通用7篇)  在充满活力,日益开放的今天,很多地方都会使用到主持稿,主持稿是主持人...