【第一节】从C语言到C++

目录

一、面向对象编程

1.早期概念

2.发展与普及

3. 现代发展

二、从C语言到C++

1.关于堆内存的使用

2.关于函数重载

3.关于默认参数

4.引用

5.引用参数

6.作用域符号

三、C++的输入输出机制


一、面向对象编程

        面向对象编程(Object-Oriented Programming,简称OOP)是一种计算机编程范式,它使用“对象”来设计应用程序和计算机程序。这种编程范式强调数据和操作数据的函数(方法)的封装,以及对象之间的交互。面向对象编程的由来和发展可以追溯到20世纪60年代,以下是其主要的发展历程:

1.早期概念

  • Simula语言(1960年代):被认为是第一个引入面向对象概念的编程语言。Simula引入了类(class)和对象(object)的概念,以及继承和动态绑定等特性。

  • Smalltalk语言(1970年代):由Alan Kay等人开发,是第一个完全基于面向对象概念的编程语言。Smalltalk对后来的面向对象编程语言产生了深远影响,它定义了许多现代OOP语言的特性,如消息传递、类和对象、继承等。

2.发展与普及

  • C++语言(1980年代):由Bjarne Stroustrup开发,最初称为“C with Classes”。C++在C语言的基础上增加了类和对象的概念,支持面向对象编程,同时也保持了对C语言的兼容性。C++的成功使得面向对象编程开始广泛流行。

  • Objective-C语言(1980年代):由Brad Cox和Tom Love开发,是另一种支持面向对象编程的语言,后来被苹果公司用于开发Mac OS X和iOS应用程序。

  • Java语言(1990年代):由Sun Microsystems的James Gosling等人开发。Java是一种完全面向对象的编程语言,它的跨平台特性(通过Java虚拟机实现)和简单性使其迅速成为主流编程语言之一。

  • Python、Ruby等语言(1990年代至今):这些语言都支持面向对象编程,并且各自以简洁的语法和强大的功能吸引了大量开发者。

3. 现代发展

  • 多范式编程语言:现代编程语言如C#、JavaScript、Swift等,虽然支持面向对象编程,但也支持其他编程范式,如函数式编程。

  • 设计模式和框架:随着面向对象编程的普及,出现了许多设计模式(如单例模式、观察者模式等)和框架(如Spring、Hibernate等),这些都极大地丰富了面向对象编程的实践。

        面向对象编程的核心概念包括封装、继承和多态,这些概念使得代码更加模块化、可重用和易于维护。随着技术的发展,面向对象编程继续在软件开发领域扮演着重要角色。

 

二、从C语言到C++

        C++是C的扩展,C是C++的子集,C++包括C的全部特征、属性和优点。同时,增加了对面向对象编程的完全支持。接下来我们先了解C++一些特点,帮助大家更好的从C过度到C++的基本使用。

1.关于堆内存的使用

        C++中申请堆空间用的是new与delete运算符,这两个类似于c语言中的malloc与free函数。
new使用方式如下所示:
语法:
指针变量 = new 数据类型:
指针变量 = new 数据类型[长度n];
例如:
int *p; pnew int;
char *pStr = new char[50];

delete使用方式如下:
语法:
delete 指针变量:
delete[]指针变量;

例如:
delete p;
delete [] pStr;//对于数组

代码示例:

#include <iostream>using namespace std;
int main() {int* p = new int(33);//分配一个整数空间4字节,圆括号代表初始化值cout << *p << endl;int* p2 = new int[10];//分配连续的10个整数空间40字节delete p;delete[] p2;return 0;
}

        我们可以把new和delete对比着malloc与free来学习:
1)从示例中可以看出使用new申请空间并不是以字节为单位的,而是以数据类型,从而
也无需强制转换。
2)要申请多个数据,需要使用了中括号,释放这块内存的时候也需要中括号。
3)注意中括号和圆括号的差别,圆括号是初始化,中括号是申请多个的意思。

 

2.关于函数重载

        相同的作用域,如果两个函数名称相同,面参数不同,我们把它们称为函数重载,函数
重载又称为函数的多态性。请一定注意那个前提:相同的作用域、相同的作用域,相同的作用域。

以下几种方式会构成函数重载

形参数量不同
形参类型不同
形参的顺序不同
形参数量和形参类型都不同

        总而言之,就是参数的不同会构成重载,那么构成了重载有什么用处呢?
如果我们的算法需要支持多个数据类型,比如求两个数的和,想要支持整数,浮点数甚至字符串。
如果没有函数重载实现如下:

