C++基础

C++ 多维数组

C++ 支持多维数组。多维数据声明的一般形式如下:

1
type name[size1][size2]...[sizeN];

例如,下面的声明创建了一个三维5.10.4 整型数组:

1
int threedim[5][10][4];

二维数组

多维数组最简单的形式是二维数据,一个二维数组,在本质上,是一个一维数组的列表。申明一个 x 行 y 列的二维整型数组,形式如下:

1
type arrayName [ x ] [ y ];

其中,type 可以是任意有效的 C++ 数据类型, arrayName 是一个有效的 C++ 标识符。一个二维数组可以被认为是一个带有 x 行和 y 列的表格。下面是一个二维数组,包含 3 行和 4 列:

Column 0 Column 1 Column 2 Column 3
Row 0 a[0][0] a[0][1] a[0][2] a[0][3]
Row 1 a[1][0] a[1][1] a[1][2] a[1][3]
Row 2 a[2][0] a[2][1] a[2][2] a[2][3]

因此,数组中的每个元素是使用形式为a[i,j] 的元素名称来标识,其中 a 是数组名称,i 和 j 是唯一标示 a 中每个元素的下标。

初始化二维数组

多维数组可以通过在括号内为每行指定值来进行初始化。下面是一个带有 3 行 4 列的数组。

1
2
3
4
5
int a[3][4] = {
{0, 1, 2, 3}, //初始化索引号为 0 的行
{4, 5, 6, 7}, //初始化索引号为 1 的行
{8, 9, 10, 11} //初始化索引号为 2 的行
};

内部嵌套的括号是可选的,下面的初始化与上面是等同的:

1
int a[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11}

访问二维数组元素

二维数组中的元素是通过使用下标(即数组的行索引和列索引)来访问的。例如:

1
int val = a[2][3];

上面的语句将获取数组中第3行第4个元素。您可以通过上面的示意图来进行验证。让我们来看看下面的程序,我们将使用嵌套循环来处理二维数组:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

using namespace std;

int main() {
int a[5][2] {
{0,1},
{1,2},
{3,4},
{5,6},
{7,8}
};

for ( int i = 0; i < 5; i++ )
for ( int j = 0; j < 2; j++ ) {
cout << "a[" << i <<"] [" << j << "]: ";
cout << a[i][j] << endl;
}
return 0;
};

当上面的代码被编译和执行时,它会产生下列结果:

1
2
3
4
5
6
7
8
9
10
a[0] [0]: 0
a[0] [1]: 1
a[1] [0]: 1
a[1] [1]: 2
a[2] [0]: 3
a[2] [1]: 4
a[3] [0]: 5
a[3] [1]: 6
a[4] [0]: 7
a[4] [1]: 8

如上所述,您可以创建任意维度的数组,但是一般情况下,我们创建的数组是一维数组和二维数组。

C++ 类成员函数

类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。类成员函数是类的一个成员,它可以操作类的任意对象,可以访问对象中的所有成员。

让我们看看之前定义的类 Box,现在我们要使用成员函数来访问类的成员,而不是直接访问这些类的成员:

1
2
3
4
5
6
7
8
class Box
{
public:
double length; //长度
double breadth; //宽度
double height; //高度
double getVolume(void); //返回体积
};

成员函数可以定义在类定义内部,或者单独使用范围解析运算符 :: 来定义。在类定义中定义的成员函数把函数声明为内联的,即便没有使用 inline 标识符。所以您可以按照如下方式定义 Volume() 函数:

1
2
3
4
5
6
7
8
9
10
11
12
class Box
{
public:
double length; //长度
double breadth; //宽度
double height; //高度

double GetVolume(void)
{
return Length * breadth * height;
}
}

您也可以在类的外部使用范围解析运算符 :: 定义该函数,如下所示:

1
2
3
4
double Box::getVolume(void)
{
return length * breadth * height;
}

在这里,需要强调一点,在 :: 运算符之前必须使用类名。调用成员函数是在对象上使用点运算符(.),这样它就能操作与该对象相关的数据,如下所示:

1
2
Box myBox;		//创建一个对象
myBox.GetVolume(); //调用该对象的成员函数

让我们使用上面提到的概念来设置和获取类中不同的成员的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include <iostream>

using namespace std;

class Box{
public:
double length; //长度
double breadth; //宽度
double height; //高度


//成员函数申明
double getVolume(void);
void setLength( double len );
void setBreadth( double bre );
void setHeight( double hei );
};

//成员函数定义

double Box::getVolume(void){
return length * breadth * height;
};

void Box::setLength( double len ){
length = len;
}

void Box::setBreadth( double bre ){
breadth = bre;
};

void Box::setHeight( double hei ){
height = hei;
}

//程序的主函数

int main(){
Box Box1; //声明 Box1, 类型为 Box
Box Box2; //声明 Box2, 类型为 Box
double volume = 0.0; //用来存储体积

// box 1 详述
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);

