BeginnersBook-C---教程-一-

news/2024/10/24 18:13:43/文章来源:https://www.cnblogs.com/apachecn/p/18500083

BeginnersBook C++ 教程(一)

原文:BeginnersBook

协议:CC BY-NC-SA 4.0

C++ 中的for循环

原文: https://beginnersbook.com/2017/08/cpp-for-loop/

循环用于重复执行语句块,直到满足特定条件。例如,当您显示从 1 到 100 的数字时,您可能希望将变量的值设置为 1 并将其显示 100 次,在每次循环迭代时将其值增加 1。

在 C++ 中,我们有三种类型的基本循环:forwhiledo-while 。在本教程中,我们将学习如何在 C++ 中使用for 循环。

for循环的语法

for(initialization; condition ; increment/decrement)
{C++ statement(s);
}

for循环的执行流程

当程序执行时,解释器总是跟踪将要执行的语句。我们将其称为控制流程或程序的执行流程。

C++ for loop flow diagram

第一步:for循环中,初始化只发生一次,这意味着for循环的初始化部分只执行一次。

第二步: for循环中的条件在每次循环迭代时进行计算,如果条件为真,则for循环体内的语句将被执行。一旦条件返回falsefor循环中的语句就不会执行,并且控制被转移到程序中for循环后的下一个语句。

第三步:每次执行for循环体后,for循环的递增/递减部分更新循环计数器。

第四步:第三步后,控制跳转到第二步,重新求值条件。

从第二到第四的步骤重复,直到循环条件返回false

C++ 中的简单for循环示例

这里,在循环初始化部分中,将变量i的值设置为 1,条件是i <= 6,并且在每次循环迭代中,i的值递增 1。

#include <iostream>
using namespace std;
int main(){for(int i=1; i<=6; i++){/* This statement would be executed* repeatedly until the condition* i<=6 returns false.*/cout<<"Value of variable i is: "<<i<<endl;}return 0;
}

输出:

Value of variable i is: 1
Value of variable i is: 2
Value of variable i is: 3
Value of variable i is: 4
Value of variable i is: 5
Value of variable i is: 6

C++ 中的无限循环

当循环重复执行并且永不停止时,循环被认为是无限的。这通常是错误的。当你在for循环中设置条件时它永远不会返回false,它就会变成无限循环。

例如:

#include <iostream>
using namespace std;
int main(){for(int i=1; i>=1; i++){cout<<"Value of variable i is: "<<i<<endl;}return 0;
}

这是一个无限循环,因为我们递增i的值,因此它总是满足条件i <= 1,条件永远不会返回false

这是无限for循环的另一个例子:

// infinite loop
for ( ; ; ) {// statement(s)
}

示例:使用for循环显示数组元素

#include <iostream>
using namespace std;
int main(){int arr[]={21,9,56,99, 202};/* We have set the value of variable i* to 0 as the array index starts with 0* which means the first element of array * starts with zero index.*/for(int i=0; i<5; i++){cout<<arr[i]<<endl;}return 0;
}

输出:

21
9
56
99
202

C++ 中的while循环

原文: https://beginnersbook.com/2017/08/cpp-while-loop/

在上一篇教程中,我们讨论了for循环 。在本教程中,我们将讨论while循环。如前所述,循环用于重复执行程序语句块,直到给定的循环条件返回false

while循环的语法

while(condition)
{statement(s);
}

循环如何工作?

while循环中,首先计算条件,如果它返回true,则执行while循环中的语句,这会重复发生,直到条件返回false。当条件返回false时,控制流退出循环并跳转到程序中的while循环后的下一个语句。

注意:使用while循环时要注意的重点是,我们需要在while循环中使用递增或递减语句,以便循环变量在每次迭代时都会发生变化,并且在某些情况下返回false。这样我们就可以结束while循环的执行,否则循环将无限期地执行。

while循环流程图

c++ while loop flow diagram

C++中的while循环示例

#include <iostream>
using namespace std;
int main(){int i=1;/* The loop would continue to print* the value of i until the given condition* i<=6 returns false.*/while(i<=6){cout<<"Value of variable i is: "<<i<<endl; i++;}
}

输出:

Value of variable i is: 1
Value of variable i is: 2
Value of variable i is: 3
Value of variable i is: 4
Value of variable i is: 5
Value of variable i is: 6

无限循环

永远不停止的while循环被认为是无限循环,当我们以这样的方式给出条件,以使它永远不会返回false时,循环变为无限并且无限地重复。

无限循环的一个例子:

这个循环永远不会结束,因为我从 1 开始递减i的值,因此条件i <= 6永远不会返回false

#include <iostream>
using namespace std;
int main(){int i=1; while(i<=6) {cout<<"Value of variable i is: "<<i<<endl; i--;}
}

示例:使用while循环显示数组元素

#include <iostream>
using namespace std;
int main(){int arr[]={21,87,15,99, -12};/* The array index starts with 0, the* first element of array has 0 index* and represented as arr[0]*/int i=0;while(i<5){cout<<arr[i]<<endl;i++;}
}

输出:

21
87
15
99
-12

C++ 中的do-while循环

原文: https://beginnersbook.com/2017/08/cpp-do-while-loop/

正如上一篇关于while循环的教程中所讨论的,循环用于重复一个语句块,直到给定的循环条件返回false。在本教程中,我们将看到do-while循环。do-while循环类似于while循环,但它们之间存在差异:在while循环中,首先计算条件,然后执行循环体内的语句,另一方面在do-while循环中执行 - 首先执行,然后求值条件。

do-while循环的语法

do
{statement(s);
} while(condition);

do-while循环如何工作?

首先,循环内的语句执行,然后条件得到求值,如果条件返回true,则控制跳转到do以进一步重复执行它,这会重复发生,直到条件返回false。一旦条件返回false,控制就会跳转到程序中do-while之后的下一个语句。

C++ do while loop flow diagram

C++ 中的do-while循环示例

#include <iostream>
using namespace std;
int main(){int num=1;do{cout<<"Value of num: "<<num<<endl;num++;}while(num<=6);return 0;
}

输出:

Value of num: 1
Value of num: 2
Value of num: 3
Value of num: 4
Value of num: 5
Value of num: 6

示例:使用do-while循环显示数组元素

这里我们有一个整数数组,它有四个元素。我们使用do-while循环显示它的元素。

#include <iostream>
using namespace std;
int main(){int arr[]={21,99,15,109};/* Array index starts with 0, which* means the first element of array* is at index 0, arr[0]*/int i=0;do{cout<<arr[i]<<endl;i++;}while(i<4);return 0;
}

输出:

21
99
15
109

C++ 中的continue语句

原文: https://beginnersbook.com/2017/08/cpp-continue-statement/

在循环内使用continue语句。每当在循环内遇到continue语句时,控制流直接跳转到循环的开头以进行下一次迭代,跳过循环体内当前迭代的语句的执行。

continue语句的语法

continue;

示例:for循环中的continue语句

正如你可以看到输出缺少值 3,但循环迭代num值 0 到 6。这是因为我们在循环中设置了一个条件,这种情况下当num值等于 3 时遇到语句。因此,对于此迭代,循环跳过cout语句并开始下一次循环迭代。

#include <iostream>
using namespace std;
int main(){for (int num=0; num<=6; num++) {/* This means that when the value of* num is equal to 3 this continue statement* would be encountered, which would make the* control to jump to the beginning of loop for* next iteration, skipping the current iteration*/ if (num==3) {continue;}cout<<num<<" ";}return 0;
}

输出:

0 1 2 4 5 6

continue语句的流程图

C++ continue statement

示例:在while循环中使用continue

#include <iostream>
using namespace std;
int main(){int j=6;while (j >=0) {if (j==4) {j--;continue;}cout<<"Value of j: "<<j<<endl;j--;}return 0;
}

输出:

Value of j: 6
Value of j: 5
Value of j: 3
Value of j: 2
Value of j: 1
Value of j: 0

do-while循环中continue的示例

#include <iostream>
using namespace std;
int main(){int j=4;do {if (j==7) {j++;continue;}cout<<"j is: "<<j<<endl;j++;}while(j<10);return 0;
}

输出:

j is: 4
j is: 5
j is: 6
j is: 8
j is: 9

C++ 中的break语句

原文: https://beginnersbook.com/2017/08/cpp-break-statement/

break语句用于以下两种情况:

a)使用break语句立即退出循环。每当在循环内遇到break语句时,控制流就会直接从循环中退出。它与if语句一起使用,只能在循环内部使用(参见下面的示例),以便它仅在特定条件下发生。

b)用于switch-case控制结构。通常,在switch case中的所有情况都跟一个break语句,以避免后续的情况(参见下面的例子)执行。无论何时在switch-case块中遇到,控制流都从switch-case体中出来。

break语句的语法

break;

break语句流程图

C++ break statement

示例 - 在while循环中使用break语句

在下面的示例中,我们有一个从 10 到 200 运行的while循环,但由于我们有一个在循环计数器,变量值达到 12 时遇到break语句,循环终止并且控制流跳转到程序中循环体之后的下一个语句。

#include <iostream>
using namespace std;
int main(){int num =10;while(num<=200) {cout<<"Value of num is: "<<num<<endl;if (num==12) {break;}num++;} cout<<"Hey, I'm out of the loop";return 0;
}

输出:

Value of num is: 10
Value of num is: 11
Value of num is: 12
Hey, I'm out of the loop

示例:for循环中的break语句

#include <iostream>
using namespace std;
int main(){int var;for (var =200; var>=10; var --) {cout<<"var: "<<var<<endl;if (var==197) {break;}}cout<<"Hey, I'm out of the loop";return 0;
}

输出:

var: 200
var: 199
var: 198
var: 197
Hey, I'm out of the loop

示例:switch-case中的break语句

#include <iostream>
using namespace std;
int main(){int num=2;switch (num) {case 1: cout<<"Case 1 "<<endl;break;case 2: cout<<"Case 2 "<<endl;break;case 3: cout<<"Case 3 "<<endl;break;default: cout<<"Default "<<endl;}cout<<"Hey, I'm out of the switch case";return 0;
}

输出:

Case 2 
Hey, I'm out of the switch case

在这个例子中,我们在每个case块之后都有break语句,这是因为如果我们没有它,那么后续的case块也会执行。没有break的同一程序的输出将是:

Case 2
Case 3
Default
Hey, I'm out of the switch case

C++ 中的goto语句

原文: https://beginnersbook.com/2017/08/cpp-goto-statement/

goto语句用于将程序的控制转移到给定标签。 goto语句的语法如下所示:

goto label_name;

程序结构:

label1:
...
...
goto label2;
...
..
label2:
...

在程序中我们有任意数量的gotolabel语句,goto语句后跟一个标签名称,每当遇到goto语句时,程序的控制权就会跳转到goto语句中指定的标签。

goto语句几乎从不在任何开发中使用,因为它们很复杂,使得程序的可读性更低,更容易出错。代替goto,你可以使用continuebreak语句。

C++ 中goto语句的示例

#include <iostream>
using namespace std;
int main(){int num; cout<<"Enter a number: "; cin>>num;if (num % 2==0){goto print;}else {cout<<"Odd Number";}print:cout<<"Even Number";return 0;
}

输出:

Enter a number: 42
Even Number

函数

C++ 中的函数

原文: https://beginnersbook.com/2017/08/cpp-functions/

函数是用于执行特定任务的代码块,例如,假设您正在编写一个大型 C++ 程序,并且在该程序中,您希望多次执行特定任务,例如显示从 1 到 10 的值,为了做到这一点,你必须编写几行代码,每次显示值时都需要重复这些行。另一种方法是在函数内写入这些行,并在每次要显示值时调用该函数。这将使您的代码简单,可读和可重用。

函数的语法

return_type function_name (parameter_list)
{//C++ Statements
}

让我们举一个简单的例子来理解这个概念。

一个简单的函数示例

#include <iostream>
using namespace std;
/* This function adds two integer values* and returns the result*/int
sum(int num1, int num2){int num3 = num1+num2; return num3;
}int main(){//Calling the functioncout<<sum(1,99);return 0;
}

