C++基础知识(入门章)

绪论

历经千辛万苦,我们终于来到了一个全新的板块---C++。本期的内容主要是关于C++的一些基础知识的初步了解。让我们一起努力,克服编程路上的艰难险阻,迎接属于自己成功的彼岸~

C++的发展历史

1979年

        C++的起源可以追溯到1979年,当时Bjarne Stroustrup(本贾尼·斯特劳斯特卢普),这个翻译的名字不同的地⽅可能有差异)在⻉尔实验室从事计算机科学和软件⼯程的研究⼯作。⾯对项⽬中复杂的软件开发任务,特别是模拟和操作系统的开发⼯作,他感受到了现有语⾔(如C语⾔)在表达能⼒、可维护性和可扩展性⽅⾯的不⾜。

1983年

1983年,Bjarne Stroustrup在C语⾔的基础上添加了⾯向对象编程的特性,设计出了C++语⾔的雏形, 此时的C++已经有了类、封装、继承等核⼼概念,为后来的⾯向对象编程奠定了基础。这⼀年该语⾔被正式命名为C++。

1989年

        C++的标准化⼯作于1989年开始,并成⽴了⼀个ANSI和ISO(International Standards  Organization)国际标准化组织的联合标准化委员会。1994年标准化委员会提出了第⼀个标准化草 案。在该草案中,委员会在保持斯特劳斯特卢普最初定义的所有特征的同时,还增加了部分新特征。

1997年

1997年11⽉14⽇,联合标准化委员会通过了该标准的最终草案。

1998年

1998年,C++的ANSI/IS0标准被投⼊使⽤。

让我们来见一见祖师爷~

C++的历代版本

C++的参考文档

以下三个是C++学习过程中可供参考的网址:

https://legacy.cplusplus.com/reference/

https://zh.cppreference.com/w/cpp

https://en.cppreference.com/w/

C++的第一个程序

C++是由C语言不断改良而生成的新语言,所以它能兼容C语言的绝大多数语法。我们就从所有语言的第一个代码---“hello world!”来开启我们的学习吧!

首先我们来看看C语言的代码:

#include<stdio.h>
int main()
{printf("hello world\n");return 0;
}

相较于C语言,C++有⼀套⾃⼰的输⼊输出,严格说C++版本的hello world应该是这样写的。

#include<iostream>
using namespace std;
int main()
{cout << "hello world" << endl;return 0;
}

命名空间

概念:

在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全局作⽤域中,可能会导致很多冲突。使⽤命名空间的⽬的是对标识符的名称进⾏本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

接下来我们借助一串代码来理解命名空间的隔离原则:

#include <stdio.h> #include <stdlib.h>
int rand = 10;
int main()
{// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数” printf("%d\n", rand);return 0;
}

引入了“stdlib.h”的头文件,由于rand在库函数中有定义,导致全局变量中所创建的整型变量rand与要打印的rand类型冲突,编译器无法正确的识别定义的变量。C++中引入的namespace很好的解决了这个问题。我们接着来看:

域作用限定符

在开启接下来的内容之前,我们先来了解一下什么是域作用限定符:

在一串代码中,main函数的调用顺序是局部域,全局域,最后再调用命名空间域的变量,命名空间域中的变量也属于全局变量。其符号为---“::”

int main()
{// 这⾥默认是访问的是全局的rand函数指针 printf("%p\n", rand);// 这⾥指定bit命名空间中的rand printf("%d\n", XY::rand);return 0;
}

特别的,当要访问的是全局变量中的值,域作用限定符的用法为:

int main()
{printf("%d ",::rand);
}

namespace的定义

• 定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。

namespace xy
{int rand=0;void fun(int a,int b){cout<<a+b<<endl; }
}

• namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以下⾯的rand不在冲突了。

• C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/ 类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响 编译查找逻辑,还会影响变量的⽣命周期,命名空间域和类域不影响变量⽣命周期。

• namespace只能定义在全局,当然他还可以嵌套定义。(如下)

namespace G
{namespace X{int rand = 1;int fun(int a, int b){return a + b;}struct node{int data;struct node* next;};}namespace Y{int rand = 2;int fun(int a, int b){return (a + b)*2;}struct node{int data;struct node* next;};}
}

嵌套命名的调用方式为:

int main()
{printf("%d\n", G::X::rand);printf("%d\n", G::Y::rand);printf("%d\n", G::X::Add(1, 2));printf("%d\n", G::Y::Add(1, 2));return 0;
}