int AdditionInt(int numA, int numB) {return numA + numB;
}
double AdditionDouble(double numA, int numB) {return numA + numB;
}
int AdditionStr(char* pNumA, char* pNumB) {int nNumA = 0;int nNumB = 0;sscanf_s(pNumA, "%d", &nNumA);sscanf_s(pNumB, "%d", &nNumB);return nNumA + nNumB;
}

        对于函数的使用者而言,需要记住三个功能类似,但是名称不同的函数。而代码写成下面的样子,就可以解决这个问题:

int Addition(int numA, int numB) {return numA + numB;
}double Addition(double numA, int numB) {return numA + numB;
}
int Addition(char* pNumA, char* pNumB) {int nNumA = 0;int nNumB = 0; sscanf_s(pNumA, "%d", &nNumA);sscanf_s(pNumB, "%d", &nNumB);return nNumA + nNumB;
}

        此代码在C语言中会因为函数重名而编译失败,但在C++中这则是一个典型的重载函数C++会根据传入函数参数的不同进而决定调用哪个函数。有了这个机制,使用者仅仅需要记住一个函数名即可,随意的往里面传递各种数据类型。函数重载的本质,以上的同名函数,在C++看来实际上是不同的函数名称,C++为了支持这种特性,进而提出了名称粉碎/名字改编(name managling)机制,以上面的函数为例,他们的函数名分别不同。根据函数参数的不同,把函数修改成了不同的名字。

3.关于默认参数

        在C++中,还有一个不错的机制,叫做默认参数,函数声明或者定义的时候,可以给形参赋一些默认值,调用函数时,若没有给出实参,则按指定的默认值进行工作。

int Addition(int a, int b, int c = 0, int d = 0, int e = 0) {return a + b + c + d + e;
}

        在以上这个例子中,调用函数的时候,可以传递两个参数,也可以传递三个,四个,五传递的参数不足五个的时候,后面的会默认的被传递0。个。需要注意的几个问题:
1)函数没有声明时,在函数定义中指定形参的默认值
2)函数既有定义又有声明时,声明时指定后,定义后就不能再指定默认值
3)当使用了默认参数的同时还使用了重载容易造成二义性

#include<iostream>
using namespace std;int fun(int a, int b = 5) {//声明与定义在一起,直接写默认参数就可以return a + b;
}int fun(int a, int b, int c = 3);//1声明与定义不能同时带默认参数int  //2这里造成了二义性int main(void) {cout << fun(3) << endl;cout << fun(3, 4) << endl;cout << fun(3, 4, 5) << endl;return 0;
}int fun(int a, int b, int c) {return a + b + c;
}

4)默认值的定义必须遵守从右到左的顺序,如果某个形参没有默认值,则它左边的参数就不能有默认值。

void funcl(int a, double b = 4.5, int c = 3);//合法
void funcl(int a = 1, double b, int c = 3);//不合法

函数调用时,实参与形参按从左到右的顺序进行匹配。

 

4.引用

        引用是C++引入的新语言特性,是C++常用的一个重要内容之一,正确、灵活地使用引用,可以使程序简洁、高效。
引用是给一个变量起别名,定义引用的一般格式:
类型 &引用名 = 变量名;
int nSize;
&nNum = nSize;

需要注意的是:
1)由于引用就是变量的一个别名,因此上例中nSize的地址与m的地址是完全一样的;
2)定义引用时一定要初始化,指明该引用变量是谁的别名;
3 )引用一经初始化不能再引用其他对象。

示例代码:

#include <iostream>
using namespace std;int main(void) {int val = 100;//int &refval; //Error,引用必须初始化int& refval = val; refval = 200;//将200赋值给refval//实际上改变的是val这个变量cout << "val=" << val << endl;int val2 = 500;refval = val2;//不代表将refval引用至va12这个变量//仅仅只是代表将va12赋值给refvalcout<< "val="<<val<<endl;
}

5.引用参数

        引用传递方式是在函数定义时在形参前面加上引用运算符"&”
        例如:int swap(int &nNumA, int &nNumB);
        按值传递方式容易理解,但形参值的改变不能对实参产生影响,地址传递方式通过形参的改变使相应的实参改变,但是C++的设计者认为这恰巧是C语言程序容易产生错误且难以阅读的原因。
        于是引用在这里发挥了重要的作用,引用作为参数对形参的任何操作都能改变相应的实参的数据,又使函数调用显得方便、自然。

代码示例:

#include <iostream>
using namespace std;//引用作为参数传递
void swap(int& x, int& y) {int temp = x;x = y;y = temp;
}
int main(void) {int a = 5;int b = 6;swap(a, b);//在函数调用时,引用被初始化x=a,y=b;cout<< "a=" << a <<"b=" << b << endl;return 0;
}