输出:

100

同样的程序可以这样写:好吧,我正在编写这个程序,让你理解一个关于函数的重要术语,即函数声明。让我们先看看程序,然后在最后讨论函数声明,定义和函数调用。

#include <iostream>
using namespace std;
//Function declaration
int sum(int,int);//Main function
int main(){//Calling the functioncout<<sum(1,99);return 0;
}
/* Function is defined after the main method */
int sum(int num1, int num2){int num3 = num1+num2;return num3;
}

函数声明:你已经看到我用两种方式编写了相同的程序,在第一个程序中我没有任何函数声明,在第二个程序中我在程序开头有函数声明。问题是,当您在程序中的main()函数之前定义函数时,您不需要执行函数声明,但如果您在main()函数之后编写函数,就像我们在第二个程序中那样,那么您需要先声明函数,否则会出现编译错误。

函数声明的语法:

return_type function_name(parameter_list);

注意:在提供parameter_list时,您可以避免参数名称,就像我在上面的示例中所做的那样。我给了int sum(int,int);而不是int sum(int num1,int num2);

函数定义:编写函数的全部称为定义函数。

函数定义语法:

return_type function_name(parameter_list) {//Statements inside function
}

调用函数:我们可以像这样调用函数:

function_name(parameters);

现在我们已经理解了函数的工作原理,让我们看看 C++ 中的函数类型。

函数类型

我们在 C++中有两种类型的函数:

C++ types of functions: built-in and user-defined

1)内置函数

2)用户定义的函数

1)内置函数

内置函数也称为库函数。我们不需要声明和定义这些函数,因为它们已经在 C++ 库中编写,例如iostreamcmath等。我们可以在需要时直接调用它们。

示例:C++ 内置函数示例

这里我们使用内置函数pow(x, y),它是xy次幂。此函数在cmath头文件中声明,因此我们使用#include指令将该文件包含在我们的程序中。

#include <iostream>
#include <cmath>
using namespace std;
int main(){/* Calling the built-in function * pow(x, y) which is x to the power y* We are directly calling this function*/cout<<pow(2,5);return 0;
}

输出:

32

2)用户定义的函数

C++ functions

我们已经看过用户定义的函数,我们在本教程开头给出的示例是用户定义函数的示例。我们在程序中声明和编写的函数是用户定义的函数。让我们看另一个用户定义函数的例子。

用户定义的函数

#include <iostream>
#include <cmath>
using namespace std;
//Declaring the function sum
int sum(int,int);int main(){int x, y;cout<<"enter first number: ";cin>> x;cout<<"enter second number: ";cin>>y;cout<<"Sum of these two :"<<sum(x,y);return 0;
}
//Defining the function sum
int sum(int a, int b) {int c = a+b;return c;
}

输出:

enter first number: 22
enter second number: 19
Sum of these two :41

C++ 函数中的默认参数

原文: https://beginnersbook.com/2017/08/cpp-default-arguments/

在调用函数时不提供任何参数或仅提供少量参数时,将使用默认参数。在编译程序期间使用默认参数。例如,假设您有一个用户定义的函数sum声明如下:int sum(int a=10, int b=20),现在在调用此函数时,您不提供任何参数,简称为sum();那么在这种情况下结果将是 30,编译器使用函数签名中声明的默认值 10 和 20。如果你只传递一个这样的参数:sum(80)那么结果将是 100,使用传递的参数 80 作为第一个值,20 个从默认参数中获取。

示例:C++ 中的默认参数

#include <iostream>
using namespace std;
int sum(int a, int b=10, int c=20);int main(){/* In this case a value is passed as* 1 and b and c values are taken from* default arguments.*/cout<<sum(1)<<endl;/* In this case a value is passed as* 1 and b value as 2, value of c values is* taken from default arguments.*/cout<<sum(1, 2)<<endl;/* In this case all the three values are* passed during function call, hence no* default arguments have been used.*/cout<<sum(1, 2, 3)<<endl;return 0;
}
int sum(int a, int b, int c){int z;z = a+b+c;return z;
}

输出:

31
23
6

默认参数的规则

正如您在上面的示例中所看到的,我在函数声明期间仅为两个参数bc分配了默认值。您可以为所有参数或仅选定的参数指定默认值,但在仅为某些参数指定默认值时,请记住以下规则:

如果为参数指定默认值,则必须为后续参数分配默认值,否则将出现编译错误。

例如:让我们看一些有效和无效的案例。

有效:以下函数声明有效:

int sum(int a=10, int b=20, int c=30);
int sum(int a, int b=20, int c=30);
int sum(int a, int b, int c=30);

无效:以下函数声明无效:

/* Since a has default value assigned, all the* arguments after a (in this case b and c) must have * default values assigned*/
int sum(int a=10, int b, int c=30);/* Since b has default value assigned, all the* arguments after b (in this case c) must have * default values assigned*/
int sum(int a, int b=20, int c);/* Since a has default value assigned, all the* arguments after a (in this case b and c) must have * default values assigned, b has default value but* c doesn't have, thats why this is also invalid*/
int sum(int a=10, int b=20, int c);

C++ 递归

原文: https://beginnersbook.com/2017/08/cpp-recursion/

函数调用自身的过程称为递归,相应的函数称为递归函数。理解递归的流行示例是阶乘函数。

阶乘函数: f(n) = n * f(n-1),基本条件:如果n <= 1f(n)= 1。不要担心我们将讨论什么是基本条件,以及为什么它很重要。

在下图中。我已经证明了在函数达到基本条件之前,阶乘函数如何调用自身。

C++ recursion

让我们用 C++ 程序解决问题。

C++ 递归示例:阶乘

#include <iostream>
using namespace std;
//Factorial function
int f(int n){/* This is called the base condition, it is* very important to specify the base condition* in recursion, otherwise your program will throw* stack overflow error.*/
   if (n <= 1)
        return 1;
   else       return n*f(n-1);
}
int main(){int num;  cout<<"Enter a number: ";
   cin>>num;
   cout<<"Factorial of entered number: "<<f(num);return 0;
}

输出:

Enter a number: 5
Factorial of entered number: 120

基本情况

在上面的程序中,您可以看到我在递归函数中提供了基本条件。条件是:

if (n <= 1)
        return 1;

递归的目的是将问题分成较小的问题,直到达到基本条件。例如,在上述阶乘程序中,我通过调用较小的阶乘函数f(n-1)来求解阶乘函数 f(n),这一直重复发生,直到n值达到基本条件(f(1) = 1)。如果未在递归函数中定义基本条件,则会出现堆栈溢出错误。

直接递归与间接递归

直接递归:当函数调用自身时,它被称为直接递归,我们上面看到的例子是直接递归示例。

间接递归:当函数调用另一个函数并且该函数调用这个函数时,这称为间接递归。例如:函数 A 调用函数 B,函数 B 调用函数 A。

C++ 中的间接递归示例

#include <iostream>
using namespace std;
int fa(int);
int fb(int);
int fa(int n){if(n<=1)return 1;elsereturn n*fb(n-1);
}
int fb(int n){if(n<=1)return 1;elsereturn n*fa(n-1);
}
int main(){int num=5;
   cout<<fa(num);return 0;
}

输出:

120

基础

数组

C++ 中的数组

原文: https://beginnersbook.com/2017/08/cpp-arrays/

数组是存储在连续内存位置的类似项的集合。在编程中,有时一个简单的变量不足以容纳所有数据。例如,假设我们要存储 500 名学生的信息,这个任务有 500 个不同的变量是不可行的,我们可以定义一个大小为 500 的数组,可以保存所有学生的信息。

C++ arrays

用 C++声明一个数组

有几种方法可以声明一个数组。

方法 1:

int arr[5];
arr[0] = 10;
arr[1] = 20;
arr[2] = 30;
arr[3] = 40;
arr[4] = 50;

方法 2:

int arr[] = {10, 20, 30, 40, 50};

方法 3:

int arr[5] = {10, 20, 30, 40, 50};

访问数组元素

数组索引以 0 开头,这意味着第一个数组元素位于索引 0,第二个数据元素位于索引 1,依此类推。我们可以使用此信息来显示数组元素。请参阅以下代码:

#include <iostream>
using namespace std;int main(){int arr[] = {11, 22, 33, 44, 55};cout<<arr[0]<<endl;cout<<arr[1]<<endl;cout<<arr[2]<<endl;cout<<arr[3]<<endl;cout<<arr[4]<<endl;return 0;
}

输出:

11
22
33
44
55

尽管此代码工作正常,但不建议显示此类数组的所有元素。当你想访问一个特定的数组元素时,这很好,但如果你想显示所有元素,那么你应该使用这样的循环:

#include <iostream>
using namespace std;int main(){int arr[] = {11, 22, 33, 44, 55};int n=0;while(n<=4){cout<<arr[n]<<endl;n++;}return 0;
}

C++ 中的多维数组

原文: https://beginnersbook.com/2017/08/cpp-multidimensional-arrays/

多维数组也称为数组的数组。多维数组中的数据以表格形式存储,如下图所示:

Multidimensional Array in C++

二维数组:

int arr[2][3];

该数组总共有2 * 3 = 6个元素。

三维数组:

int arr[2][2][2];

该数组总共有2 * 2 * 2 = 8个元素。

二维数组

让我们看看如何声明,初始化和访问二维数组的元素。

如何声明二维数组?

int myarray[2][3];

初始化:

我们可以通过多种方式初始化数组:

方法 1:

int arr[2][3] = {10, 11 ,12 ,20 ,21 , 22};

方法 2:

这种初始化方式是首选,因为您可以在此处显示行和列。

int arr[2][3] = {{10, 11 ,12} , {20 ,21 , 22}};

访问数组元素:

  • arr [0] [0] - 第一个元素
  • arr [0] [1] - 第二个元素
  • arr [0] [2] - 第三个元素
  • arr [1] [0] - 第四个元素
  • arr [1] [1] - 第五个元素
  • arr [1] [2] - 第六个元素

示例:C++ 中的二维数组

#include <iostream>
using namespace std;int main(){int arr[2][3] = {{11, 22, 33}, {44, 55, 66}};for(int i=0; i<2;i++){for(int j=0; j<3; j++){cout<<"arr["<<i<<"]["<<j<<"]: "<<arr[i][j]<<endl;}}return 0;
}

输出:

arr[0][0]: 11
arr[0][1]: 22
arr[0][2]: 33
arr[1][0]: 44
arr[1][1]: 55
arr[1][2]: 66

三维数组

让我们看看如何声明,初始化和访问三维数组元素。

声明三维数组:

int myarray[2][3][2];

初始化:

我们可以通过多种方式初始化数组:

方法 1:

int arr[2][3][2] = {1, -1 ,2 ,-2 , 3 , -3, 4, -4, 5, -5, 6, -6};

方法 2:

这种初始化方式是首选,因为您可以在此处显示行和列。

int arr[2][3][2] = {{ {1,-1}, {2, -2}, {3, -3}},{ {4, -4}, {5, -5}, {6, -6}}
}

三维数组示例

#include <iostream>
using namespace std;int main(){// initializing the arrayint arr[2][3][2] = {{ {1,-1}, {2,-2}, {3,-3} },{ {4,-4}, {5,-5}, {6,-6} }};// displaying array values for (int x = 0; x < 2; x++) {for (int y = 0; y < 3; y++) {for (int z = 0; z < 2; z++) {cout<<arr[x][y][z]<<" ";}}}return 0;
}

输出:

1 -1 2 -2 3 -3 4 -4 5 -5 6 -6

看看这些相关的 C++ 程序:

  1. C++ 程序:相加两个矩阵
  2. C++ 程序:查找并打印矩阵 的转置

在 C++ 中将数组传递给函数

原文: https://beginnersbook.com/2017/08/cpp-passing-array-to-function/

您可以将数组作为参数传递给函数,就像将变量作为参数传递一样。为了将数组传递给函数,您只需要在函数调用中提及数组名称,如下所示:

function_name(array_name);