// box 2 详述
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);

// box 1 的体积
volume = Box1.getVolume();
cout << "Box1 的体积: " << volume <<endl;

// box 2 的体积
volume = Box2.getVolume();
cout << "Box2 的体积: " << volume <<endl;
return 0;
};

当上面的代码被编译和执行时,它会产生下列结果:

1
2
Box1 的体积: 210
Box2 的体积: 1560

C++ 变量作用域

作用域是程序的一个区域,一般来说有三个地方可以声明变量:

  • 在函数或一个代码块内部声明的变量,称为局部变量。
  • 在函数参数得定义中声明的变量,称为形式参数。
  • 在所有函数外部声明的变量,称为全局变量。

我们将在后续的章节中学习什么是函数和参数。本章我们先来讲解声明是局部变量和全局变量。

局部变量

在函数或一个代码块内部声明的变量,称为局部变量。它们只能被函数内部或者代码块内部的语句使用。下面的实例使用了局部变量:

1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;

int main(){
int a = 10, b = 20, c;
c = a + b;
cout << c << endl;
return 0;
};

全局变量

在所有函数外部定义的变量(通常是在程序的头部),称为全局变量。全局变量的值在程序的整个生命周期内都是有效的。

全局变量可以被任何函数访问。也就是说,全局变量一旦声明,在整个程序中都是可用的。下面的实例使用了全局变量和局部变量:

1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
using namespace std;

int g;

int main(){
int a = 10, b = 20;
g = a + b;

cout << g << endl;
return 0;
};

在程序中,局部变量和全局变量的名称可以相同,但是在函数内,局部变量的值会覆盖全局变量的值,下面是一个实例:

1
2
3
4
5
6
7
8
9
10
#include <iostream>
using namespace std;

int g = 20;

int main(){
int g = 10;

cout << g << endl;
};

当上面的代码被编译和执行时,它会产生下列结果:

1
10

初始化局部变量和全局变量

当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。定义全局变量时,系统会自动初始化为下列值:

数据类型 初始化默认值
int 0
char ‘\0’
float 0
double 0
pointer NULL

正确地初始化变量是一个良好的编程习惯,否则有时候程序可能会产生意想不到的结果。

C++ 指针

学习C++ 的指针既简单又有趣。通过指针,可以简化一些C++ 编程任务的执行,还有一些任务,如动态内存分配,没有指针时无法执行的。所以,想要成为一名优秀的C++ 程序员,学习指针时很有必要的。

正如您所知道的,每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&) 运算符访问的地址,它表示了在内存中的一个地址。请看下面的实例,它将输出定义的变量地址:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>

using namespace std;

int main(){
int var1;
char var2[10];

cout << "var1 变量的地址: " << &var1 << endl;
cout << "var2 变量的地址: " << &var2 << endl;

return 0;
};

当上面的代码被编译和执行时,它会产生下列结果:

1
2
var1 变量的地址: 0x7ffeefbff540
var2 变量的地址: 0x7ffeefbff56e

通过上面的实例,我们了解了什么是内存地址以及如何访问它。接下来让我们看看什么是指针。

什么是指针?

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:

1
type *var-name;

在这里,type是指针的基类型,它必须是一个有效的C++ 数据类型,var-name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:

1
2
3
4
int *ip;
double *dp;
float *fp;
char *ch

所有指针的值得实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或者常量的数据类型不同。

C++ 中使用指针

使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。下面的实例涉及到了这些操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>

using namespace std;

int main(){
int var = 20;
int *ip;

ip = &var;

cout << "Value of var variable: " << var << endl;

//输出在指针变量中存储的地址
cout << "Address stored in ip variable: " << ip << endl;

//访问指针中地址的值
cout << "Value of *ip variable: " << *ip << endl;

return 0;
};

当上面的代码被编译和执行时,它会产生下列结果:

1
2
3
Value of var variable: 20
Address stored in ip variable: 0x7ffeefbff548
Value of *ip variable: 20

C++ 指针详解

在C++ 中,有很多指针相关的概念,这些概念都很简单,但是都很重要。下面列出了 C++ 程序员必须清楚的一些与指针相关的重要概念:

概念 描述
C++ Null 指针 C++ 支持空指针。NUll 指针时一个定义在标准库中的值为零的常量。
C++ 指针的算术运算 可以对指针进行四中算数运算 ++、–、+、-
C++ 指针 VS 数组 指针和数组之间有着密切的关系
C++ 指针数组 可以定义用来存储指针的数组
C++ 指向指针的指针 C++ 允许指向指针的指针
C++ 传递指针给函数 通过引用或地址传递参数,使传递的参数在调用函数中被改动
C++ 从函数返回指针 C++ 允许韩式返回指针到局部变量、静态变量和动态内存分配