【C++】认识C++(上)

目录

  • 从C到C++
  • 命名空间
    • 同名冲突
    • 命名空间的定义
    • 命名空间的使用
  • C++的输入和输出
  • 缺省参数(默认参数)

请添加图片描述

从C到C++

  C语言的出现是计算机科学和工程史上的一个重要里程碑,许多现代计算机语言都受C语言的影响。C语言是面向过程的,结构化和模块化的语言。 C语言的设计者必须细致地设计程序中的每一个细节,准确考虑程序运行时每一个步骤发生的事,但是随着计算机应用的推广,需要解决更多更复杂的问题,C语言就太适合了。
  于是乎,20世纪80年代,计算机界提出了面向对象的程序设计OOP(Object Orientde Programming)思想,由此支持面向对象的程序设计语言应运而生。
  1982年,AT&T Bell(贝尔)实验室的Bjarne Stroustrup博士及其同事在C语言的基础上引入并扩充了面向对象的概念,为了表达该语言与C语言的渊源关系,将其命名为C++。
  C++保留了C语言原有的主要优点,增加了面向对象的机制。 又因为C++是C发展而来的,与C兼容,用C语言编写的程序基本上可以不加修改的用于C++。C++是C的超集,可用于面向过程的结构化设计,但更多地用于面向对象的程序设计,是一种功能强大的混合型的程序设计语言
  下面就来走进C++,敲开C++的大门。

命名空间

同名冲突

  在C/C++中,变量,函数和C++中要学习到的类都是大量存在的。由于它们的大量存在,我们就喜欢将它们定义在全局作用域上,以方便修改。
  在实际生活中,通常会将一个项目分到几个小组去写,最后整合,这样时间效率都会增高。但是这就会出现一个问题,在整合项目的时候,可能会有些命名上的重复,导致程序报错。
  不仅如此,在程序设计中往往需要引用一些库(包括C++编译系统提供的库,以及开发者字节开发的库等等),为此需要包含有关头文件。如果在这些库中包含有与程序的全局实体同名的实体,或者不同库有相同的变量或函数或类的名字,就会在编译时出现名字冲突,也就是全局命名空间污染。 那么如何解决这个问题,C++中namespace 关键字的存在就是针对这种问题的。
  我们已经说了,写程序时容易发生命名冲突,则使用命名空间的目的就是对标识符的名称本地化,以避免命名冲突或文字污染。命名空间实际上就是一个由程序设计者命名的内存区域。所以一开始在学C语言的时候,我们就知道了有两个作用域,一个是全局域,另一个是局部域,现在加了这个命名空间以后,C++的一个程序上就会有三个域的存在

  1. 全局域
  2. 局部域
  3. 命名空间域

例如:

#include<stdio.h>
#include<stdlib.h>int rand = 10;
int main()
{printf("%d\n", rand);return 0;
}

rand本身是一个库函数,用来生成随机值,要用的时候需要包含在头文件stdlib.h中。
而此时全局变量中又定义了一个rand,导致printf在输出时不知道应该调用库函数里面的rand,还是全局变量中的rand,此时就发生了命名冲突。
在这里插入图片描述

命名空间的定义

  定义命名空间,需要使用到namespace关键字,后面接着命名空间的名字,最后加一对{}即可,{}中即为命名空间的成员。命名空间中不止可以包括变量,还可以包括函数,结构体,类(后面会学习到),模板,命名空间(嵌套使用也可以)等,例如下面的例子:

namespace ns1
{int a = 1;//定义变量int Add(int x, int y)//定义函数{return x+y;}struct ListNode//定义结构体{int val;struct ListNode* next;};namespace ns2//嵌套了另一个命名空间{int sub(int x, int y){return x+y;}}
}

  还有值得要提的一点是,同一个工程中存在多个相同名称的命名空间,编译器最后都将会合成在同一个命名空间中。 就像你在北京有套房,在上海也有套房,那别人也就知道你是有两套房,都在你的名下。
如:

namespace ns1
{int a = 1;//定义变量int b = 2;
}namespace ns1
{int Add(int x, int y)//定义函数{return x + y;}
}

  最终编译器会认为是:

namespace ns1
{int a = 1;//定义变量int b = 2;int Add(int x, int y)//定义函数{return x + y;}
}

  命名空间所定义的命名空间域,将命名空间中的内容都局限于该命名空间中。

命名空间的使用

  我们介绍了如何去定义命名空间,下面来看看它是如何使用的。
  命名空间有三种使用方式:

  • 第一种方式:加命名空间名称及作用域限定符(在需要使用命名空间中的内容时再制定访问)