示例:将数组传递给函数

在这个例子中,我们传递两个数组ab到函数sum()。此函数相加两个数组的相应元素并显示它们。

#include <iostream>
using namespace std;
/* This function adds the corresponding
 * elements of both the arrays and
 * displays it.
 */
void sum(int arr1[], int arr2[]){int temp[5];for(int i=0; i<5; i++){temp[i] = arr1[i]+arr2[i];cout<<temp[i]<<endl;}
}
int main(){int a[5] = {10, 20, 30, 40 ,50};int b[5] = {1, 2, 3, 4, 5};//Passing arrays to functionsum(a, b);return 0;
}

输出:

11
22
33
44
55

示例 2:将多维数组传递给函数

在这个例子中,我们将多维数组传递给函数square,该函数显示每个元素的平方。

#include <iostream>
#include <cmath>
using namespace std;
/* This method prints the square of each
 * of the elements of multidimensional array
 */
void square(int arr[2][3]){int temp;for(int i=0; i<2; i++){for(int j=0; j<3; j++){temp = arr[i][j];cout<<pow(temp, 2)<<endl;}}
}
int main(){int arr[2][3] = { 
       {1, 2, 3},      {4, 5, 6}};square(arr);return 0;
}

输出:

1
4
9
16
25
36

C++ 中的字符串

原文: https://beginnersbook.com/2017/08/strings-in-c/

字符串是由字符组成的单词,因此它们被称为字符序列。在 C++ 中,我们有两种方法来创建和使用字符串:1)通过创建char数组并将它们视为字符串 2)通过创建string对象

让我们先讨论这两种创建字符串的方法,然后我们会看到哪种方法更好,为什么。

1)字符数组 - 也称为 C 字符串

例 1:

一个简单例子,我们在声明期间初始化了char数组。

#include <iostream>
using namespace std;
int main(){char book[50] = "A Song of Ice and Fire";  cout<<book;return 0;
}

输出:

A Song of Ice and Fire

示例 2:将用户输入作为字符串

这可以被视为读取用户输入的低效方法,为什么?因为当我们使用cin读取用户输入字符串时,只有字符串的第一个单词存储在char数组中而其余部分被忽略。cin函数将字符串中的空格视为分隔符,并忽略其后的部分。

#include <iostream>
using namespace std;
int main(){char book[50];cout<<"Enter your favorite book name:";//reading user inputcin>>book;cout<<"You entered: "<<book;return 0;
}

输出:

Enter your favorite book name:The Murder of Roger Ackroyd
You entered: The

你可以看到只有The被捕获在book中,空格之后的剩下部分被忽略。那怎么处理呢?那么,为此我们可以使用cin.get函数,它读取用户输入的完整行。

示例 3:使用 cin.get 正确捕获用户输入字符串的方法

#include <iostream>
using namespace std;
int main(){char book[50];cout<<"Enter your favorite book name:";//reading user inputcin.get(book, 50);cout<<"You entered: "<<book;return 0;
}

输出:

Enter your favorite book name:The Murder of Roger Ackroyd
You entered: The Murder of Roger Ackroyd

这种方法的缺点

1)char数组的大小是固定的,这意味着通过它创建的字符串的大小是固定大小的,在运行时期间不能分配更多的内存。例如,假设您已创建一个大小为 10 的字符数组,并且用户输入大小为 15 的字符串,则最后五个字符将从字符串中截断。

另一方面,如果您创建一个更大的数组来容纳用户输入,那么如果用户输入很小并且数组比需要的大得多,则会浪费内存。

2)在这种方法中,你只能使用为数组创建的内置函数,它们对字符串操作没有多大帮助。

这些问题的解决方案是什么?

我们可以使用字符串对象创建字符串。让我们看看我们如何做到这一点。

C++ 中的string对象

到目前为止我们已经看到了如何使用char数组处理 C++ 中的字符串。让我们看看在 C++ 中处理字符串的另一种更好的方法 - 字符串对象。

#include<iostream>
using namespace std;
int main(){// This is how we create string objectstring str;cout<<"Enter a String:";/* This is used to get the user input* and store it into str*/getline(cin,str);cout<<"You entered: ";cout<<str<<endl;/* This function adds a character at* the end of the string*/ str.push_back('A');cout<<"The string after push_back: "<<str<<endl;/* This function deletes a character from* the end of the string*/str.pop_back();cout << "The string after pop_back: "<<str<<endl;return 0;
}

输出:

Enter a String:XYZ
You entered: XYZ
The string after push_back: XYZA
The string after pop_back: XYZ

使用这种方法的好处是你不需要声明字符串的大小,大小是在运行时确定的,所以这是更好的内存管理方法。内存在运行时动态分配,因此不会浪费内存。

指针

C++ 中的指针

原文: https://beginnersbook.com/2017/08/cpp-pointers/

指针是 C++ 中的一个变量,它包含另一个变量的地址。它们的数据类型就像变量一样,例如整数类型指针可以保存整数变量的地址,字符类型指针可以保存char变量的地址。

指针的语法

data_type *pointer_name;

如何声明指针?

/* This pointer p can hold the address of an integer * variable, here p is a pointer and var is just a* simple integer variable*/
int *p, var

赋值

如上所述,整数类型指针可以保存另一个int变量的地址。这里我们有一个整数变量var和指针p,它保存var的地址。要将变量的地址赋值给指针,我们使用&符号

/* This is how you assign the address of another variable* to the pointer*/
p = &var;

如何使用它?

// This will print the address of variable var
cout<<&var;    /* This will also print the address of variable* var because the pointer p holds the address of var*/
cout<<p;    /* This will print the value of var, This is * important, this is how we access the value of* variable through pointer
*/
cout<<*p; 

指针示例

让我们举一个简单的例子来理解我们上面讨论的内容。

#include <iostream>
using namespace std;
int main(){//Pointer declarationint *p, var=101;//Assignmentp = &var;cout<<"Address of var: "<<&var<<endl;cout<<"Address of var: "<<p<<endl;cout<<"Address of p: "<<&p<<endl;cout<<"Value of var: "<<*p;return 0;
}

输出:

Address of var: 0x7fff5dfffc0c
Address of var: 0x7fff5dfffc0c
Address of p: 0x7fff5dfffc10
Value of var: 101

指针和数组

在使用指针处理数组时,您需要注意一些事情。关于数组的第一个也是非常重要的注意事项是,数组名称单独表示数组的基地址,因此在将数组地址赋值给指针时不要使用符号(&)。这样做:

正确:因为arr代表数组的地址。

p = arr;

不正确:

p = &arr;

示例:使用指针遍历数组

#include <iostream>
using namespace std;
int main(){//Pointer declarationint *p;//Array declarationint arr[]={1, 2, 3, 4, 5, 6};//Assignmentp = arr;for(int i=0; i<6;i++){    cout<<*p<<endl;//++ moves the pointer to next int position    p++;
   }return 0;
}

输出:

1
2
3
4
5
6

如何递增指针地址和指针的值?

当我们通过指针访问变量的值时,有时我们只需要增加或减少变量的值,或者我们可能需要将指针移动到下一个int位置(就像我们在使用数组时一样)。 ++运算符用于此目的。我们在上面看到的++运算符的一个示例,我们通过使用++运算符递增指针值来遍历数组。让我们看几个案例。

// Pointer moves to the next int position (as if it was an array)
p++; 
// Pointer moves to the next int position (as if it was an array)   
++p;   /* All the following three cases are same they increment the value * of variable that the pointer p points.*/
++*p;   
++(*p); 
++*(p); 

C++ this指针

原文: https://beginnersbook.com/2017/08/cpp-this-pointer/

this指针保存当前对象的地址,简单来说,你可以说这个指针指向该类的当前对象。让我们举个例子来理解这个概念。

C++ 示例:this指针

在这里你可以看到我们有两个数据成员numch。在成员函数setMyValues()中,我们有两个与数据成员名称相同的局部变量。在这种情况下,如果要将局部变量值赋值给数据成员,那么除非使用this指针,否则您将无法执行此操作,因为除非您使用this,否则编译器将不知道您指的是对象的数据成员。这是必须使用this指针的示例之一。

#include <iostream>
using namespace std;
class Demo {
private:int num;char ch;
public:void setMyValues(int num, char ch){this->num =num;this->ch=ch;}void displayMyValues(){cout<<num<<endl;cout<<ch;}
};
int main(){Demo obj;obj.setMyValues(100, 'A');
  obj.displayMyValues();return 0;
}

输出:

100
A

示例 2:使用this指针进行函数链式调用

使用this指针的另一个示例是返回当前对象的引用,以便您可以链式调用函数,这样您就可以一次调用当前对象的所有函数。在这个程序中需要注意的另一个要点是,我在第二个函数中增加了对象num的值,你可以在输出中看到它实际上增加了我们在第一个函数调用中设置的值。这表明链接是顺序的,对对象的数据成员所做的更改将保留以进一步链式调用。

#include <iostream>
using namespace std;
class Demo {
private:int num;char ch;
public:Demo &setNum(int num){this->num =num;return *this;}Demo &setCh(char ch){this->num++;this->ch =ch;return *this;}void displayMyValues(){cout<<num<<endl;cout<<ch;}
};
int main(){Demo obj;//Chaining callsobj.setNum(100).setCh('A');obj.displayMyValues();return 0;
}

输出:

101
A

OOP

C++ 中的 OOP 概念

原文: https://beginnersbook.com/2017/08/cpp-oops-concepts/

面向对象编程是一种通过使用对象将问题分解为更小问题来解决复杂问题的方法。在面向对象编程(通常称为 OOP)之前,程序是用过程语言编写的,它们只是一长串指令。另一方面,OOP 就是创建可以交互的对象,这使得在 OOP 中开发程序变得更容易,因为我们可以理解它们之间的关系。

面向对象编程(OOP)

在面向对象编程中,我们使用类和对象编写程序,利用 OOP 的特征,如抽象封装继承多态

类和对象

类就像数据成员和函数的蓝图,对象是类的实例。例如,假设我们有一个类 Car ,它有数据成员(变量),如speedweightprice,和函数,如gearChange()slowDown()brake()等。现在让我们说我创建了一个名为FordFigo的类的对象,它使用这些数据成员和函数,并为它们提供自己的值。同样,我们可以使用蓝图(类)创建任意数量的对象。

//Class name is Car
class Car
{//Data memberschar name[20];int speed;int weight;public://Functionsvoid brake(){}void slowDown(){}
};int main()
{//ford is an objectCar ford; 
}

抽象

抽象是隐藏用户不相关细节的过程。例如,当您发送短信时,您只需键入消息,选择联系人并单击发送,手机会显示消息已发送,单击发送时背景中实际发生的情况对您是隐藏的,因为它对你不相关。

封装

封装是将数据和函数组合成像胶囊这样的单个单元的过程。这是为了避免从类外部访问私有数据成员。为了实现封装,我们将类的所有数据成员设为私有并创建公共函数,使用它们我们可以从这些数据成员获取值或为这些数据成员设置值。

继承

继承是一个特性,子类的对象使用该特性获取父类的属性。

#include <iostream>
using namespace std;
class ParentClass {//data memberpublic:int var1 =100;
};
class ChildClass: public ParentClass {public:int var2 = 500;
};
int main(void) {ChildClass obj;
}

现在这个对象obj可以使用ParentClass的属性(例如变量var1)。

多态

函数重载和运算符重载是多态的例子。多态是一种在不同情况下对象表现不同的特性。

在函数重载中,我们可以有多个函数,具有相同名称但不同数量,类型或顺序的参数。

多态实例

#include <iostream>
using namespace std;
class Sum {public:int add(int num1,int num2){return num1 + num2;}int add(int num1, int num2, int num3){return num1 + num2 + num3;}
};
int main(void) {//Object of class SumSum obj;//This will call the second add functioncout<<obj.add(10, 20, 30)<<endl;//This will call the first add functioncout<<obj.add(11, 22);return 0;
}

输出:

60
33

Hello World - 第一个 C++ 程序

原文: https://beginnersbook.com/2017/08/first-cpp-program/

