【C++笔记】C++启航之为C语言填坑的语法

这篇具有很好参考价值的文章主要介绍了【C++笔记】C++启航之为C语言填坑的语法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


我们都知道C++其实就是C语言的升级,那么在“升级”最初阶段就是要对一些在C语言中不足的语法进行改进,这些改进能让我们省很多的力并且代码写起来也比较简洁。

一、命名空间

1、为什么要引入命名空间?

C++引入命名空间主要是为了弥补在C语言中不能存在同名变量或函数的这个语法漏洞。
我们知道在C语言中,相同名称或变量是不能同时存在的:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
如上面的例子中,编译器就会报错。

2、命名空间的基本用法

为了解决这个问题,C++就引入了命名空间,命名空间的主要语法如下:

namespace _name {
	// 成员
	int a = 1;
	// 成员
	double b = 1.1;
}

命名空间使用,namespace这个关键自定义,在命名空间中我们可以定义各种成员,我们几乎可以定义所有的东西:变量、函数、结构体(类)、命名空间(嵌套定义)……

而当我们要在命名空间外使用这些成员时,我就必须得加上一个“域作用限定符”:

_name::

【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
而如果不加上,就会报错:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
这是因为C++的编译器也和C语言的编译器一样默认只会在全局去寻找。

这样我们就可以同时定义两个同名函数了,比如在全局也有一个同名的Add函数:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言

3、展开命名空间

而如果我们不想每次使用都要加上与作用限定符或者某一个成员被使用的次数太过频繁,我们就可以将命名空间进行展开:
全部展开

using namespace _name;

【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
当然,当我们展命名空间后,也是不能存在同名函数的,因为编译器会依次在全局和命名空间中查找,如果找到两个同名函数,就会存在歧义:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
上面展示的是将命名空间全部展开,而如果我们只是经常要用到命名空间中的某一个成员,而并不想展开其他成员,那我们就可以使用部分展开

using _name::Add;

【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
而对其他成员,我们依然要加上域作用限定符:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言

4、命名空间的套娃

在命名空间中也是可以再定义命名空间的:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
这样,我们就可以再定义很多的同名变量和函数了。
在使用的时候其实也和C语言的指针解引用一样,再加上一个域作用限定符就行了:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
理论上我们可以嵌套无数层的命名空间,但在实际应用中我们最多就嵌套两层就足够了。

5、命名空间的自动合并

那么问题来了,如果定义了同名的命名空间编译器会不会报错呢?
答案是不会的,当我们定义了多个命名空间,它们会自动合并:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言

二、缺省参数

1、为什么要引入缺省参数?

在C语言中,当我们要对完成某些功能的函数,进行传参时,总是会遇到不知道具体参数要传多少的情况,比如我们要写一个栈,我们想要在初始化接口中给栈分配一个空间,因为场景的不同,我们总不能具体知道要分配多少空间:

typedef struct Stack {
	int* array;
	int size;
	int capacity;
} Stack;

void StackInit(Stack* pst) {
	assert(pst);
	pst->array = (int*)malloc((? ) * sizeof(int));
	if (NULL == pst->array) {
		perror("malloc fail!\n");
		exit(-1);
	}
	pst->size = 0;
	pst->capacity = ? ;
}

针对这种情况,C++就引入了缺省参数来解决。

2、缺省参数的基本用法

缺省参数就是在函数定义时,在形参部分给一个“缺省值”:

void StackInit(Stack* pst, int n = 4) {
	assert(pst);
	pst->array = (int*)malloc((?n) * sizeof(int));
	if (NULL == pst->array) {
		perror("malloc fail!\n");
		exit(-1);
	}
	pst->size = 0;
	pst->capacity = n ;
}

当我们使用时,可以显示给值或者不显示给值:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
从结果中我们可以看出,当我们显示给值的时候,初始化用的n就是我们显示给的值,而当我们不显示给值的时候就是用的是默认的(缺省的)。

3、缺省的参数必须从右向左

在给缺省参数时,缺省参数的顺序一定是从右向左的,也就是说,缺省参数一定实在参数列表的右端并且一定是连续的,例如:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
而不能出现下面这样的情况:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
置于为什么要这样,只能说是“规定”,不要问为什么。