#include<stdio.h>
namespace ns1
{int a = 1;//定义变量int b = 2;
}
int main()
{
//    printf("%d\n", a);
//     这种直接想打印命名空间域里面的变量时编译器会报错
//     error C2065: “a”: 未声明的标识符printf("%d\n",ns1::a);return 0;
}

  我们发现在命名空间名字的后面有一个::符号,这叫做域作用限定符, 也就限定了内容在哪块查找。如:

#include<stdio.h>
int a = 10;
int main()
{int a = 20;printf("%d\n", a);   //打印的是局部域中的a是20printf("%d\n", ::a); //打印的是全局域中的a是10return 0;
}
  • 第二种方式:使用using将命名空间中某个成员引入

  即在程序中需要大量使用命名空间中的某一个成员时,每一次都去加上限定符比较麻烦,于是我们用using来制定展开某一个,例如:

#include<stdio.h>
namespace ns1
{int a = 1;//定义变量int b = 2;
}
using ns1::a;
int main()
{printf("%d\n", a);printf("%d\n", a);//此时我们使用a时就不用再加上限定符printf("%d\n", ns1::b);//我们只是展开了变量a,所以在使用b的时候还是要加上限定符return 0;
}
  • 第三种方式:使用using namespace命名空间名称引入

  使用了这个命名空间引入,可以将命名空间中的变量所有都展开来,后面在使用时都不需要加上限定符。例如:

#include<stdio.h>
namespace ns1
{int a = 1;//定义变量int b = 2;
}
using namespace ns1;
int main()
{printf("%d\n", a);printf("%d\n", b);return 0;
}

  注意!:编译器在编译时对变量等的查找会有默认查找顺序,首先查找的是当前局部域,其次是全局域。
  只有命名空间被展开了,最后才会到这里面去找。

C++的输入和输出

  C语言的输入输出是有scanf和printf来控制的,而在C++中则是由cin和cout来控制。
  例如:

#include<iostream>
using namespace std;
int main()
{int a, b;cin >> a >> b;cout << "a = " << a << "  " << "b = " << b << endl;return 0;
}

  结果如下:
在这里插入图片描述
  我们发现该程序进行了对a和b的输入并且打印输出操作。
在C++中,cout和cin是系统定义的对象名,cin是标准输入对象(键盘),cout是标准输出对象(控制台),(我们运行结果出来的框框就是控制台)。
  <<是流插入运算符,与cin配套使用,>>是流提取运算符,与cout配套使用。
  在C语言中,scanf和printf的使用需要包含头文件<stdio.h>,C++中也一样,在使用cin和cout时,需要包含头文件 < iostream>
  C++标准库中的类和函数时再命名空间std中声明的,如果需要使用C++标准库中的内容,就需要使用using namespace std来声明,表示要用命名空间std中的库函数
  使用C++的输入输出更加方便,不需要像printf/scanf那样,需要手动控制格式C++的输入输出可以自动识别变量类型。

  注意:
std是C++标准库的命名空间,应该如何去使用

  1. 在日常练习中,可以直接使用using namespace std 即可,方便使用各种库函数。
  2. 因为using namespace std展开,标准库就全部露出来了,如果我们定义根库重名的类型/对象/函数,就存在冲突问题,这种问题在日常练习中很少出现,但是项目开发中代码较多,规模较大,就很容易出现问题,所以在项目开发中建议使用:像std::cout这样使用时指定命名空间 + using std::cout展开常用的库对象/类型等方式。

缺省参数(默认参数)

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

  • 全缺省参数(全默认参数)
    也就是函数的形参全部给了默认值
#include<iostream>
using namespace std;
void func(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a;cout << " b = " << b;cout << " c = " << c << endl;
}int main()
{func(1, 2, 3);func(1, 2);func(1);func();return 0;
}

  运行结果如下:
在这里插入图片描述

  • 半缺省参数
#include<iostream>
using namespace std;
void func(int a , int b = 20, int c = 30)
{cout << "a = " << a;cout << " b = " << b;cout << " c = " << c << endl;
}int main()
{func(1, 2, 3);func(1, 2);func(1);return 0;
}

  运行结果如下:
在这里插入图片描述
  在使用缺省参数时有几个注意事项如下:

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数的声明和定义中同时出现
  3. 缺省值必须是常量或者是全局变量
  4. C语言不支持。

对于第2点的解释:
我们对一个函数进行声明和定义时,通常把声明放在.h文件中,定义放在.cpp文件中。
所以会出现:
xxx.h文件中函数声明:void func(int a = 10);
xxx.cpp文件中函数定义:void func(int a = 20){…}
此时两个位置提供的值不同,编译器就不知道该用那个缺省(默认)值,会报错。

  今天的内容到此结束啦,感谢大家观看,如果大家喜欢,希望大家一键三连支持一下,如有表述不正确,也欢迎大家批评指正。

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/701885.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows Docker 部署 Etcd 键值存储系统