在本指南中,我们将编写和理解** C++** 编程中的第一个程序。我们正在编写一个打印Hello World!消息的简单 C++ 程序。让我们先看看程序,然后我们将详细讨论它的每一部分。

C++中的Hello World程序

/*
* Multiple line
* comment
*/
#include<iostream>//Single line comment
using namespace std;//This is where the execution of program begins
int main()
{// displays Hello World! on screencout<<"Hello World!";return 0;
}

输出:

Hello World!

我们来讨论上述程序的每一部分。

1. 注释 - 您可以在上述程序中看到两种类型的注释

// This is a single line comment
/* This is a multiple line comment
* suitable for long comments
*/

顾名思义,注释只是程序员在代码开发过程中编写的文本。注释不会以任何方式影响您的程序逻辑,您可以在注释中编写任何您想要的内容,但它应该与代码相关并具有一些含义,以便当其他人查看您的代码时,该人只需阅读您的注释就应该了解您的代码。

例如:

/* This function adds two integer numbers * and returns the result as an integer value*/
int sum(int num1, int num2) {return num1+num2;
}

现在,如果有人阅读我的注释,他或她只需阅读我的注释即可理解我在那里所做的事情。这提高了代码的可读性,当您与团队成员一起开展项目时,这将成为必不可少的方面。

2. #include <iostream> - 此语句告诉编译器包含iostream文件。该文件包含我们可以在程序中使用的预定义输入/输出函数。

3. using namespace std; - 名称空间就像一个区域,我们有函数,变量等,它们的范围仅限于该特定区域。这里std是一个命名空间名称,它告诉编译器查看所有变量,函数等的特定区域。我不会在这里详细讨论它,因为它可能会让你感到困惑。我在一个单独的教程中通过示例介绍了这个主题。按照给定顺序阅读教程,你会没事的。

4. int main() - 顾名思义这是我们程序的主函数,程序的执行从这个函数开始,这里的int是返回类型,它向编译器指示这个函数将返回一个整数值。这是我们在main函数末尾放置return 0语句的主要原因。

5. cout<<"Hello World!"; - cout对象属于iostream文件,此对象的目的是在屏幕上显示双引号之间的内容。这个对象也可以在屏幕上显示变量的值(不用担心,我们将在后面的教程中看到)。

6. return 0; - 该语句从main()函数返回值 0,表示main函数执行成功。值 1 表示执行失败。

C++ 中的构造函数

原文: https://beginnersbook.com/2017/08/cpp-constructors/

构造函数是初始化类对象的类的特殊成员函数。构造函数名称与类名称相同,并且没有返回类型。让我们举一个简单的例子来理解构造函数的工作原理。

简单示例:如何在 C++ 中使用构造函数

阅读以下程序中的注释,以了解该程序的每个部分。

#include <iostream>
using namespace std;
class constructorDemo{
public:int num;char ch;/* This is a default constructor of the* class, do note that it's name is same as* class name and it doesn't have return type.*/constructorDemo() {num = 100; ch = 'A';}
};
int main(){/* This is how we create the object of class,* I have given the object name as obj, you can* give any name, just remember the syntax:* class_name object_name;*/constructorDemo obj;/* This is how we access data members using object* we are just checking that the value we have* initialized in constructor are reflecting or not.*/cout<<"num: "<<obj.num<<endl;cout<<"ch: "<<obj.ch;return 0;
}

输出:

num: 100
ch: A

构造函数与成员函数

现在我们知道什么是构造函数,让我们讨论构造函数与类的成员函数的不同之处。

1)构造函数没有返回类型。成员函数具有返回类型。

2)当我们创建类的对象时,会自动调用构造函数。需要使用类的对象显式调用成员函数。

3)当我们不在我们的类中创建任何构造函数时,C++ 编译器生成一个默认构造函数并将其插入到我们的代码中。这同样适用于成员函数。

这是编译器生成的默认构造函数的外观:

class XYZ
{ ....XYZ(){//Empty no code}
};

C++ 中构造函数的类型

C++ 中有两种类型的构造函数。 1)默认构造函数 2)参数化构造函数

1)默认构造函数

默认构造函数没有任何参数(或参数)。

#include <iostream>
using namespace std;
class Website{
public://Default constructorWebsite() {cout<<"Welcome to BeginnersBook"<<endl;}
};
int main(void){/*creating two objects of class Website.* This means that the default constructor* should have been invoked twice.*/Website obj1;Website obj2;return 0;
}

输出:

Welcome to BeginnersBook
Welcome to BeginnersBook

如果未在类中指定任何构造函数,则编译器将在代码中插入没有代码(空体)的默认构造函数。

2)参数化构造函数

带参数的构造函数称为参数化构造函数。这些类型的构造函数允许我们在创建对象时传递参数。让我们看看他们的样子:

让我们假设类名是XYZ

默认构造函数:

XYZ() {}
....
XYZ obj;
....

参数化构造函数:

XYZ(int a, int b) {}
...
XYZ obj(10, 20);

例:

#include <iostream>
using namespace std;
class Add{
public://Parameterized constructorAdd(int num1, int num2) {cout<<(num1+num2)<<endl;}
};
int main(void){/* One way of creating object. Also* known as implicit call to the* constructor*/Add obj1(10, 20);/* Another way of creating object. This* is known as explicit calling the* constructor.*/Add obj2 = Add(50, 60);return 0;
}

输出:

30
110

C++ 中的析构函数

原文: https://beginnersbook.com/2017/08/cpp-destructors/

析构函数是一个特殊的成员函数,与构造函数相反,与用于初始化对象的构造函数不同,析构函数销毁(或删除)对象。

析构函数语法:

~class_name()    
{   //Some code   
}

与构造函数类似,析构函数名称应与类名完全匹配。析构函数声明应始终以波形符(~)符号开头,如上面的语法所示。

什么时候析构函数被调用?

在以下情况下,析构函数自动调用

1)程序完成执行。

2)当包含局部变量的作用域({}括号)结束时。

3)当你调用delete运算符时。

析构函数示例

#include <iostream>
using namespace std;
class HelloWorld{
public://ConstructorHelloWorld(){cout<<"Constructor is called"<<endl;}//Destructor~HelloWorld(){cout<<"Destructor is called"<<endl;}//Member functionvoid display(){cout<<"Hello World!"<<endl;}
};
int main(){//Object createdHelloWorld obj;//Member function calledobj.display();return 0;
}

输出:

Constructor is called
Hello World!
Destructor is called

析构函数规则

1)名称应以波形符号(~)开头,并且必须与类名匹配。

2)一个类中不能有多个析构函数。

3)与可以有参数的构造函数不同,析构函数不允许任何参数。

4)他们没有任何返回类型,就像构造函数一样。

5)当你没有在类中指定任何析构函数时,编译器会生成一个默认的析构函数并将其插入到代码中。

C++ 中的结构

原文: https://beginnersbook.com/2017/09/cpp-structures/

结构是一种复合数据类型,包含不同类型的不同变量。例如,您要存储学生详细信息,例如学生姓名,学生卷数,学生年龄。你有两种方法可以做到这一点,一种方法是为每个数据创建不同的变量,但这种方法的缺点是,如果你想存储多个学生的细节,那么在这种情况下,为每个学生创建单独的一组变量是不可行的。

第二种是通过创建这样的结构来实现它,也是最好的方法:

struct Student
{char stuName[30];int stuRollNo;int stuAge;
};

现在这三个成员组合起来就像一个单独的变量,你可以像这样创建结构变量:

structure_name variable_name

因此,如果您想要使用此结构保存两名学生的信息,那么您可以这样做:

Student s1, s2;

然后我可以像这样访问Student结构的成员:

//Assigning name to first student
s1.stuName = "Ajeet";
//Assigning age to the second student
s2.stuAddr = 22;

同样,我可以为每个学生设置并获取结构的其他数据成员的值。让我们看一个完整的例子来把它们放在一起:

C++中的结构示例

#include <iostream>
using namespace std;
struct Student{char stuName[30];int stuRollNo;int stuAge;
};
int main(){Student s;cout<<"Enter Student Name: ";cin.getline(s.stuName, 30); cout<<"ENter Student Roll No: ";  cin>>s.stuRollNo;cout<<"Enter Student Age: ";cin>>s.stuAge;cout<<"Student Record:"<<endl;cout<<"Name: "<<s.stuName<<endl;cout<<"Roll No: "<<s.stuRollNo<<endl;cout<<"Age: "<<s.stuAge;return 0;
}

输出:

Enter Student Name: Negan
ENter Student Roll No: 4101003
Enter Student Age: 22
Student Record:
Name: Negan
Roll No: 4101003
Age: 22

C++ 中的结构和函数

原文: https://beginnersbook.com/2017/09/cpp-structure-and-function/

在之前的教程中,我们了解了结构,即对不同类型的变量进行分组的复合数据类型。在本教程中,我们将学习如何将结构作为参数传递给函数以及如何从函数返回结构。

如何将结构作为参数传递给函数

这里我们有一个函数printStudentInfo(),它将结构Student作为参数,并使用结构变量打印学生的详细信息。这里需要注意的重点是,您应该始终在函数声明之前声明结构,否则您将收到编译错误。

#include <iostream>
using namespace std;
struct Student{char stuName[30];int stuRollNo;int stuAge;
};
void printStudentInfo(Student);
int main(){Student s;cout<<"Enter Student Name: ";cin.getline(s.stuName, 30);cout<<"Enter Student Roll No: ";cin>>s.stuRollNo;cout<<"Enter Student Age: ";cin>>s.stuAge;printStudentInfo(s);return 0;
}
void printStudentInfo(Student s){cout<<"Student Record:"<<endl;cout<<"Name: "<<s.stuName<<endl;cout<<"Roll No: "<<s.stuRollNo<<endl;cout<<"Age: "<<s.stuAge;
}

输出:

Enter Student Name: Rick
Enter Student Roll No: 666123
Enter Student Age: 19
Student Record:
Name: Rick
Roll No: 666123
Age: 19

如何从函数返回结构

在这个例子中,我们有两个函数,一个从用户获取值,将它们赋值给结构成员并返回结构,另一个函数将该结构作为参数并打印细节。

#include <iostream>
using namespace std;
struct Student{char stuName[30];int stuRollNo;int stuAge;
};
Student getStudentInfo();
void printStudentInfo(Student);
int main(){Student s;s = getStudentInfo();printStudentInfo(s);return 0;
}
/* This function prompt the user to input student
 * details, stores them in structure members
 * and returns the structure
 */
Student getStudentInfo(){Student s;cout<<"Enter Student Name: ";cin.getline(s.stuName, 30);cout<<"Enter Student Roll No: ";cin>>s.stuRollNo;cout<<"Enter Student Age: ";cin>>s.stuAge;return s;
}
void printStudentInfo(Student s){cout<<"Student Record:"<<endl;cout<<"Name: "<<s.stuName<<endl;cout<<"Roll No: "<<s.stuRollNo<<endl;cout<<"Age: "<<s.stuAge;
}

输出:

Enter Student Name: Tyrion lannister
Enter Student Roll No: 333901
Enter Student Age: 39
Student Record:
Name: Tyrion lannister
Roll No: 333901
Age: 39

C++ 中的枚举

原文: https://beginnersbook.com/2017/09/cpp-enumeration/

枚举是用户定义的数据类型,我们为变量指定一组值,变量只能从一小组可能的值中取出一个。我们使用enum关键字来定义枚举。

enum direction {East, West, North, South}dir;

这里枚举名称是只能取四个方向之一的指定值,声明末尾的dir是枚举变量。

让我们举一个简单的例子来理解这一点:

这里我已经将值West分配给枚举变量dir,当我显示dir的值时,它显示 1。这是因为默认情况下值从 0 开始递增,意思是东是 0,西是 1,北是 2,南是 3。

简单的枚举示例

#include<iostream>
using namespace std;
enum direction {East, West, North, South}dir;
int main()
{dir = West;cout<<dir;return 0;
}

另一种声明枚举变量的方法