4、缺省参数不能声明和定义同时给

缺省参数还有一点需要注意的是,缺省参数不能声明和定义同时给:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
这样做的目的主要是为了防止声明和定义给的缺省值不一致,从而导致调用存在歧义。
但我们可以只在声明给,定义不给:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言

三、函数重载

1、为什么要引入函数重载?

我们在C语言中有时候会需要一些逻辑非常相似,但就是参数类型不同的函数,比如我们再排序中经常要使用到的交换两个变量的函数Swap,对于交换int和double类型,我们就必须写两个不同名的函数:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言

这样是不是很烦啊?
所以为了解决这个问题,C++就引入了函数重载。

2、函数重载的基本用法

有了函数重载,我们上面的这两个函数就可以同名了:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
函数重载有三个要点:

1.参数的类型不同
2.参数的顺序不同(不同类型的参数的顺序不同)
3.参数的个数不同

上面的例子就是类型不同。
然后是参数的顺序不同,一定要是不同类型的参数的顺序不同,例如下面这个例子:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
而如果只是参数名不同,而两个参数都是同一类型就会报错:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
因为编译器是根据不同类型参数的位置来判断到底该调用哪一个函数的,这样做会让编译器存在歧义。

然后是个数不同:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
这个祈其实就不用多说,编译器会根据参数的个数来判断到底该调用哪一个函数。

3、当函数重载跟缺省参数碰到一起

而如果函数重载跟缺省参数碰到一起,会发生什么呢?
例如下面这个例子:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言

从结果我们可以看出是没问题的,因为它们之间符合了参数类型不同,而参数有没有缺省值是没有关系的。
但下面这个例子就不同了:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
在这个例子中,虽然两个函数也满足了函数重载的条件只以——参数的个数不同,但是编译器在调用的时候可能会存在歧义,因为像上面这样只给一个参数的调用,对于两个函数来说都行得通,第一个函数本身就只有一个参数,而第二个有缺省值的函数只给一个参数也是能正常调用的。
所以如果在重载函数的时候想要给缺省参数,就一定要注意调用歧义的情况。

四、引用

1、为什么要引入引用?

我们都知道C语言有指针,但C++的祖师爷在使用指针的时候发现:C语言这个指针,用起来也太不方便了吧。例如我们要写一个交换函数Swap:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
如上面这个例子,祖师爷觉得有两个地方很麻烦,一是在Swap函数内想要拿到数据就必须得对指针解引用,二是在调用的时候要对变量取地址。
所以祖师爷为了解决这两个问题,在C++中引入了引用。

2、引用的基本用法

引用如果按底层来理解,其实它也使用指针来实现的,只不过它较之指针使用起来更方便。
引用可以理解为是某一个变量的别名:
引用的定义形式如下:

int a = 1;
int& b = a;

以前在C++中的取地址操作符“&”,现在到了C++中就有了另一个功能,将其放在类型后面就表示某个类型的引用。
之所以称为“别名”是因为,引用基本可以当做被它引用的对象来使用,对引用进行自加自减,对象本身也会发生变化:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言

在使用引用时候需要注意的一点是引用必须在定义的时候初始化,所以也就不存在什么“野引用”的说法。
还有一点是引用的只想不能改变,也就是说一个引用只能做一个变量的别名,而不像指针一样能改变其指向。

3、引用做输出型参数

由于引用的特性,所以我们日后会经常使用引用来做输出型参数,比如我们现在实现一个简单的自加函数:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言

4、在引用的过程中权限不能放大

怎样理解这一点呢?先看下面这个例子:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
报错的原因就是,引用将原本变量的权限放大了,我们知道const修饰的变量是只能读不能写的(不能改变),但引用默认是能读能写的,这样就是权限放大了。

想要消除报错,就可以对引用也加上const:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言
这成为“权限的平移”。
权限不仅可以“平移”,也可以“缩小”:
【C++笔记】C++启航之为C语言填坑的语法,C++之路,c++,笔记,开发语言文章来源地址https://www.toymoban.com/news/detail-635981.html