一、简介 etcd 是一个由 CoreOS 团队发起的开源项目&#xff0c;它用 Go 语言实现&#xff0c;是一个分布式、高可用的键值存储系统。etcd 采用 Raft 算法&#xff0c;确保了数据的强一致性和高可用性&#xff0c;即使集群中有部分节点发生故障&#xff0c;也能保持服务的正常…

2024深圳杯数学建模C题参考论文24页+完整代码数据解题

一、问题研究 24页参考论文&#xff1a; 【编译器识别】2024深圳杯C题24页参考论文1-3小问完整解题代码https://www.jdmm.cc/file/2710545/ 为了回答这些问题&#xff0c;我们需要进行一系列的编译实验、分析编译结果&#xff0c;并构建判别函数。以下是对这些问题的初步分析…

杨校老师项目之基于单片机STC89C52的智能环境监测系统【嵌入式】

获取全套资料&#xff1a; 有偿获取&#xff1a;mryang511688 技术&#xff1a;C语言、单片机等 摘要&#xff1a; 此设计可分为三个主要部分。此中的温度和湿度的检测功能&#xff0c;通过操纵单总线型温湿度传感器DHT11以数字形式显示&#xff0c;实现了切确测得温湿度的功能…

乡村振兴的农业科技创新:加大农业科技投入,推广农业科技成果,提升农业科技创新水平,推动美丽乡村农业现代化

一、引言 随着全球化和信息化时代的到来&#xff0c;农业作为国民经济的基础&#xff0c;其现代化进程日益受到关注。在乡村振兴战略的大背景下&#xff0c;农业科技创新成为推动乡村经济转型升级、实现农业现代化的关键力量。本文旨在探讨如何通过加大农业科技投入、推广农业…

[图解]EA从数据库逆向得到分析类模型-01

1 00:00:00,840 --> 00:00:02,400 今天&#xff0c;我们来说一下 2 00:00:02,670 --> 00:00:06,320 一个最近几天不止一个同学问的问题 3 00:00:06,490 --> 00:00:11,410 就是说&#xff0c;怎样把一个数据库 4 00:00:13,740 --> 00:00:16,720 转到分析类图 5 …

项目管理-案例重点知识(整合管理)

项目管理&#xff1a;每天进步一点点~ 活到老&#xff0c;学到老 ヾ(◍∇◍)&#xff89;&#xff9e; 何时学习都不晚&#xff0c;加油 一、整合管理 案例重点 重点内容&#xff1a; &#xff08;1&#xff09;项目章程内容和作用 &#xff08;2&#xff09;项目管理计划…

前端 performance api使用 —— mark、measure计算vue3页面echarts渲染时间

文章目录 ⭐前言&#x1f496;vue3系列文章 ⭐Performance api计算持续时间&#x1f496; mark用法&#x1f496; measure用法 ⭐计算echarts渲染的持续时间⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于 前端 performance api使用 —— mark、measure计…

vs2019 c++中模板 enable_if_t 的使用

&#xff08;1&#xff09; 该模板的定义如下&#xff1a; template <bool _Test, class _Ty void> struct enable_if {}; // no member "type" when !_Testtemplate <class _Ty> struct enable_if<true, _Ty> { // type is _Ty for _Testusing …

C++——动态规划

公共子序列问题 ~待补充 最长公共子序列 对于两个字符串A和B&#xff0c;A的前i位和B的前j位的最大公共子序列必然是所求解的一部分&#xff0c;设dp[i][j]为串A前i位和B串前j位的最长公共子序列的长度&#xff0c;则所求答案为dp[n][m]&#xff0c;其中n&#xff0c;m分别为…

C++ | Leetcode C++题解之第90题子集II

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<int> t;vector<vector<int>> ans;vector<vector<int>> subsetsWithDup(vector<int> &nums) {sort(nums.begin(), nums.end());int n nums.size();for (int mask …

楼宇智慧公厕建设新方案-集成更简单!成本价更低!

在当今的大厦和写字楼中&#xff0c;公厕面临着诸多痛点。 办公楼公厕常常存在厕位难找的问题&#xff0c;使用者不得不花费时间逐一查看&#xff0c;导致效率低下&#xff1b;环境质量也令人担忧&#xff0c;异味、脏污等情况时有发生&#xff0c;影响使用者的心情和健康&…

特征模态分解(FMD):一种小众而又新颖的分解方法

​ 声明&#xff1a;文章是从本人公众号中复制而来&#xff0c;因此&#xff0c;想最新最快了解各类智能优化算法及其改进的朋友&#xff0c;可关注我的公众号&#xff1a;强盛机器学习&#xff0c;不定期会有很多免费代码分享~ 今天为大家介绍一个小众而又新颖的信号分…