正如我们在上面的例子中看到的,我在枚举声明中声明了枚举变量dir,还有另一种声明枚举变量的方法。

#include <iostream>
using namespace std;
enum direction {East, West, North, South};
int main(){direction dir;
   dir = South;   cout<<dir;   return 0;
}

输出:

3

为什么在 C++ 中使用enum

既然我们已经理解了什么是枚举以及如何在程序中使用它们,那么让我们讨论一下我们使用它们的原因:

只有在我们期望变量具有一组可能的值时才使用枚举,例如,我们有一个保存方向的dir变量。由于我们有四个方向,这个变量可以取四个值中的任何一个,如果我们尝试为这个变量赋另一个随机值,它将抛出一个编译错误。这会增加编译时检查并避免通过传入无效常量而发生的错误。

经常使用它们的另一个重要位置是switch-case语句,其中case块期望的所有值都可以在枚举中定义。这样我们就可以确保我们在switch括号中传递的enum变量没有采用它不应该接受的任何随机值。

如何更改enum的默认值

#include <iostream>
using namespace std;
enum direction {East=11, West=22, North=33, South=44};
int main(){direction dir;  dir = South;
   cout<<dir;   return 0;
}

输出:

44

C++ 中的继承

原文: https://beginnersbook.com/2017/08/cpp-inheritance/

继承是面向对象编程系统(OOP)的特性之一,它允许子类获取父类的属性(数据成员)和函数(成员函数)。

什么是子类?

继承另一个类的类称为子类,它也称为派生类。

什么是父类?

被其他类继承的类称为父类,超类或基类。

继承语法

class parent_class
{//Body of parent class
};
class child_class : access_modifier parent_class
{//Body of child class
};

在 C++编程中使用继承有什么好处

继承的主要优点是代码可重用性可读性。当子类继承父类的属性和函数时,我们不需要在子类中再次编写相同的代码。这使得重用代码变得更容易,使我们编写更少的代码,代码变得更具可读性。

让我们来看一个现实生活中的例子来理解这一点:让我们假设Human是一个具有heightweightcolor等属性的类,以及诸如eat()sleep()dream()work()等函数。

现在我们要创建MaleFemale类,这些类是不同的,但由于男性和女性都是人类,他们共享一些共同的属性和行为(函数),所以他们可以继承Human类,其余的那些属性和函数可以单独写在它们的类中。

这种方法使我们编写更少的代码,因为这两个类从基类继承了几个属性和函数,因此我们不需要重写它们。此外,这使得更容易阅读代码。

继承示例

在我们讨论继承类型之前,让我们举个例子:

这里我们有两个类TeacherMathTeacherMathTeacher类继承了Teacher类,这意味着Teacher是一个父类,MathTeacher是一个子类。子类可以使用父类的属性collegeName

另一个要注意的重点是,当我们创建子类的对象时,它调用子类的构造函数,子类构造函数自动调用基类的构造函数。

#include <iostream>
using namespace std;
class Teacher {
public:Teacher(){cout<<"Hey Guys, I am a teacher"<<endl;}string collegeName = "Beginnersbook";
};
//This class inherits Teacher class
class MathTeacher: public Teacher {
public:MathTeacher(){cout<<"I am a Math Teacher"<<endl;}string mainSub = "Math";string name = "Negan";
};
int main() {MathTeacher obj;cout<<"Name: "<<obj.name<<endl;cout<<"College Name: "<<obj.collegeName<<endl;cout<<"Main Subject: "<<obj.mainSub<<endl;return 0;
}

输出:

Hey Guys, I am a teacher
I am a Math Teacher
Name: Negan
College Name: Beginnersbook
Main Subject: Math

C++ 中的继承类型

1)单一继承

2)多级继承

3)多重继承

4)分层继承

5)混合继承

单继承

在单继承中,一个类完全继承一个类。

例如:假设我们有A类和B类.

B inherits A

单一继承的例子:

#include <iostream>
using namespace std;
class A {
public:A(){cout<<"Constructor of A class"<<endl;}
};
class B: public A {
public:B(){cout<<"Constructor of B class";}
};
int main() {//Creating object of class BB obj;return 0;
}

输出:

Constructor of A class
Constructor of B class

2)多级继承

在这种类型的继承中,一个类继承另一个子类。

C inherits B and B inherits A

多级继承示例:

#include <iostream>
using namespace std;
class A {
public:A(){cout<<"Constructor of A class"<<endl;}
};
class B: public A {
public:B(){cout<<"Constructor of B class"<<endl;}
};
class C: public B {
public:C(){cout<<"Constructor of C class"<<endl;}
};
int main() {//Creating object of class CC obj;return 0;
}

输出:

Constructor of A class
Constructor of B class
Constructor of C class

多重继承

在多继承中,类可以继承多个类。这意味着在这种类型的继承中,单个子类可以具有多个父类。
例如:

C inherits A and B both

多重继承的例子:

#include <iostream>
using namespace std;
class A {
public:A(){cout<<"Constructor of A class"<<endl;}
};
class B {
public:B(){cout<<"Constructor of B class"<<endl;}
};
class C: public A, public B {
public:C(){cout<<"Constructor of C class"<<endl;}
};
int main() {//Creating object of class CC obj;return 0;
}
Constructor of A class
Constructor of B class
Constructor of C class

4)分层继承

在这种类型的继承中,一个父类具有多个子类。例如:

Class B and C inherits class A

分层继承的例子:

#include <iostream>
using namespace std;
class A {
public:A(){cout<<"Constructor of A class"<<endl;}
};
class B: public A {
public:B(){ cout<<"Constructor of B class"<<endl;}
};
class C: public A{
public:C(){cout<<"Constructor of C class"<<endl;}
};
int main() {//Creating object of class CC obj;return 0;
}

输出:

Constructor of A class
Constructor of C class

5)混合继承

混合继承是多种继承类型的组合。例如,遵循多重和分层继承的子类和父类关系都可以称为混合继承。

C++ 中的多态

原文: https://beginnersbook.com/2017/08/cpp-polymorphism/

多态是 OOP 的一个特征,它允许对象在不同条件下表现不同。在 C++ 中,我们有两种类型的多态:

1)编译时多态 - 这也称为静态(或早期)绑定。

2)运行时多态 - 这也称为动态(或晚期)绑定。

1)编译时多态

函数重载和运算符重载是编译时多态的完美例子。

编译时多态示例

在这个例子中,我们有两个具有相同名称但参数数量不同的函数。根据我们在函数调用期间传递的参数确定要调用哪个函数,这就是为什么它被视为多态的一个例子,因为在不同的条件下输出是不同的。因为,在编译期间确定调用,这就是为什么它被称为编译时多态。

#include <iostream>
using namespace std;
class Add {
public:int sum(int num1, int num2){return num1+num2;}int sum(int num1, int num2, int num3){return num1+num2+num3;}
};
int main() {Add obj;//This will call the first functioncout<<"输出: "<<obj.sum(10, 20)<<endl;//This will call the second functioncout<<"输出: "<<obj.sum(11, 22, 33);return 0;
}输出:
输出: 30
输出: 66

2)运行时多态

函数覆盖是运行时多态的一个例子。

函数覆盖:当子类声明一个已存在于父类中的方法时,这称为函数覆盖,这里子类覆盖父类。

在函数覆盖的情况下,我们有两个相同函数的定义,一个是父类,一个是子类。在运行时确定对函数的调用,以决定调用函数的哪个定义,这就是它被称为运行时多态的原因。

运行时多态的例子

#include <iostream>
using namespace std;
class A {
public:void disp(){cout<<"Super Class Function"<<endl;}
};
class B: public A{
public:void disp(){cout<<"Sub Class Function";}
};
int main() {//Parent class objectA obj;obj.disp();//Child class objectB obj2;obj2.disp();return 0;
}

输出:

Super Class Function
Sub Class Function

C++ 中的函数重载

原文: https://beginnersbook.com/2017/08/cpp-function-overloading/

函数重载是 C++ 编程的一个特性,它允许我们有多个具有相同名称但不同参数列表的函数,当我说参数列表时,它表示参数的数据类型和顺序,例如函数myfuncn(int a, float b)的参数列表是(int, float),它与函数myfuncn(float a, int b)参数列表(float, int)不同。函数重载是编译时多态。

现在我们知道什么是参数列表,让我们看一下重载规则:我们可以在同一范围内拥有以下函数。

sum(int num1, int num2)
sum(int num1, int num2, int num3)
sum(int num1, double num2)

记住这条规则的最简单方法是参数应符合以下任何一个或多个条件,它们应具有不同的类型数量顺序的参数。

例如:

这两个函数有不同的参数类型

sum(int num1, int num2)
sum(double num1, double num2)

这两个的参数数量不同:

sum(int num1, int num2)
sum(int num1, int num2, int num3)

这两个有不同的参数顺序

sum(int num1, double num2)
sum(double num1, int num2)

以上三种情况都是有效的重载情况。我们可以有任意数量的函数,只需记住参数列表应该是不同的。例如:

int sum(int, int)
double sum(int, int)

由于参数列表相同,因此不允许这样做。尽管它们具有不同的返回类型,但它无效。

函数重载示例

让我们举一个例子来理解 C++ 中的函数重载。

#include <iostream>
using namespace std;
class Addition {
public:
    int sum(int num1,int num2) {
        return num1+num2;
    }
    int sum(int num1,int num2, int num3) {    return num1+num2+num3;
    }
};
int main(void) {Addition obj;
    cout<<obj.sum(20, 15)<<endl;
    cout<<obj.sum(81, 100, 10);   return 0;
}

输出:

35
191

函数重载例 2

正如我在本指南开头所提到的,具有不同返回类型和相同参数列表的函数不能重载。但是,如果函数具有不同的参数列表,则它们可以具有相同或不同的返回类型,以便有资格进行重载。简而言之,函数的返回类型在函数重载中不起任何作用。重要的是函数的参数列表。

#include <iostream>
using namespace std;
class DemoClass {
public:
    int demoFunction(int i) {
        return i;
    }
    double demoFunction(double d) {    return d;
    }
};
int main(void) {DemoClass obj;
    cout<<obj.demoFunction(100)<<endl;
    cout<<obj.demoFunction(5005.516);
   return 0;
}

输出:

100
5006.52

函数重载的优点

函数重载的主要优点是提高代码可读性并允许代码可重用性。在示例 1 中,我们已经看到我们如何能够为具有不同参数的相同任务(添加)提供多个函数,这允许我们相加两个整数以及三个整数,如果我们希望我们可以创建一些具有相同名称和四个或五个参数的函数。

想象一下,如果我们没有函数重载,我们要么只能相加两个整数,要么为同一个任务添加编写不同的名称函数,这会降低代码的可读性和可重用性。

C++ 函数覆盖

原文: https://beginnersbook.com/2017/09/cpp-function-overriding/

函数覆盖允许我们在子类中具有已存在于父类中的相同函数。子类继承父类的数据成员和成员函数,但是当您想要覆盖覆盖中的函数时,您可以使用函数覆盖。这就像在子类中创建旧函数的新版本一样。

函数覆盖示例

要覆盖函数,您必须在子类中具有相同的签名。签名是指数据类型和参数序列。这里我们在父函数中没有任何参数,所以我们没有在子函数中使用任何参数。

#include <iostream>
using namespace std;
class BaseClass {
public:void disp(){cout<<"Function of Parent Class";}
};
class DerivedClass: public BaseClass{
public:void disp() {cout<<"Function of Child Class";}
};
int main() {DerivedClass obj = DerivedClass();obj.disp();return 0;
}

输出:

Function of Child Class

注意:在函数覆盖中,父类中的函数被称为被覆盖函数,子类中的函数称为覆盖函数。

如何从子类调用被覆盖函数

正如我们在上面看到的那样,当我们调用函数(涉及覆盖)时,会调用子类函数(覆盖函数)。如果要通过使用子类的对象来调用被覆盖的函数,该怎么办?您可以通过创建子类对象,并使父类的引用指向它来实现。让我们举个例子来理解它。