• 项⽬⼯程中多⽂件中定义的同名namespace会认为是⼀个namespace,不会冲突。(自动合二为一)

• C++标准库都放在⼀个叫std(standard)的命名空间中。

命名空间的使用

编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间⾥⾯去查找。所以下⾯程序会编译报错。所以我们要使⽤命名空间中定义的变量/函数,有三种⽅式:

• 指定命名空间访问,项⽬中推荐这种⽅式。

• using将命名空间中某个成员展开,项⽬中经常访问的不存在冲突的成员推荐这种⽅式。

• 展开命名空间中全部成员,项⽬不推荐,冲突⻛险很⼤,⽇常⼩练习程序为了⽅便推荐使⽤。

namespace G
{int a = 0;int b = 1;
}// 指定命名空间访问 
int main()
{printf("%d\n", G::a);return 0; 
}
// using将命名空间中某个成员展开 
using G::b;
int main()
{printf("%d\n", G::a);printf("%d\n", b);return 0; 
}
// 展开命名空间中全部成员 
using namespce G;
int main()
{printf("%d\n", a);printf("%d\n", b);return 0; 
}

C++的输入与输出

在认识输入输出之前,我们先来了解一下系统的介绍:

<iostream>InputOutput的缩写,是标准的输⼊、输出流库,定义了标准的输⼊、输出对象。

std::cin istream 类的对象,它主要⾯向窄字符(narrow characters (of type char))的标准输 ⼊流。

std::cout ostream 类的对象,它主要⾯向窄字符的标准输出流。

std::endl 是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区。

• <<是流插入运算符,>>是流提取运算符。(C语⾔还⽤这两个运算符做位运算左移/右移)

• 使⽤C++输⼊输出更⽅便,不需要像printf/scanf输⼊输出时那样,需要⼿动指定格式,C++的输⼊输出可以⾃动识别变量类型(本质是通过函数重载实现的,这个后面的作品会细说),其实最重要的是 C++的流能更好的⽀持⾃定义类型对象的输⼊输出。

• IO流涉及类和对象,运算符重载、继承等很多⾯向对象的知识,由于是初识C++,所以本期我们只能简单认识⼀下C++ IO流的⽤法,后⾯我们会有专⻔的⼀个章节来细节IO流库。

cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要通过命名空间的使⽤⽅式去⽤他们。

• ⼀般⽇常练习中我们可以using namespace std,实际项⽬开发中不建议using namespace std。

• 这⾥我们没有包含<stdio.h>,也可以使⽤printf和scanf,在包含<iostream>间接包含了。

话不多说,上代码!

#include <iostream>
using namespace std;
int main()
{int a = 0;double b = 0.1;char c = 'x';cout << a << " " << b << " " << c << endl;std::cout << a << " " << b << " " << c << std::endl;scanf("%d%lf", &a, &b);printf("%d %lf\n", a, b);// 可以⾃动识别变量的类型 cin >> a;cin >> b >> c;cout << a << endl;cout << b << " " << c << endl;return 0;
}

缺省参数

• 缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调⽤该函数时,如果没有指定实参则采⽤该形参的缺省值,否则使⽤指定的实参,缺省参数分为全缺省和半缺省参数。(有些地⽅把缺省参数也叫默认参数)

• 全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往左依次连续缺省,不能间隔跳跃给缺省值。

• 带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参。

• 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省 值。

#include <iostream>
#include <assert.h>
using namespace std;
void Func(int a = 0)
{cout << a << endl;
}
int main()
{Func(); // 没有传参时,使⽤参数的默认值 Func(10); // 传参时,使⽤指定的实参 return 0;
}
#include <iostream>
using namespace std;
// 全缺省 
void Func1(int a = 10, int b = 20, int c = 30)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
// 半缺省 
void Func2(int a, int b = 10, int c = 20)
{cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl << endl;
}
int main()
{Func1();Func1(1);Func1(1,2);Func1(1,2,3);Func2(100);Func2(100, 200);Func2(100, 200, 300);return 0;
}

*这里给大家做一个比喻,缺省参数就好像我们生活中的备胎一样,我们不能做生活中的缺省参数哦~


函数重载

C++⽀持在同⼀作⽤域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者类型不同。这样C++函数调⽤就表现出了多态⾏为,使⽤更灵活。C语⾔是不⽀持同⼀作⽤域中出现同名函数的。

