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 | int a[3][4] = { |
内部嵌套的括号是可选的,下面的初始化与上面是等同的:
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 |
|
当上面的代码被编译和执行时,它会产生下列结果:
1 | a[0] [0]: 0 |
如上所述,您可以创建任意维度的数组,但是一般情况下,我们创建的数组是一维数组和二维数组。
C++ 类成员函数
类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。类成员函数是类的一个成员,它可以操作类的任意对象,可以访问对象中的所有成员。
让我们看看之前定义的类 Box,现在我们要使用成员函数来访问类的成员,而不是直接访问这些类的成员:
1 | class Box |
成员函数可以定义在类定义内部,或者单独使用范围解析运算符 :: 来定义。在类定义中定义的成员函数把函数声明为内联的,即便没有使用 inline 标识符。所以您可以按照如下方式定义 Volume() 函数:
1 | class Box |
您也可以在类的外部使用范围解析运算符 :: 定义该函数,如下所示:
1 | double Box::getVolume(void) |
在这里,需要强调一点,在 :: 运算符之前必须使用类名。调用成员函数是在对象上使用点运算符(.),这样它就能操作与该对象相关的数据,如下所示:
1 | Box myBox; //创建一个对象 |
让我们使用上面提到的概念来设置和获取类中不同的成员的值:
1 | #include <iostream> |
当上面的代码被编译和执行时,它会产生下列结果:
1 | Box1 的体积: 210 |
C++ 变量作用域
作用域是程序的一个区域,一般来说有三个地方可以声明变量:
- 在函数或一个代码块内部声明的变量,称为局部变量。
- 在函数参数得定义中声明的变量,称为形式参数。
- 在所有函数外部声明的变量,称为全局变量。
我们将在后续的章节中学习什么是函数和参数。本章我们先来讲解声明是局部变量和全局变量。
局部变量
在函数或一个代码块内部声明的变量,称为局部变量。它们只能被函数内部或者代码块内部的语句使用。下面的实例使用了局部变量:
1 | #include <iostream> |
全局变量
在所有函数外部定义的变量(通常是在程序的头部),称为全局变量。全局变量的值在程序的整个生命周期内都是有效的。
全局变量可以被任何函数访问。也就是说,全局变量一旦声明,在整个程序中都是可用的。下面的实例使用了全局变量和局部变量:
1 | #include <iostream> |
在程序中,局部变量和全局变量的名称可以相同,但是在函数内,局部变量的值会覆盖全局变量的值,下面是一个实例:
1 | #include <iostream> |
当上面的代码被编译和执行时,它会产生下列结果:
1 | 10 |
初始化局部变量和全局变量
当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。定义全局变量时,系统会自动初始化为下列值:
| 数据类型 | 初始化默认值 |
|---|---|
| int | 0 |
| char | ‘\0’ |
| float | 0 |
| double | 0 |
| pointer | NULL |
正确地初始化变量是一个良好的编程习惯,否则有时候程序可能会产生意想不到的结果。
C++ 指针
学习C++ 的指针既简单又有趣。通过指针,可以简化一些C++ 编程任务的执行,还有一些任务,如动态内存分配,没有指针时无法执行的。所以,想要成为一名优秀的C++ 程序员,学习指针时很有必要的。
正如您所知道的,每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&) 运算符访问的地址,它表示了在内存中的一个地址。请看下面的实例,它将输出定义的变量地址:
1 | #include <iostream> |
当上面的代码被编译和执行时,它会产生下列结果:
1 | var1 变量的地址: 0x7ffeefbff540 |
通过上面的实例,我们了解了什么是内存地址以及如何访问它。接下来让我们看看什么是指针。
什么是指针?
指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:
1 | type *var-name; |
在这里,type是指针的基类型,它必须是一个有效的C++ 数据类型,var-name 是指针变量的名称。用来声明指针的星号 * 与乘法中使用的星号是相同的。但是,在这个语句中,星号是用来指定一个变量是指针。以下是有效的指针声明:
1 | int *ip; |
所有指针的值得实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,都是一样的,都是一个代表内存地址的长的十六进制数。不同数据类型的指针之间唯一的不同是,指针所指向的变量或者常量的数据类型不同。
C++ 中使用指针
使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。下面的实例涉及到了这些操作:
1 | #include <iostream> |
当上面的代码被编译和执行时,它会产生下列结果:
1 | Value of var variable: 20 |
C++ 指针详解
在C++ 中,有很多指针相关的概念,这些概念都很简单,但是都很重要。下面列出了 C++ 程序员必须清楚的一些与指针相关的重要概念:
| 概念 | 描述 |
|---|---|
| C++ Null 指针 | C++ 支持空指针。NUll 指针时一个定义在标准库中的值为零的常量。 |
| C++ 指针的算术运算 | 可以对指针进行四中算数运算 ++、–、+、- |
| C++ 指针 VS 数组 | 指针和数组之间有着密切的关系 |
| C++ 指针数组 | 可以定义用来存储指针的数组 |
| C++ 指向指针的指针 | C++ 允许指向指针的指针 |
| C++ 传递指针给函数 | 通过引用或地址传递参数,使传递的参数在调用函数中被改动 |
| C++ 从函数返回指针 | C++ 允许韩式返回指针到局部变量、静态变量和动态内存分配 |