#include <iostream>
using namespace std;
class BaseClass {
public:void disp(){cout<<"Function of Parent Class";}
};
class DerivedClass: public BaseClass{
public:void disp() {cout<<"Function of Child Class";}
};
int main() {/* Reference of base class pointing to* the object of child class.*/BaseClass obj = DerivedClass(); obj.disp();return 0;
}

输出:

Function of Parent Class

如果你想从覆盖函数调用被覆盖的函数,那么你可以这样做:

parent_class_name::function_name

要在上面的例子中执行此操作,我们可以在子类的disp()函数中编写以下语句:

BaseClass::disp();

C++ 中的虚函数:运行时多态

原文: https://beginnersbook.com/2017/09/cpp-virtual-functions-runtime-polymorphism/

在本指南中,我们将看到什么是虚函数以及我们使用它们的原因。当我们在一个类中将一个函数声明为虚函数时,所有覆盖此函数的子类默认情况下的函数实现为虚函数(无论它们是否标记为虚拟)。

为什么我们声明一个虚函数?

让编译器知道需要在运行时解析对此函数的调用(也称为晚期绑定和动态链接),以便确定对象类型并且调用函数的正确版本。

让我们举个例子来理解当我们不将覆盖函数标记为虚拟时会发生什么。

示例 1:覆盖非虚函数

在这里看到问题。即使我们指向子类的实例(对象)的父类指针,也会调用该函数的父类版本。

您可能在想我为什么创建指针,我可以简单地创建子类的对象,如下所示:Dog obj;并将Dog实例分配给它。好吧,在这个例子中我只有一个子类,但是当我们有一个包含多个子类的大项目时,不建议单独创建子类的对象,因为它增加了复杂性并且代码容易出错。在此示例之后更加清晰。

#include<iostream>
using namespace std;
//Parent class or super class or base class
class Animal{
public:void animalSound(){cout<<"This is a generic Function";}
};
//child class or sub class or derived class
class Dog : public Animal{
public:void animalSound(){      cout<<"Woof";  }
};
int main(){Animal *obj;obj = new Dog();obj->animalSound();return 0;
}

输出:

This is a generic Function

示例 2:使用虚函数

在这种情况下,输出是Woof,这是我们所期望的。在这种情况下会发生什么?由于我们将函数animalSound()标记为虚拟,因此在运行时解析对函数的调用,编译器在运行时确定对象的类型并调用适当的函数。

#include<iostream>
using namespace std;
//Parent class or super class or base class
class Animal{
public:virtual void animalSound(){cout<<"This is a generic Function";}
};
//child class or sub class or derived class
class Dog : public Animal{
public:void animalSound(){      cout<<"Woof";  }
};
int main(){Animal *obj;obj = new Dog();obj->animalSound();return 0;
}

输出:

Woof

C++ 中的变量

原文: https://beginnersbook.com/2017/08/cpp-variables/

变量是与可以更改的值相关联的名称。例如,当我写int num=20;时,变量名是num,它与值 20 相关联,int是数据类型,表示该变量可以保存整数值。我们将在下一个教程中介绍数据类型。在本教程中,我们将讨论变量。

在 C++ 中声明变量的语法

data_type variable1_name = value1, variable2_name = value2;

例如:

int num1=20, num2=100;

我们也可以这样写:

int num1,num2;
num1=20;
num2=100;

变量的类型

变量可以根据其数据类型进行分类。例如,在上面的例子中,我们看到了整数类型变量。以下是 C++ 中可用的变量类型。

int :这些类型的变量保存整数值。

char :保存字符值,如'c''F''B''p''q'等。

bool :保存布尔值为truefalse

double :双精度浮点值。

float :单精度浮点值。

基于作用域的变量类型

在进一步讨论之前,先讨论什么是作用域。当我们讨论 Hello World 程序时,我们在程序中看到了这样的大括号:

int main {//Some code}

在这些花括号内声明的任何变量都限制在这些花括号中,如果你在main()函数中声明一个变量并尝试在main()函数之外使用该变量,那么你将得到编译错误。

现在我们已经理解了什么是作用域。让我们根据作用域转向变量类型。

  1. 全局变量
  2. 局部变量

全局变量

在任何函数之外声明的变量(包括main)也称为全局变量。全局变量拥有整个程序中的作用域,它们可以在程序的任何地方,主函数,用户定义的函数中的任何地方访问。

让我们举个例子来理解它:

全局变量示例

这里我们有一个全局变量myVar,它在main之外声明。我们在main()函数中访问了变量两次而没有任何问题。

#include <iostream>
using namespace std;
// This is a global variable
char myVar = 'A';
int main()
{cout <<"Value of myVar: "<< myVar<<endl;myVar='Z';cout <<"Value of myVar: "<< myVar;return 0;
}

输出:

Value of myVar: A
Value of myVar: Z

局部变量

局部变量在任何用户定义函数,主函数,循环或任何控制语句(ifif-else等)的大括号内声明,并且其作用域限制在这些大括号内。

局部变量的例子

#include <iostream>
using namespace std;char myFuncn() {
// This is a local variable
char myVar = 'A';
}
int main()
{cout <<"Value of myVar: "<< myVar<<endl;myVar='Z';cout <<"Value of myVar: "<< myVar;return 0;
}

输出:

编译时错误,因为我们试图在其作用域之外访问变量myVarmyVar的作用域仅限于这些括号内的函数体myFuncn()

全局变量和局部变量可以在 C++ 中具有相同的名称吗?

让我们看一个具有相同名称的全局变量和局部变量的示例。

#include <iostream>
using namespace std;
// This is a global variable
char myVar = 'A';
char myFuncn() {// This is a local variablechar myVar = 'B';return myVar;
}
int main()
{cout <<"Funcn call: "<< myFuncn()<<endl;cout <<"Value of myVar: "<< myVar<<endl;myVar='Z';cout <<"Funcn call: "<< myFuncn()<<endl;cout <<"Value of myVar: "<< myVar<<endl;return 0;
}

输出:

Funcn call: B
Value of myVar: A
Funcn call: B
Value of myVar: Z

正如您所看到的,当我在main函数中更改myVar的值时,它只更改了全局变量myVar的值,因为局部变量myVar作用域仅限于函数myFuncn()

C++ 封装

原文: https://beginnersbook.com/2017/09/cpp-encapsulation/

封装是将数据成员和函数组合在一个称为类的单个单元中的过程。这是为了防止直接访问数据,通过类的函数提供对它们的访问。它是面向对象编程(OOP)的流行特性之一,它有助于数据隐藏

如何在类上实现封装

为此:

1)将所有数据成员设为私有。

2)为每个数据成员创建公共设置器和获取器函数,使设置器设置数据成员的值,获取器获取数据成员的值。

让我们在一个示例程序中看到这个:

C++ 中的封装示例

这里我们有两个数据成员numch,我们已将它们声明为私有,因此它们在类外无法访问,这样我们就隐藏了数据。获取和设置这些数据成员的值的唯一方法是通过公共设置器和获取器函数。

#include<iostream>
using namespace std;
class ExampleEncap{
private:/* Since we have marked these data members private,* any entity outside this class cannot access these* data members directly, they have to use getter and* setter functions.*/int num;char ch;
public:/* Getter functions to get the value of data members.* Since these functions are public, they can be accessed* outside the class, thus provide the access to data members* through them*/int getNum() const {return num;}char getCh() const {return ch;}/* Setter functions, they are called for assigning the values* to the private data members.*/void setNum(int num) {this->num = num;}void setCh(char ch) {this->ch = ch;}
};
int main(){ExampleEncap obj;obj.setNum(100);obj.setCh('A');cout<<obj.getNum()<<endl;cout<<obj.getCh()<<endl;return 0;
}

输出:

100
A

C++ 中的抽象

原文: https://beginnersbook.com/2017/09/abstraction-in-c-with-example/

抽象是面向对象编程的功能之一,您只需向用户显示相关详细信息并隐藏不相关的详细信息。例如,当您向某人发送电子邮件时,您只需单击“发送”即可获得成功消息,单击“发送”时实际发生的情况,数据通过网络传输给收件人的方式对您来说是隐藏的(因为它与您无关) 。

让我们看看如何使用访问说明符在 C++ 程序中实现:

抽象示例

#include <iostream>
using namespace std;
class AbstractionExample{
private:/* By making these data members private, I have* hidden them from outside world.* These data members are not accessible outside* the class. The only way to set and get their* values is through the public functions.*/int num;
   char ch;public:void setMyValues(int n, char c) {num = n; ch = c;}void getMyValues() {cout<<"Numbers is: "<<num<< endl;cout<<"Char is: "<<ch<<endl;}
};
int main(){AbstractionExample obj;obj.setMyValues(100, 'X');obj.getMyValues();return 0;
}

输出:

Numbers is: 100
Char is: X

数据抽象的优势

使用此功能的主要优点是,当代码发展并且您需要在代码中进行一些调整时,您只需要修改已将成员声明为私有的高级类。由于没有类直接访问这些数据成员,因此您无需更改低级别(用户级别)类代码。

想象一下,如果您将这些数据成员公开,如果在某些时候您想要更改代码,则必须对直接访问成员的所有类进行必要的调整。

数据抽象的其他优点是:

1)通过使数据私有化并避免可能破坏数据的用户级错误,使应用安全。

2)这避免了代码重复并增加了代码的可重用性。

C++ 中的接口:抽象类

原文: https://beginnersbook.com/2017/09/cpp-abstract-class/

在 C++ 中,我们互换使用术语抽象类和接口。具有纯虚函数的类称为抽象类。例如,以下函数是纯虚函数:

virtual void fun() = 0;

纯虚函数用虚拟关键字标记,签名后有= 0。您可以将此函数称为抽象函数,因为它没有正文。派生类必须为父类的所有纯虚函数提供实现,否则默认情况下它将成为抽象类。

为什么我们需要一个抽象类?

让我们借助现实生活中的例子来理解这一点。让我们说我们有一个类Animal,它会睡眠,发出声音等等。现在我只考虑这两个行为并创建一个具有两个函数sound()sleeping()的类Animal

现在,我们知道动物的声音是不同的,猫说“喵”,狗说“汪”。那么我在Animal类中为函数sound()提供了什么实现?这样做的唯一和正确的方法是使这个函数纯粹抽象,这样我就不需要在Animal类中给出实现但是所有继承Animal的类必须为此函数提供实现。这样我确保所有动物都有声音,但它们有独特的声音。

可以在 C++ 程序中编写相同的示例,如下所示:

抽象类示例

#include<iostream>
using namespace std;
class Animal{
public://Pure Virtual Functionvirtual void sound() = 0;//Normal member Functionvoid sleeping() {cout<<"Sleeping";}
};
class Dog: public Animal{
public:void sound() {cout<<"Woof"<<endl;}
};
int main(){Dog obj;obj.sound();obj.sleeping();return 0;
}

抽象类规则

1)我们已经看到任何具有纯虚函数的类都是抽象类。

2)我们无法创建抽象类的实例。例如:如果我在上面的程序中写了这行Animal obj;,就会导致编译错误。

3)我们可以创建指向子类的实例的抽象基类的指针和引用。例如,这是有效的:

Animal *obj = new Dog();
obj->sound();

4)抽象类可以有构造函数。

5)如果派生类没有实现父类的纯虚函数,则派生类变为抽象类。

从 C++ 中的函数传递和返回对象

原文: https://beginnersbook.com/2017/09/cpp-pass-and-return-object-from-a-function/

在本教程中,我们将了解如何将对象作为参数传递给函数以及如何从函数返回对象。

将对象传递给函数

可以将对象传递给函数,就像我们将结构传递给函数一样。在A类中,我们有一个函数disp(),我们在其中传递类A的对象。类似地,我们可以将一个类的对象传递给不同类的函数。

#include <iostream>
using namespace std;
class A {
public:int n=100;char ch='A';void disp(A a){cout<<a.n<<endl;cout<<a.ch<<endl;}
};
int main() {A obj;obj.disp(obj);return 0;
}

输出:

100
A

从函数返回对象