引用和指针的区别:
引用访问一个变量是直接访问,而指针里面需要保存变量的地址,所以是间接访间
引用是一个变量的别名,本身不单独分配自己的内存空间,它不是一个单独的变量,而指针有自己的内存空间
引用一经初始化不能再引用其它变量,而指针可以(非const指针)
尽可能使用引用,不得已时使用指针。

三种传参方式比较:
值传递:实参要初始化形参要分配空间,将实参内容拷贝到形参
指针传递:传递的是地址,能够间接修改函数外部的变量,其本质仍是值传递。
引用传递:实参初始化形参的时候不分配空间,而是形参实参融为一体,修改了形参就是改变了实参。

 

6.作用域符号

在C++中,双冒号::被称为作用域解析运算符(Scope Resolution Operator)。它主要用于以下几个方面:

1. 访问全局变量:当局部变量与全局变量同名时,可以使用::来访问全局变量。例如:

int x = 10; // 全局变量
void someFunction() {int x = 20; // 局部变量std::cout << x << std::endl; // 输出局部变量x的值,即20std::cout << ::x << std::endl; // 输出全局变量x的值,即10
}

2. 访问类成员:在类的外部定义成员函数时,需要使用::来指定该函数属于哪个类。例如:

class MyClass {
public:void myFunction();
};void MyClass::myFunction() {// 函数实现
}

3. 访问命名空间成员:当一个命名空间中的名称与另一个命名空间或全局作用域中的名称冲突时,可以使用::来指定访问哪个命名空间中的成员。例如:

namespace MyNamespace {int x = 10;
}int x = 20;int main() {std::cout << x << std::endl; // 输出全局变量x的值,即20std::cout << MyNamespace::x << std::endl; // 输出MyNamespace中的x的值,即10return 0;
}

        作用域解析运算符::在C++中是一个非常关键的工具,它帮助程序员清晰地管理和访问不同作用域中的变量和函数,有效地解决了命名冲突的问题。

三、C++的输入输出机制

        I/0流是指输入输出的一系列数据流,输出使用插入操作符“<<”向cout 输出流中插入字符。
在使用 cout 和 cin的时候,需要包含 iostream 这个头文件,并且使用 std 这个命名空间。如下所示:

#include <iostream>
using namespace std;int main() {cout << "this is a program";return 0;
}

输入使用抽取操作符“>>”从cin输入流中抽取字符

#include <iostream>
using namespace std;int main() {int myage;cin >> myage;int i; float f; long l; cin >> i >> f >> l; return 0;
}

C++的输出能够控制输出的数据格式,常用格式如下:

控制符描述
dec按10进制输出
hex按16进制输出
oct按8进制输出
setfi1l(c)设填充字符为c
setprecision(n)设置显示小数精度为n位
setw(n)设域宽为n个子符
setiosflags(ios::fixed)小数方式表示
setiosflags(ios::scientific)指数表示
setiosflags(ios::left)左对齐
setiosflags(ios::right)右对齐

输出宽度示例
cout<<setw(8)<<10<<endl;

若数值10和20均按照宽度8输出
cout<<setw(8)<<10<<setw(8)<<20<<endl;

如果一个值的位数大于setw(n)确定的宽度位数,则按原宽度输出,例如
float amount=4.53671;
cout<<setw(4)<<amount<<endl ;

输出八进制,十六进制和十进制数示例:

#include <iostream>
#include <iomanip>
#include<stdlib.h>
using std::wcout;
using std::endl;
using std::setiosflags;
using std::ios; int main() {int number = 1001;wcout << L"Decimal:"<< std::dec << number << endl \<< L"Hexadecimal :" << std::hex << number << endl \<< L"Octal:" << L"Hexadecimal :" << std::hex \<< std::oct << number << endl \<< setiosflags(ios::uppercase) << number << endl; system("pause");return 0;
}

控制左右对齐输出,默认情况下,I/0流以右对齐格式显示。

#include <iostream>
#include <iomanip>#include<stdlib.h>
using std::endl; using std::setiosflags; 
using std::setw; using std::wcout;int main() {wcout << setiosflags(std::ios::left) << setw(5) << 1 << setw(5) << 2 << setw(5) << 3 << endl; wcout << setiosflags(std::ios::right) << setw(5) << 1 << setw(5) << 2 << setw(5) << 3 << endl; system("pause");return 0;
}

以上是 C++提供的输入输出方式,使用printf/scanf 依然也是可以的。