到了这里,关于【C++笔记】C++启航之为C语言填坑的语法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【小梦C嘎嘎——启航篇】C++ 基础中的精华(一)

        😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧!!! 😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主! 😘博主小留言:哈喽! 😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不

    2024年02月12日
    浏览(32)
  • 侯捷课程笔记(一)(传统c++语法,类内容)

    2023-09-03更新: 本小节已经完结,只会进行小修改 埋下了一些坑,后面会单独讲或者起新章节讲 最近在学习侯捷的一些课程,虽然其中大部分内容之前也都已经了解过了,不过还是收获颇丰,特别是独立与所谓语法之外的,还有许多与设计相关的。 这一章内容比较简单,也

    2024年02月10日
    浏览(39)
  • “C++基础入门指南:了解语言特性和基本语法”

    C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式 等。熟悉C语言之后,对C++学习有一定的帮助 工作之后,看谁的技术牛不牛逼,不用看谁写出多牛逼的代码,就代码风格扫一眼,立刻就能看出来是正规军还是野生的程序员。代码的风

    2024年02月16日
    浏览(38)
  • R语言基础的代码语法解译笔记

    1、双冒号,即:“::” 要使用某个包里的函数,通常做法是先加载(library)包,再调用函数。最新加载的包的namespace会成为最新的enviroment,某些情况下可能影响函数的结果。而 package name::functionname 的用法,一是可以在需要用某个函数时临时直接加载包,不用事先library。另

    2024年03月11日
    浏览(63)
  • C++进阶语法——OOP(面向对象)【学习笔记(四)】

    1、C++ OOP面向对象开发 1.1 类(classes)和对象(objects) 简单介绍一下类: C++ 类(classes) 创建对象⽤的蓝图(blueprint) ⽤户⾃定义的数据类型 有成员属性(data)和成员⽅法(methods) 可以隐藏属性和⽅法(private) 可以提供公共接⼝(public) 示例: Account, Student, std::vecto

    2024年02月07日
    浏览(49)
  • 算法笔记 ① acwing C++基础语法 | 全课程内容

    cstdio 有两个函数 printf,scanf 用于输出和输入 iostream 有 cin 读入,cout 输出 使用了std命名空间,cin、cout定义在该命名空间中,不引入空间会找不到导致出错 函数执行入口 ⭐所有 cout、cin 都能用 scanf、printf 替换,但反过来,由于cout、cin效率可能较低会导致超时 ⭐ printf %c 会读

    2024年02月10日
    浏览(35)
  • c++:基于c语言基础上的语法不同(1)

    前言:此篇文章适合学完c语言基础概念的同学,是帮助c向c++语言的同学快速掌握基本语法。 按照c语言的语法也可以,头文件多包含#includestring 下面是通过数组名的方法打印字符串hello world。 1e2就是1x10的二次方 1e-2就是1x10的负二次方 float类型后面的数字要多写一个f,不然编

    2024年01月20日
    浏览(39)
  • 编程语言学习笔记-架构师和工程师的区别,PHP架构师之路

    🏆作者简介,黑夜开发者,全栈领域新星创作者✌,CSDN博客专家,阿里云社区专家博主,2023年6月CSDN上海赛道top4。 🏆数年电商行业从业经验,历任核心研发工程师,项目技术负责人。 🏆本文已收录于PHP专栏:PHP进阶实战教程。 🎉欢迎 👍点赞✍评论⭐收藏 什么是架构师

    2024年02月12日
    浏览(50)
  • C++进阶语法——STL 标准模板库(下)(Standard Template Library)【学习笔记(七)】

    1、迭代器 迭代器可以将任意的容器抽象成一个序列,可以使用迭代器遍历容器中的元素 迭代器设计的目的是为了解决容器与算法之间的耦合问题,与指针类似,可以通过迭代器访问容器中的元素 迭代器的声明方式为: 容器类型::iterator 变量名称 , 可以理解为一个普通的指

    2024年02月06日
    浏览(46)
  • 嵌入式C语言自我修养《GNU C编译器扩展语法》学习笔记

    目录 一、C语言标准和编译器 二、指定初始化 三、宏构造“利器”:语句表达式 四、typeof与container_of宏 五、零长度数组 六、属性声明:section  七、属性声明:aligned  C语言标准的发展过程: ● KR C. ● ANSI C. ● C99. ● C11. 指定初始化结构体成员:         和数组类似,

    2024年02月08日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包