在这个例子中,我们有两个函数,函数input()返回Student对象,disp()Student对象作为参数。

#include <iostream>
using namespace std;
class Student {
public:int stuId;int stuAge;string stuName;/* In this function we are returning the* Student object.*/Student input(int n, int a, string s){Student obj;obj.stuId = n;obj.stuAge = a;obj.stuName = s;return obj;}/* In this function we are passing object* as an argument.*/void disp(Student obj){cout<<"Name: "<<obj.stuName<<endl;cout<<"Id: "<<obj.stuId<<endl;cout<<"Age: "<<obj.stuAge<<endl;}
};
int main() {Student s;s = s.input(1001, 29, "Negan");s.disp(s);return 0;
}

输出:

Name: Negan
Id: 1001
Age: 29

C++ 中的友元类和友元函数

原文: https://beginnersbook.com/2017/09/friend-class-and-friend-functions/

我们知道一个类无法访问其他类的私有成员。类似地,不继承另一个类的类不能访问其受保护的成员。

友元类:

友元类是一个类,可以访问被声明为友元的类的私有成员和受保护成员。当我们想要允许特定类访问类的私有成员和受保护成员时,这是必需的。

函数类示例

在这个例子中,我们有两个类XYZABCXYZ类有两个私有数据成员chnum,这个类将ABC声明为友元类。这意味着ABC可以访问XYZ的私有成员,在ABC类的函数disp()访问私有成员numch的示例中也证明了这一点。在这个例子中,我们将对象作为参数传递给函数。

#include <iostream>
using namespace std;
class XYZ {
private:char ch='A';int num = 11;
public:/* This statement would make class ABC* a friend class of XYZ, this means that* ABC can access the private and protected* members of XYZ class. */friend class ABC;
};
class ABC {
public:void disp(XYZ obj){cout<<obj.ch<<endl;cout<<obj.num<<endl;}
};
int main() {ABC obj;XYZ obj2;obj.disp(obj2);return 0;
}

输出:

A
11

友元函数:

与友元类相似,此函数可以访问另一个类的私有和受保护成员。全局函数也可以声明为友元,如下例所示:

友元函数示例

#include <iostream>
using namespace std;
class XYZ {
private:int num=100;char ch='Z';
public:friend void disp(XYZ obj);
};
//Global Function
void disp(XYZ obj){cout<<obj.num<<endl; cout<<obj.ch<<endl;
}
int main() {XYZ obj;disp(obj);return 0;
}

输出:

100
Z

C++ 中的数据类型

原文: https://beginnersbook.com/2017/08/cpp-data-types/

数据类型定义变量可以容纳的数据类型,例如整数变量可以保存整数数据,字符类型变量可以保存字符数据等。

C++ 中的数据类型分为三组:内置用户定义派生

data types in c++

内置数据类型

char :用于字符。大小 1 个字节。

char ch = 'A';

int :用于整数。大小 2 个字节。

int num = 100;

float :用于单精度浮点数。大小 4 个字节。

float num = 123.78987;

double :用于双精度浮点数。大小为 8 个字节。

double num = 10098.98899;

bool :用于布尔,真或者假。

bool b = true;

wchar_t :宽字符。应该避免这种情况,因为它的大小是实现定义的并且不可靠。

用户定义的数据类型

我们在 C++中有三种类型的用户定义数据类型。

  1. struct
  2. union
  3. enum

我在单独的教程中详细介绍了它们。现在只记得它们属于用户定义的数据类型。

C++ 中的派生数据类型

我们在 C++ 中有三种派生数据类型

  1. 数组
  2. 函数
  3. 指针

它们是 C++ 的广泛主题,我在单独的教程中介绍了它们。按照给定顺序阅读教程,你会没事的。

C++ 中的运算符

原文: https://beginnersbook.com/2017/08/cpp-operators/

运算符代表一个行为。例如,+是表示加法的运算符。运算符处理两个或多个操作数并生成输出。例如3 + 4 + 5,这里+运算符在三个操作数上工作并产生 12 作为输出。

C++ 中的运算符类型

C++ Operator Types

1)基本算术运算符

2)赋值运算符

3)自增和自减运算符

4)逻辑运算符

5)比较(关系)运算符

6)位运算符

7)三元运算符

1)基本算术运算符

基本算术运算符为:+ - * / %

  • + 用于加法。
  • - 用于减法。
  • * 用于乘法。
  • / 用于除法。
  • %用于模数。

:模运算符返回余数,例如20%5将返回 0。

算术运算符的例子

#include <iostream>
using namespace std;
int main(){int num1 = 240; int num2 = 40;cout<<"num1 + num2: "<<(num1 + num2)<<endl;cout<<"num1 - num2: "<<(num1 - num2)<<endl; cout<<"num1 * num2: "<<(num1 * num2)<<endl; cout<<"num1 / num2: "<<(num1 / num2)<<endl;cout<<"num1 % num2: "<<(num1 % num2)<<endl;return 0;
}

输出:

num1 + num2: 280
num1 - num2: 200
num1 * num2: 9600
num1 / num2: 6
num1 % num2: 0

2)赋值运算符

C++ 中的赋值运算符是:= += -= *= /= %=

  • num2 = num1 将变量num1的值赋给变量num2
  • num2 += num1 等于num2 = num2 + num1
  • num2 -= num1 等于num2 = num2 - num1
  • num2 *= num1 等于num2 = num2 * num1
  • num2 /= num1 等于num2 = num2 / num1
  • num2 %= num1 等于num2 = num2 % num1

赋值运算符的示例

#include <iostream>
using namespace std;
int main(){int num1 = 240;int num2 = 40;num2 = num1;cout<<"= 输出: "<<num2<<endl;num2 += num1;cout<<"+= 输出: "<<num2<<endl;num2 -= num1;
 cout<<"-= 输出: "<<num2<<endl;num2 *= num1;      cout<<"*= 输出: "<<num2<<endl;num2 /= num1;      cout<<"/= 输出: "<<num2<<endl;num2 %= num1;      cout<<"%= 输出: "<<num2<<endl;return 0;
}

输出:

= 输出: 240
+= 输出: 480
-= 输出: 240
*= 输出: 57600
/= 输出: 240
%= 输出: 0

3)自增和自减运算符

++--

  • num++相当于num = num + 1;
  • num--相当于num = num - 1;

自增和自减运算符的示例

#include <iostream>
using namespace std;
int main(){int num1 = 240;int num2 = 40;num1++; num2--;cout<<"num1++ is: "<<num1<<endl;cout<<"num2-- is: "<<num2;return 0;
}

输出:

num1++ is: 241
num2-- is: 39

4)逻辑运算符

逻辑运算符与二进制变量一起使用。它们主要用于条件语句和循环以评估条件。

C++中的逻辑运算符是:&& || !

假设我们有两个布尔变量b1b2

如果b1b2都为真,则b1 && b2将返回true,否则它将返回false

如果b1b2都为假,则b1 || b2将返回false,否则返回true

!b1将返回与b1相反的东西,这意味着如果b1为假则为真,如果b1为真则返回false

逻辑运算符的示例

#include <iostream>
using namespace std;
int main(){bool b1 = true;
   bool b2 = false;cout<<"b1 && b2: "<<(b1&&b2)<<endl;  cout<<"b1 || b2: "<<(b1||b2)<<endl;
   cout<<"!(b1 && b2): "<<!(b1&&b2);return 0;
}

输出:

b1 && b2: 0
b1 || b2: 1
!(b1 && b2): 1

5)关系运算符

我们在 C++中有六个关系运算符:== != > < >= <=

  • 如果左侧和右侧都相等,则==返回true
  • 如果左侧不等于右侧,则!=返回 true。
  • 如果左侧大于右侧,>返回true
  • 如果左侧小于右侧,<返回true
  • 如果左侧大于或等于右侧,则>=返回true
  • 如果左侧小于或等于右侧,则<=返回true

关系运算符的示例

#include <iostream>
using namespace std;
int main(){int num1 = 240;int num2 =40;if (num1==num2) {cout<<"num1 and num2 are equal"<<endl;
   }  else{cout<<"num1 and num2 are not equal"<<endl;  }if( num1 != num2 ){     cout<<"num1 and num2 are not equal"<<endl; } else{      cout<<"num1 and num2 are equal"<<endl;  }if( num1 > num2 ){     cout<<"num1 is greater than num2"<<endl;  }  else{     cout<<"num1 is not greater than num2"<<endl;  }if( num1 >= num2 ){ 
      cout<<"num1 is greater than or equal to num2"<<endl;  }  else{     cout<<"num1 is less than num2"<<endl;  }if( num1 < num2 ){cout<<"num1 is less than num2"<<endl;  }  else{cout<<"num1 is not less than num2"<<endl;  }if( num1 <= num2){cout<<"num1 is less than or equal to num2"<<endl;  }  else{cout<<"num1 is greater than num2"<<endl;  }return 0;
}

输出:

num1 and num2 are not equal
num1 and num2 are not equal
num1 is greater than num2
num1 is greater than or equal to num2
num1 is not less than num2
num1 is greater than num2

6)按位运算符

有六个按位运算符:& | ^ ~ << >>

num1 = 11; /* equal to 00001011*/
num2 = 22; /* equal to 00010110 */

按位运算符执行逐位处理。

num1 & num2比较num1num2的相应位,如果两个位相等则生成 1,否则返回 0。在我们的例子中它将返回:2,这是00000010,因为在num1num2的二进制形式中,只有倒数第二位匹配。

num1 | num2比较num1num2的相应位,如果任一位为 1,则生成 1,否则返回 0。在我们的例子中,它将返回 31,即00011111

num1 ^ num2比较num1num2的相应位,如果它们不相等则生成 1,否则返回 0。在我们的例子中它将返回 29,相当于00011101

~num1 是一个补码运算符,只是将位从 0 更改为 1,1 更改为 0。在我们的示例中,它将返回 -12,相当于11110100

num1 << 2是左移位运算符,它将位移到左边,丢弃最左边的位,并将最右边的位赋值为 0。在我们的例子中,输出为 44,相当于00101100

注意:在下面的示例中,我们在此移位运算符的右侧提供 2,这是位向左移动两个位置的原因。我们可以更改此数字,并且位将按照移位运算符右侧指定的位数移动。同样适用于右移位运算符。

num1 >> 2是右移位运算符,它将位向右移动,丢弃最右位,并将最左边的位指定为 0。在我们的例子中,输出为 2,相当于00000010

按位运算符的示例

#include <iostream>
using namespace std;
int main(){int num1 = 11;  /* 11 = 00001011 */  int num2 = 22;  /* 22 = 00010110 */ 
   int result = 0;result = num1 & num2;  cout<<"num1 & num2: "<<result<<endl;result = num1 | num2; cout<<"num1 | num2: "<<result<<endl;result = num1 ^ num2;  cout<<"num1 ^ num2: "<<result<<endl;result = ~num1; cout<<"~num1: "<<result<<endl;result = num1 << 2; cout<<"num1 << 2: "<<result<<endl;result = num1 >> 2;  cout<<"num1 >> 2: "<<result;return 0;
}

输出:

num1 & num2: 2
num1 | num2: 31
num1 ^ num2: 29
~num1: -12
num1 << 2: 44 num1 >> 2: 2

7)三元运算符

此运算符计算布尔表达式并根据结果赋值。

语法:

variable num1 = (expression) ? value if true : value if false

如果表达式结果为true,则将冒号(:)之前的第一个值赋给变量num1,否则将第二个值赋给num1

三元运算符的例子

#include <iostream>
using namespace std;
int main(){int num1, num2; num1 = 99;/* num1 is not equal to 10 that's why* the second value after colon is assigned* to the variable num2*/num2 = (num1 == 10) ? 100: 200;cout<<"num2: "<<num2<<endl;/* num1 is equal to 99 that's why* the first value is assigned* to the variable num2*/num2 = (num1 == 99) ? 100: 200;cout<<"num2: "<<num2;return 0;
}

输出:

num2: 200
num2: 100

杂项运算符