如下输出打印一个菱形图案:

4ff54b3d79b14d0e8eeb48bf05ab85bd.png

#include <iostream>
#include <iomanip>
#include <stdlib.h>
using std::wcout; 
using std::endl;
using std::setfill; 
using std::setw; int main() {for (int i = 0; i < 7; i++) {if (i < 4) {wcout << setfill(L' ') << setw(4 - i) << L' ';wcout << setfill(L'*') << setw(i * 2 + 1) << L'*' << endl;}else {wcout << setfill(L' ') << setw(i - 2) << L' ';wcout << setfill(L'*') << setw(i - (i - 4) * 3 + 1) << L'*' << endl;}}system("pause");return 0;
}

 

 

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

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

相关文章

如何进一步缩短Python性能

1、问题背景 给定一个(x,y)处的节点网格&#xff0c;每个节点有一个值(0…255)从0开始。有N个输入坐标&#xff0c;每个坐标在(0…x, 0…y)的范围内。一个值Z&#xff0c;它定义了节点的“邻域”。增加输入坐标及其邻居节点的值。网格边缘之外的邻居被忽略。基准案例&#xff…

产教协同|暴雨AI算力赋能传媒实践教学

近日&#xff0c;“第七届传媒实践教学创新研讨会暨中国高校影视学会实验教学专业委员会年会”在美丽的山城重庆成功举办。本次大会以“拥抱AI&#xff0c;融合共生”为主题&#xff0c;吸引了来自全国200多所高校、30多家企业以及700多位大视听实践教学产学研用各界专家、学者…

Data Lakehouse:你的下一个数据仓库

作者&#xff1a;张友东 StarRocks TSC member/镜舟科技 CTO 数据分析是现代企业和组织决策过程中不可或缺的一部分&#xff0c;数据分析技术经过数十年的发展&#xff0c;需求场景从 BI 报表到数据探寻、实时预测、用户画像等不断丰富&#xff0c;技术架构经历从数据仓库、数据…

【AIGC】GPT-4o技术分析-浅谈

GPT-4o&#xff1a;人工智能技术的全新里程碑 一、引言二、GPT系列版本间的对比分析三、GPT-4o的技术能力分析多模态处理能力速度与性能优化情感理解与表达能力 四、个人整体感受五、结语 一、引言 在人工智能技术的浪潮中&#xff0c;OpenAI再次以其卓越的创新能力引领潮流。近…

15.Redis之持久化

0.知识引入 mysql的事务,有四个比较核心的特性. 1. 原子性 2.一致性 3.持久性 >(和持久化说的是一回事)【把数据存储在硬盘 >持久把数据存储茌内存上>不持久~】【重启进程/重启主机 之后,数据是否存在!!】 4.隔离性~ Redis 是一个 内存 数据库.把数据存储在内存中的…

RFID芯片掼蛋牌:高科技与传统玩法结合,游戏体验焕然一新。

火爆“出圈”的掼蛋&#xff0c;是一种玩法相当鲜明的智力游戏。近年来得到了不少的推广和发展&#xff0c;各地举办了各种掼蛋比赛和活动&#xff0c;吸引了大量的参赛者和观众。此外&#xff0c;一些企业和机构也开始将掼蛋作为一种企业文化或者社交活动的方式&#xff0c;通…

灯下黑”挖出国内知名安全平台某BUF的CSRF漏洞

漏洞复现&#xff1a; 漏洞点在删除文章的地方&#xff0c;首先为了测试先发布一篇文章 发布之后我们可以查看文章&#xff0c;注意url中的一串数字&#xff0c;就是这篇文章的id&#xff0c;如下如&#xff1a; 这里的文章id是“271825”&#xff0c;首先抓一下删除文章的数据…

JavaScript基础(十)

上一篇学了各种数组方法&#xff0c;正好先做个练习回忆一下: 排序并去重 我随便写一组数&#xff0c;要求排好并去掉重复的: var arr [2,8,1,7,2,6,1,5,2,7,6,5]; for (var i0; i<arr.length; i){ for (var ji1; j<arr.length; j){ if(arr[i]arr[j]){ arr.splice(j,1)…

LeetCode 474.一和零

没做出来&#xff0c;最后看了解析&#xff0c;看了半天才懂。 我一开始把这个题当成多重背包来做了&#xff0c;因为有0和1两个参数需要考虑&#xff0c;但是中间很多情况不知道怎么处理。后面看了解析才知道这是个01背包问题&#xff0c;0和1都是一个物品上的属性&#xff0c…

K-means 聚类模型详解