上代码:

#include<iostream>
using namespace std;
// 1、参数类型不同 
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、参数个数不同 
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同(本质上是类型不同) 
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}

!返回值不同不能作为重载条件,因为调⽤时也⽆法区分

// 下⾯两个函数构成重载 
// f()但是调⽤时,会报错,存在歧义,编译器不知道调⽤谁 
void f1()
{cout << "f()" << endl;
}
void f1(int a = 10)
{cout << "f(int a)" << endl;
}

结尾

以上便是本期的全部内容~感谢各位朋友的支持,后续我会努力创作出更多质量更好的文章,敬请期待哦~

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

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

相关文章

基于K210智能人脸识别+车牌识别系统(完整工程资料源码)

运行效果&#xff1a; 基于K210的智能人脸与车牌识别系统工程 目录&#xff1a; 运行效果&#xff1a; 目录&#xff1a; 前言&#xff1a; 一、国内外研究现状与发展趋势 二、相关技术基础 2.1 人脸识别技术 2.2 车牌识别技术 三、智能小区门禁系统设计 3.1 系统设计方案 3.2 …

卓越运营必备神器:规划复杂项目、使用标准的项目模板,看Minitab Workspace!

可确保过程与产品卓越性的可视化工具 您是否知道Minitab Workspace是专门为Minitab统计软件配套而设计的&#xff1f; 您和您的团队或许会面临以下相关问题: 1) 在规划复杂项目上存在困难&#xff0c;如业务优化项目; 2) 因完成工作需要而使用多种未知品牌的产品; 3) 缺乏…

一款好用的开源网站内容管理系统

今天给大家介绍的是一款开源网站内容管理系统&#xff08;灵活、易用&#xff0c;性能良好、运行稳定&#xff0c;轻松管理建设网站&#xff09; 官网&#xff1a;https://www.ujcms.com/ 介绍 客户端兼容Edge&#xff08;Chromium版&#xff09;、谷歌浏览器&#xff08;Chro…

AI称重收银一体秤

系统介绍 专门为零售行业的连锁店量身打造的收银系统&#xff0c;适用于常规超市、生鲜超市、水果店、便利店、零食专卖店、服装店、母婴用品、农贸市场等类型的门店使用。同时线上线下数据打通&#xff0c;线下收银的数据与小程序私域商城中的数据完全同步&#xff0c;如商品…

MMC和eMMC的区别

MMC 和 eMMC 的区别 1. MMC MMC&#xff08;MultiMediaCard&#xff09;是一种接口协议&#xff0c;定义了符合这一接口的内存器&#xff0c;称为 MMC 储存体或 MMC 卡。它是一种非易失性存储器件&#xff0c;广泛应用于消费类电子产品中。 1.1 外观及引脚定义 MMC卡共有七个…

LLM之本地部署GraphRAG(GLM-4+Xinference的embedding模型)(附带ollma部署方式)

前言 有空再写 微软开源的GraphRAG默认是使用openai的接口的&#xff08;GPT的接口那是要money的&#xff09;&#xff0c;于是就研究了如何使用开源模型本地部署。 源码地址&#xff1a;https://github.com/microsoft/graphrag 操作文档&#xff1a;https://microsoft.git…

nextjs 实现TodoList网页应用案例

参考&#xff1a; https://nextjs.org/ Next.js 是用于网络的一种 React 框架。一些世界上最大的公司在使用它&#xff0c;它能够借助 React 组件的力量让您创建高质量的网络应用程序。 1、创建项目&#xff1a; 另外注意&#xff1a;pages与app路由存在冲突&#xff0c;如果有…

Jenkins未授权访问漏洞 *

漏洞复现 步骤一&#xff1a;使用以下fofa语法进行产品搜索.... port"8080" && app"JENKINS" && title"Dashboard [Jenkins]" 步骤二&#xff1a;在打开的URL中...点击Manage Jenkins --> Scritp Console在执行以下命令..…

leetcode数论(​3044. 出现频率最高的质数)

前言 经过前期的基础训练以及部分实战练习&#xff0c;粗略掌握了各种题型的解题思路。现阶段开始专项练习。 描述 给你一个大小为 m x n 、下标从 0 开始的二维矩阵 mat 。在每个单元格&#xff0c;你可以按以下方式生成数字&#xff1a; 最多有 8 条路径可以选择&#xff1…