C++ 中很少有其他运算符,如逗号运算符sizeof运算符。我们将在单独的教程中详细介绍它们。

C++ 中的运算符优先级

如果表达式具有多个运算符,则确定首先需要对哪个运算符求值。顶部的运算符具有较高优先级,底部具有较低优先级。

  • 一元运算符

    ++ -- ! ~

  • 乘法

    * / %

  • 加法

    + -

  • 移位

    << >>

  • 关系

    < <= > >=

  • 相等

    == !=

  • 位与

    &

  • 位异或

    ^

  • 位或

    |

  • 逻辑与

    &&

  • 逻辑或

    ||

  • 三元

    ?:

  • 赋值

    = += -= *= /= %= >>= <<= &= ^= |=

控制语句

C++ 中的if语句

原文: https://beginnersbook.com/2017/08/cpp-if-else-statement/

有时我们只有在满足或不满足特定条件时才需要执行一个语句块。这被称为决策,因为我们在程序逻辑中做出决定后执行某个代码。对于 C++ 中的决策,我们有四种类型的控制语句(或控制结构),如下所示:

a)if语句

b)嵌套if语句

c)if-else语句

d)if-else-if语句

C++ 中的if语句

if语句包含条件,后跟语句或一组语句,如下所示:

if(condition){Statement(s);
}

if括号(通常称为正文)中的语句仅在给定条件为真时才执行。如果条件为假,则完全忽略正文中的语句。**

if语句的流程图

if statement flow diagram

if语句的示例

#include <iostream>
using namespace std;
int main(){int num=70;if( num < 100 ){/* This cout statement will only execute,* if the above condition is true*/ cout<<"number is less than 100";}if(num > 100){/* This cout statement will only execute,* if the above condition is true*/ cout<<"number is greater than 100";}return 0;
}

输出:

number is less than 100

C++ 中的嵌套if语句

当在另一个if语句中有if语句时,它被称为嵌套if语句。嵌套的结构如下所示:

if(condition_1) {Statement1(s);if(condition_2) {Statement2(s);}
}

如果condition_1true,则执行Statement1。只有条件(condition_1condition_2)都为真时,Statement2才会执行。

嵌套if语句的示例

#include <iostream>
using namespace std;
int main(){int num=90;/* Nested if statement. An if statement* inside another if body*/if( num < 100 ){cout<<"number is less than 100"<<endl;if(num > 50){cout<<"number is greater than 50";} }return 0;
}

输出:

number is less than 100
number is greater than 50

在 C++ 中使用if-else语句

有时你有一个条件,如果条件为真,你想要执行一段代码,如果相同的条件为假,则执行另一段代码。这可以使用if-else语句在 C++ 中实现。

这是if-else语句的外观:

if(condition) {Statement(s);
}
else {Statement(s);
}

如果条件为真,则if内的语句将执行,如果条件为假,则else内的语句将执行。

if-else

If else flow diagram的流程图

if-else语句的示例

#include <iostream>
using namespace std;
int main(){int num=66;if( num < 50 ){//This would run if above condition is truecout<<"num is less than 50";}else {//This would run if above condition is falsecout<<"num is greater than or equal 50";}return 0;
}

输出:

num is greater than or equal 50

C++ 中的if-else-if语句

当我们需要检查多个条件时使用if-else-if语句。在这个控制结构中,我们只有一个if和一个else,但是我们可以有多个else if块。这是它的样子:

if(condition_1) {/*if condition_1 is true execute this*/statement(s);
}
else if(condition_2) {/* execute this if condition_1 is not met and* condition_2 is met*/statement(s);
}
else if(condition_3) {/* execute this if condition_1 & condition_2 are* not met and condition_3 is met*/statement(s);
}
.
.
.
else {/* if none of the condition is true* then these statements gets executed*/statement(s);
}

注意:这里要注意的最重要的一点是,在if-else-if中,只要满足条件,就会执行相应的语句集,忽略其余。如果没有满足条件,则执行else内的语句。

if-else-if的示例

#include <iostream>
using namespace std;
int main(){int num;cout<<"Enter an integer number between 1 & 99999: ";cin>>num;if(num <100 && num>=1) {cout<<"Its a two digit number";}else if(num <1000 && num>=100) {cout<<"Its a three digit number";}else if(num <10000 && num>=1000) {cout<<"Its a four digit number";}else if(num <100000 && num>=10000) {cout<<"Its a five digit number";}else {cout<<"number is not between 1 & 99999";}return 0;
}

输出:

Enter an integer number between 1 & 99999: 8976
Its a four digit number

C++ 中的switch-case语句

原文: https://beginnersbook.com/2017/08/cpp-switch-case/

当我们有多个条件并且我们需要根据条件执行不同的操作时,使用switch case语句。当我们有多个条件时,我们需要在满足特定条件时执行一个语句块。在这种情况下,我们可以使用冗长的 if..else-if语句或switch case。冗长if..else-if的问题是当我们有几个条件时它会变得复杂。switch-case是处理这种情况的干净而有效的方法。

switch case语句的语法:

switch (variable or an integer expression)
{case constant://C++ code;case constant://C++ code;default://C++ code;
}

即使break语句是可选的,switch case语句也大量使用break语句。我们将首先看到一个没有break语句的例子,然后我们将讨论switch casebreak

switch-case示例

#include <iostream>
using namespace std;
int main(){int num=5;switch(num+2) {case 1: cout<<"Case1: Value is: "<<num<<endl;case 2: cout<<"Case2: Value is: "<<num<<endl;case 3: cout<<"Case3: Value is: "<<num<<endl;default: cout<<"Default: Value is: "<<num<<endl;}return 0;
}

输出:

Default: Value is: 5

说明:在swicth中我给出了一个表达式,你也可以给出变量。我给了表达式num + 2,其中num值是 5,并且在相加之后表达式得到 7。由于没有用值 4 定义的情况,所以执行了默认情况。

switch-case流程图

它求值表达式或变量的值(基于switch括号内给出的内容),然后根据结果执行相应的情况。

switch case flow diagram

switch-case中的break语句

在我们讨论break语句之前,让我们看看当我们在switch case中不使用break语句时会发生什么。请参阅以下示例:

#include <iostream>
using namespace std;
int main(){int i=2;switch(i) {case 1: cout<<"Case1 "<<endl;case 2: cout<<"Case2 "<<endl;case 3: cout<<"Case3 "<<endl;case 4: cout<<"Case4 "<<endl;default: cout<<"Default "<<endl; }return 0;
}

输出:

Case2 
Case3 
Case4 
Default 

在上面的程序中,我们在switch括号内部有变量i,这意味着无论变量i的值是什么,都会执行相应的case块。我们已将整数值 2 传递给switch,因此控制流切换到case 2,但是在case 2 之后我们没有使用break语句,导致控制流继续到后续case直到结束。然而,这不是我们想要的,我们想要执行正确case块并忽略其余的块。这个问题的解决方案是在每个case块之后使用break语句。

当您希望程序流从switch主体中出来时,使用break语句。每当在switch主体中遇到break语句时,执行流程将直接从switch中出来,忽略其余的情况。这就是您必须使用break语句结束每个case块的原因。

让我们采用相同的例子,但这次使用break语句。

#include <iostream>
using namespace std;
int main(){int i=2;switch(i) {case 1:cout<<"Case1 "<<endl;break;case 2:cout<<"Case2 "<<endl;break;case 3:cout<<"Case3 "<<endl;break;case 4:cout<<"Case4 "<<endl;break;default:cout<<"Default "<<endl;}return 0;
}

输出:

Case2

现在您可以看到只有case 2被执行,其余的后续case被忽略了。

为什么我在default块不使用break语句?

控制流本身会在默认情况下从switch中出来,所以我之后没有使用break语句,但是如果你想要它可以使用它,那么这样做是没有害处的。

重要笔记

1)case并不总是需要顺序1,2,3等。它可以在case关键字后面包含任何整数值。此外,case不需要始终按升序排列,您可以根据要求以任何顺序指定它们。

2)您也可以在switch-case中使用字符。例如:

#include <iostream>
using namespace std;
int main(){char ch='b';switch(ch) {case 'd': cout<<"Case1 ";break;case 'b': cout<<"Case2 ";break;case 'x': cout<<"Case3 ";break;case 'y': cout<<"Case4 ";break;default: cout<<"Default ";}return 0;
}

3)允许嵌套switch语句,这意味着你可以在另一个switch内部使用switch语句。但是应该避免使用嵌套的switch语句,因为它会使程序更复杂,更不易读。

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

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

相关文章

BeginnersBook-Servlet-教程-一-

BeginnersBook Servlet 教程(一)原文:BeginnersBook 协议:CC BY-NC-SA 4.0项目的web.xml文件中的welcome-file-list标签原文: https://beginnersbook.com/2014/04/welcome-file-list-in-web-xml/你有没见过web.xml文件中的<welcome-file-list>标签并想知道它是什么?…

.net7.0 WebApi 添加 JWT 验证

https://blog.csdn.net/u012563853/article/details/128659472 详细步骤: 1.创建默认WebApi 项目2.开始添加认证包 安装 Microsoft.AspNetCore.Authentication.JwtBearer 包 这个包是用来支持WebApi 的 JWT 认证的3.在appsetting 中配置JWT的配置信息 这里需要注意的是 key …

2024-10-24 瀑布流(vue3)

效果图: 代码:<template><div id="waterfallContainer" class="waterfall-container"><div v-for="(column, columnIndex) in columns" :key="columnIndex" class="waterfall-column"><div v-for=&q…

如何用反射调用泛型类的方法

例子一:泛型类不含构造函数using System; using System.Reflection;namespace 使用反射调用泛型类的方法 {class Program{static void Main(string[] args){//定义要使用的类型参数(就是调用方法时要传入的参数类型,例如int)Type genericTypeArgument = typeof(int);//获取…

[日志分析篇]-利用ELK分析jumpserver日志-日志拆分篇

需要通过elk日志分析平台接收jumpserver日志,对日志进行过滤和拆分。并通过Grafana进行企业微信告警推送和大屏展示1.系统介绍名称 软件版本jumpserver jumpserver-3.10.13-tlselasticsearch elasticsearch-8.12.2kibana kibana-8.12.2logstash logstash-8.12.2granfa Grafana…

IDEA运行不了代码

同样的代码在eclipse可以正常运行,创建的方法也保持一样,为什么在IDEA就报错,本人是小白看不懂下面的报错

扩展被恢复分区挡住的 C 盘

之前装系统的时候想着以后要不要装个 Ubuntu 以作备用,所以给 SSD 分区的时候留了一小部分,没有全分给 C 盘。结果后来用 WSL 用得乐不思蜀了,觉得剩下的空间留着没必要,于是想把剩下的空间扩容给 C 盘。结果操作的时候发现 C 盘后面跟了一个恢复分区!无法给 C 盘扩容了。…

若依开启注册功能

若依开启用户注册功能 1、修改数据库,如下:2、修改前端:参考鸣谢: https://blog.csdn.net/weixin_43684214/article/details/121609310

OCR视图识别(Tess4J)

1.概述 图片文字识别 OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程 2.Tess4j快速入门 1.导入依赖<dependencies><…

『模拟赛』多校A层冲刺NOIP2024模拟赛12

『模拟赛记录』多校A层冲刺NOIP2024模拟赛12Rank 挂了不少,还行A. Alice 和璀璨花 签。 一眼最长上升子序列,昨天在 AT 专题里刚见过,不过赛时没想到离散化之后树状数组,所以打的动态开点,结果细节挂了 30pts。 和最长上升子序列思路基本一致,直接区间查询 \([1,a_i-1]\)…

分享一些利用商品详情数据挖掘潜在需求的成功案例

以下是一些利用商品详情数据挖掘潜在需求的成功案例: 一、亚马逊的个性化推荐系统:案例背景:亚马逊是全球知名的电商平台,拥有海量的商品和庞大的用户群体。为了提高用户的购物体验和增加销售额,亚马逊投入大量资源开发个性化推荐系统。 数据挖掘过程:亚马逊通过分析用户…