K-means 聚类模型详解 K-means 是一种常用的无监督学习算法&#xff0c;用于将数据集分成 K 个簇。其目标是最小化各个簇内数据点到簇中心的距离平方和。K-means 广泛应用于图像压缩、市场细分、模式识别等领域。 算法步骤 初始化: 随机选择 K 个初始簇中心&#xff08;质心…

【主题广泛|投稿优惠】2024年区块链、网络与物联网国际会议(BNIT 2024)

2024年区块链、网络与物联网国际会议&#xff08;BNIT 2024&#xff09; 2024 International Conference on Blockchain, Networks, and the Internet of Things 【重要信息】 大会地点&#xff1a;深圳 大会官网&#xff1a;http://www.icbnit.com 投稿邮箱&#xff1a;icbni…

揭秘智慧校园:可视化技术引领教育新篇章

随着科技的飞速发展&#xff0c;我们的生活方式正在经历一场前所未有的变革。而在这场变革中&#xff0c;学校作为培养未来人才的重要基地&#xff0c;也在不断地探索与创新。 一、什么是校园可视化&#xff1f; 校园可视化&#xff0c;就是通过先进的信息技术&#xff0c;将学…

永久免费SSL证书领取流程

一、SSL证书的前世今生 起源&#xff1a; SSL证书起源于1994年&#xff0c;当时网景公司&#xff08;Netscape&#xff09;推出了安全套接字层&#xff08;SSL&#xff0c;Secure Sockets Layer&#xff09;协议&#xff0c;这是一种加密通信协议&#xff0c;用于在客户端和服…

武汉城投城更公司与竹云科技签署战略协议,携手构建智慧城市新未来!

2024年5月16日&#xff0c;武汉城投城更公司与深圳竹云科技股份有限公司&#xff08;以下简称“竹云”&#xff09;签订战略合作协议&#xff0c;双方将深入推进产业项目合作。 签约现场&#xff0c;双方围绕产业项目合作方向、路径和内容等进行了全面深入交流。城投城更公司党…

第五届武汉纺织大学ACM程序设计竞赛 个人题解(待补完)

前言&#xff1a; 上周周日教练要求打的一场重现赛&#xff0c;时长五个小时&#xff0c;题目难度还行&#xff0c;除了部分题目前我还写不出来之外&#xff0c;大部分题都写完或补完了&#xff0c;这边给出比赛链接和我的代码&#xff08;有些是队友的&#xff09;和题解。 正…

这些项目,我当初但凡参与一个,现在也不至于还是个程序员

10年前&#xff0c;我刚开始干开发不久&#xff0c;我觉得这真是一个有前景的职业&#xff0c;我觉得我的未来会无限广阔&#xff0c;我觉得再过几年&#xff0c;我一定工资不菲。于是我开始像很多大佬说的那样&#xff0c;开始制定职业规划&#xff0c;并且坚决执行。但过去这…

Midjourney设计服装5步实操分享!(实操干货系列)

2k字讲清楚如何在有限素材的基础上&#xff0c;用MJ随机生成设计服装&#xff0c;附本人实操步骤图~ 灵感来源&#xff1a;既然Midjourney&#xff08;MJ&#xff09;能够参考图片进行绘图&#xff0c;那么&#xff0c;提供一些素材&#xff0c;借由MJ的随机成图来寻找一些服装…

香橙派Kunpeng Pro评测

有幸受邀评测香橙派与华为鲲鹏在2024年5月12刚刚联合发布的新品香橙派Kunpeng Pro。 本文将从软硬件、AI算法测试等角度简单分享一下博主拿到板子以来感受与所做的评测。 一、硬件 香橙派Kunpeng Pro实物图 处理器方面&#xff0c;香橙派Kunpeng Pro采用了4核64位armv8架构处…

生产者延迟消息和重试机制

messageDelayLevel1s 5s 10s 30s 1m 2m 3m 4m 5m 6m 7m 8m 9m 10m 20m 30m 1h 2h 延迟消息级别public PutMessageResult putMessage(final MessageExtBrokerInner msg) {//事务消息处理if (tranType MessageSysFlag.TRANSACTION_NOT_TYPE|| tranType MessageSysFlag.TRANSACT…

Android manifest清单文件意外权限来源和合并规则

问题背景 当自写APP发现无缘无故多申请了多个权限,其中一个就是:android.permission.WAKE_LOCK. 一想就知道如果并非自己在APP main中引入的,那就是依赖的库清单文件导入进来的. 定位问题 定位手段 1.manifest-merger-buildVariant-report.txt 根据其内容可知, WAKE_LOCK 权…