通俗易懂!495页看漫画学Python入门教程(全彩版)Git首发破万Star

前言 在编程的世界里&#xff0c;Python无疑是一颗璀璨的明星。从最初作为打发圣诞节闲暇时间的项目&#xff0c;到如今成为最受欢迎的程序设计语言之一&#xff0c;Python以其简洁、易学、强大的特点吸引了无数编程爱好者。然而&#xff0c;对于初学者来说&#xff0c;编程的…

【redis 第八篇章】链表结构

一、数组和链表 1、数组 数组会在内存中开辟一块连续的空间存储数据&#xff0c;这种存储方式有利也有弊端。当获取数据的时候&#xff0c;直接通过下标值就可以获取到对应的元素&#xff0c;时间复杂度为 O(1)。但是如果新增或者删除数据会移动大量的数据&#xff0c;时间复…

范伟:大叔这句是咱俩合唱的,赵本山:我唱不上去!——小品《门神》(下)的台词与解说

范伟&#xff1a;大叔这句是咱俩合唱的&#xff0c;赵本山&#xff1a;我唱不上去&#xff01; ——小品《门神》&#xff08;下&#xff09;的台词与解说 &#xff08;接上&#xff09; 范伟&#xff1a;大叔快快快走 赵本山&#xff1a;干啥 范伟&#xff1a;上咱家过年…

苹果手机锁屏怎么设置?3个技巧,教你快速设置

在科技与创意交织的时代&#xff0c;苹果手机以其简约而不失优雅的设计&#xff0c;成为了我们日常生活中不可或缺的一部分。而作为手机的【第一印象】&#xff0c;锁屏界面更是彰显用户个性的关键所在。那么&#xff0c;苹果手机锁屏怎么设置呢&#xff1f;接下来&#xff0c;…

AI生成PPT?三款工具让总结更轻松

哎呀&#xff0c;职场新人们&#xff0c;你们是不是也跟我一样&#xff0c;刚开始做PPT的时候&#xff0c;感觉像是走进了一个大迷宫&#xff0c;脑袋里装满了想法&#xff0c;但就是不知道怎么把它们变成一页页漂亮的幻灯片&#xff1f;别急&#xff0c;今天咱们就来聊聊三个超…

【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载 本章将分享C增加的几种常见特性&#xff0c;主要内容为引用与内联函数 | auto关键字与for循环 | 指针空值&#xff0c;这些知识看似很多&#xff0c;实际也不少。本章篇幅长&#…

C# Unity 面向对象补全计划 七大原则 之 里氏替换

本文仅作学习笔记与交流&#xff0c;不作任何商业用途&#xff0c;作者能力有限&#xff0c;如有不足还请斧正 本系列作为七大原则和设计模式的进阶知识&#xff0c;看不懂没关系 请看专栏&#xff1a;http://t.csdnimg.cn/mIitr&#xff0c;尤其是关于继承的两篇文章&#xff…

形参和实参的运用

形式参数&#xff1a;定义函数时括号中的变量。只有被调用时才被初始化&#xff0c;函数调用完成后自动销毁&#xff0c;只在函数中有效。 实际参数&#xff1a;真实传递给函数的参数&#xff0c;可以是常量、变量、表达式、函数等。无论实参是何种类型&#xff0c;在调用函数…

DBMS 与 RDBMS

DBMS 与 RDBMS 了解数据库什么是数据库管理系统&#xff1f;Types of DBMS 数据库管理系统的类型T数据库管理系统的好处 关系型数据库管理系统的优点 【纪录片】中国数据库前世今生 在数字化潮流席卷全球的今天&#xff0c;数据库作为IT技术领域的“活化石”&#xff0c;已成为…

JAVA(IO流)7.31

ok了家人们今天还是学习IO流&#xff0c; 一.打印流【了解】 1.1 打印流的概述 我们平时使用的System语句就是调用了print()方法和println()方法。 这两个方法都来自于 java.io.PrintStream 类。 作用&#xff1a; 该类能够方便地打印各种数据类型的值&#xff0c;写入数据后…

【Web】TFCCTF 2024 部分题解

目录 GREETINGS SURFING SAFE_CONTENT FLASK DESTROYER GREETINGS 打express的SSTI GitHub - TheWation/NodeJsSSTI: Express app with Pug templates demonstrating SSTI vulnerability and secure implementation for educational purposes. payload: /result?user…