目录
[C语言和C++ 的区别](#C语言和C++ 的区别)
c++的基本介绍
C++是一种通用的高级编程语言,它是从C语言发展而来的。C++在C语言的基础上增加了许多新的特性和功能,使得它成为一种更强大、更灵活的编程语言。
C++具有面向对象的编程能力,可以使用类和对象来组织和管理代码。它支持封装、继承和多态等面向对象编程的特性,可以更好地组织和管理大型项目的代码。
C++也可以进行底层系统编程,它提供了许多与硬件交互和操作系统相关的功能,例如内存管理、指针操作和文件读写等。
C++是一种编译型语言,它将源代码编译成机器码,然后可以在各种不同的平台上运行。C++的编译器非常普及,几乎可以在任何操作系统上找到,包括Windows、Linux、Mac等。
C++具有高性能和效率,它可以直接访问内存和硬件资源,不需要依赖其他高级语言的运行时环境。这使得C++成为一种特别适合开发性能敏感的应用程序,如游戏引擎、图形界面和嵌入式系统等。
总的来说,C++是一种功能强大、灵活且高效的编程语言,适用于各种不同的应用场景和项目规模。
C语言和C++ 的区别
面向对象:C++引入了面向对象编程的概念,允许使用类、对象、继承、多态等特性进行程序设计,而C语言则没有这些特性。
类型检查:C++具有更严格的类型检查机制,可以在编译阶段捕获更多的类型错误,提高了程序的安全性和可靠性。而C语言对类型检查的支持较弱。
标准库:C++标准库提供了更多的功能和组件,如容器、算法、文件操作等,使得开发更加方便,而C语言的标准库相对较小。
异常处理:C++支持异常处理的机制,可以捕获和处理程序运行时的异常情况,而C语言没有这个特性。
扩展性:C++允许通过编写类的扩展来实现新的功能,而C语言则需要通过编写新的函数来实现。
兼容性:C++是C语言的超集,几乎所有的C语言代码都可以在C++中编译和运行,但C++还引入了一些新的特性和语法,可能导致部分C语言代码无法在C++中编译。
总的来说,C++在C语言的基础上引入了面向对象编程的特性,并提供了更多的功能和安全性,适用于更复杂的程序开发。而C语言更加简洁和灵活,适用于一些对性能要求较高、对功能要求较简单的场景。
面向过程和面向对象的区别
【思考】如果把大象装进冰箱,应该怎么做?
1、 (我)打开冰箱
2、 (我)把大象放进去
3、 (我)把冰箱关上
上面的这种方式就是典型的面向过程编程思想,这种思想关注的重点是"过程",过程指的是一系列有序的步骤,只需要按照这个步骤来做,就可以得到预想的结果。这种思维方式偏向于计算机执行命令的本质。这种程序的特点是执行效率高(因为都是亲历亲为)。适合小体量软件项目编程,偏向性能的项目一般这样做。
使用面向对象的思想把大象装进冰箱。
1、 (我)把大象和冰箱拟人化。
2、 (我)给大象和冰箱安排任务。
3、 (自动)大象和冰箱执行任务。
面向对象的语言,关注的重点是"对象 "。在计算机中对象可以理解为一些列由于某种联系聚焦在一起的数据,在编程的过程中处理对象之间的关系。这种思考方式更近于人类的方式。这样的程序缺点在于执行效率底,但是编程效率高,适合大规模的软件项目。
总的来讲,面向过程是以"怎么解决问题"为核心,面向对象是以"谁来解决问题"为核心。
引用
引用从一定程度上讲是c语言中指针的平替,几乎被所有的面向对象编程语言所使用。引用相当于对某一目标变量起一个"别名", 操作引用与操作原变量完全一样。(ps:你要抓鲁迅确实关周树人的事)
cpp
#include <iostream>
using namespace std;
int main()
{
int a = 1;
int &b = a; // b是a的引用
b++;
cout << a << " " << &a << endl; // 2 0x61fe88
cout << b << " " << &b << endl; // 2 0x61fe88
return 0;
}
引用使用的注意事项
1、可以改变引用的值,但是不能成为其他变量的引用。
实例:
cpp
#include <iostream>
using namespace std;
int main()
{
int a = 1;
int &b = a; // b是a的引用
int c = 3;
b = c; // 赋值,不是引用,b还是a的引用
b++;
cout << a << " " << &a << endl; // 4 0x61fe88
cout << b << " " << &b << endl; // 4 0x61fe88
cout << c << " " << &c << endl; // 3 0x61fe84
return 0;
}
2、声明引用时,必须要初始化
实例:
cpp
#include <iostream>
using namespace std;
int main()
{
int a = 1;
// int &b; // 错误引用,必须初始化
return 0;
}
3、引用不能初始化为空
实例:
cpp
#include <iostream>
using namespace std;
int main()
{
int a = 1;
// int &b = NULL; // 错误引用不能初始化null
// int &c = nullptr; // 错误引用不能初始化nullptr
return 0;
}
4、声明引用的时候,初始化的值可以为纯数值,但是必须用 const 来修饰引用,表示引用为常量引用。
实例:
cpp
#include <iostream>
using namespace std;
int main()
{
const int &b = 12; // 常量引用
// b = 444; // 错误 常量引用的值无法被改变
cout << b << " " << &b << endl;
return 0;
}
5、可以将引用的地址赋值给一个指针,此时指针指向的还是原来的变量。
实例:
cpp
#include <iostream>
using namespace std;
int main()
{
int a = 1;
int &b = a;
int *c = &b; // c同时指向了A和B
cout << a << " " << &a << endl; // 1 0x61fe84
cout << b << " " << &b << endl; // 1 0x61fe84
cout << *c << " " << c << endl; // 1 0x61fe84
return 0;
}
6、可以使用const修饰引用,此时,无法直接通过引用改变原来的值,但是如果原来变量的值改变,引用的值也跟着改变。
实例:
cpp
#include <iostream>
using namespace std;
int main()
{
int a = 2;
const int &b = a;
// b++; // 错误 b是只读的
a++;
cout << a << " " << &a << endl; // 1 0x61fe84
cout << b << " " << &b << endl; // 1 0x61fe84
return 0;
}
7、引用作为参数进行定义的时候,在参数传参时,是不会产生副本 的,这样可以提高程序的运行效率在我们正常编程中,建议使用引用作为传递参数。引用参数不需要参与计算时,建议使用const进行修饰,避免误修改,提高引用的安全性。
实例:
cpp
#include <iostream>
using namespace std;
// 函数的功能是交换两个传入的参数原来变量的值。
void test(int &a,int &b)
{
a = a^b;
b = a^b;
a = a^b;
}
// 输出。
void test2(const int &a,const int &b)
{
cout << "a = " << a << endl;
cout << "b = " << b << endl;
}
int main()
{
int a1 = 1;
int b1 = 2;
test(a1,b1);
test2(a1,b1);
return 0;
}
赋值
通常编程中使用=进行赋值,C++新增了以下赋值语法。
cpp
#include <iostream>
using namespace std;
int main()
{
int a(1); // int a = 1;
cout << a << endl;
int b(a); // int b = a;
cout << b << endl;
int c(a+b); // int c = a + b;
cout << c << endl;
double d = 3.14;
int d2(d);
cout << d2 << endl; // 输出为3,浮点型转int型时会进行数据窄化处理,舍弃小数点后的数值(不会报错和警告)
int d3{d}; // C++11对此进行了升级:对数据窄化会做出警告(只是有个警告,其他没有任何改变)
cout << d3 << endl; // 3
return 0;
}
终端输入
cin
可以使用cin吧用户在命令行中输入的内容赋值到变量中, cin 与 cout 一样都属于 iostream 中的标准输入输出流。(遇到空格就会结束)
实例:
cpp
#include <iostream>
using namespace std;
int main()
{
int a;
// C++的字符串string
string str;
cout << "请输入一个数字和字符串" << endl;
cin >> a >> str; // 接收键盘输入,一个整数和一个字符串。可以连续操作
cout << a << " " << str << endl;
return 0;
}
getline
如果cin输入的字符串需要包含空格可以使用 getline(cin,str) 的方式
cpp
#include <iostream>
using namespace std;
int main()
{
// C++的字符串string
string str;
cout << "请输入一个字符串,可以包含空格,输入完成后点击回车" << endl;
getline(cin,str);
cout << str << endl;
return 0;
}
string字符串类
string不是C++的基本数据类型,他是一个C++标注库中的字符串类,使用时需要引入头文件#include<string>
string在绝大多数情况下可以替代C语言中的字符串,不必担心内存是否足够或字符串长度等。其中内部还包含了很多字符串处理函数,可以完成各种情况下的字符串处理功能。
string和C语言相同,字符串编码使用ASCII编码,不支持中文。
cpp
#include <iostream>
using namespace std;
int main()
{
string str = "helloworld";
cout << str.size() << endl; // 10
cout << str.length() << endl; // 10
cout << str.at(1) << endl; // e
return 0;
}
遍历方式
string支持多种遍历方式
1、普通遍历(以for循环为主)
cpp
#include <iostream>
using namespace std;
int main()
{
string str = "helloworld";
// 以for循环的方式遍历输出字符串
for(int i = 0;i < str.size();i++)
{
cout << str.at(i);
}
cout << endl;
return 0;
}
2、for each遍历方法
cpp
#include <iostream>
using namespace std;
int main()
{
string str = "helloworld";
// 以 for each的方式进行循环遍历字符串
for(char i:str)
{
cout << i;
}
return 0;
}
字符串和数字转换
istringstream:字符串转int类型
stringstream:int类型转字符串
cpp
#include <iostream>
#include <sstream> // 字符串流
using namespace std;
int main()
{
string s = "123";
// int i = s; // 错误
int i = 0;
// string → int
istringstream iss(s);
iss >> i;
cout << i << endl;
// int → string
// string s2 = i; // 错误
stringstream ss;
ss << i;
string s2 = ss.str();
cout << s2 << endl;
return 0;
}
函数
内联函数
内联函数用于取代C语言中宏定义的函数,使用inline修饰,将函数声明为内联函数。内联函数的正确使用可以提升程序的执行效率。内联函数在编译的时候,直接把函数体展开到主函数中编译,在运行时可以减少调用的开销。
虽然我们使用inline将函数进行了声明,但是函数执行时到底是不是内联函数,这个不是我们能决定的。编译器有自己的判断准则,我们只是给编译器提一个建议,具体是否变为内联函数,还是编译器自己决定的。
通常将具有以下性质的函数写为内联函数。
● 代码长度很短(5行以内)
● 不包含复杂的控制语句
● 频繁被调用
cpp
#include <iostream>
using namespace std;
// 内联函数
inline void pint_string(string str)
{
cout << str << endl;
}
int main()
{
pint_string("helloworld");
return 0;
}
函数重载overload
C++中允许多个函数使用同一个名称,这种用法就是函数重载,函数重载要求函数名称相同,但是参数不同(类型或者数量、前后顺序不同)。与返回值等其他因素无关。
cpp
#include <iostream>
using namespace std;
void print_show(int i)
{
cout << "调用了int重载" << i << endl;
}
// 错误名称一样,参数一样编译器无法区分
//void print_show(int d)
//{
// cout << "调用了int2重载" << d << endl;
//}
void print_show(string str)
{
cout << "调用了string重载" << str << endl;
}
// 错误与返回值类型无关
//string print_show(string str)
//{
// cout << "调用了string重载" << str << endl;
// return str;
//}
void print_show(double d)
{
cout << "调用了double重载" << d << endl;
}
int main()
{
print_show(1.2);
return 0;
}
哑元函数
函数的参数只有类型,没有名称,这样参数的就是哑元函数。
作用1:哑元函数用来区分函数重载
作用2:运算符重载中用到
作用3:历史遗留,向上兼容。
cpp
#include <iostream>
using namespace std;
// 哑元函数
void print_show(int t)
{
cout << "调用了int哑元函数" << t << endl;
}
void print_show(int i)
{
cout << "调用了int函数" << i << endl;
}
int main()
{
print_show(1,2);
return 0;
}
小练习:
1、键盘输入一个100-999之间的数,依次输出这个数的个十百位。
2、输入一行字符串,分别统计出其中的英文字母,数字和其他字符的个数。
参考代码
cpp
#include <iostream>
using namespace std;
void practice1()
{
int a;
while(1)
{
cout << "请输入一个100-999之间的数:";
cin >> a;
if(a<100 || a>999)
{
cout << "错误:请输入100-999!" << endl;
continue;
}
cout << "百位:" << a/100 << " 十位:" << (a/10)-(a/100)*10 <<" 个位:" << a-(a/10)*10 << endl;
}
}
void practice2()
{
string str;
int n=0;
int c=0;
int t=0;
while(1)
{
cout << "请输入一个字符串:";
getline(cin,str);
for( char i:str)
{
if(('a' <= i && i <= 'z')||('A' <= i && i <= 'Z'))
{
++c;
}
else if('0' <= i && i <= '9')
{
++n;
}
else
{
++t;
}
}
cout << "数字个数:" << n <<endl;
cout << "字母个数:" << c <<endl;
cout << "其他字符个数:" << t <<endl;
}
}
int main()
{
// practice1();
practice2();
return 0;
}