首页 > 编程笔记 > C++笔记 阅读:13

C++数组和指针用法详解(附带实例)

C++ 中,数组作为同名、同类型元素的有序集合,被顺序存放在一块连续的内存中,且每个元素的存储空间大小相同。数组中第一个元素的存储地址就是整个数组的首地址,该地址存放在数组名中。

一维数组的结构是线性的,数组元素按下标值由小到大的顺序依次存放在一块连续的内存中。二维数组以矩阵方式,先行后列依次存放各元素,在内存中仍然是线性结构。

C++指针与一维数组

指针是存放地址的变量,如果把数组的首地址赋给指针,就可以通过指针引用数组元素。

例如:
int a[8]; //定义一个整型数组a,包含8个元素
int *p;   //定义一个整型指针p
p=&a[0];  //将数组的首地址赋给p
此时,p 指向数组的首地址,也就是 a[0] 元素,p+1 指向 a[1] 元素,p+2 指向 a[2] 元素,以此类推,p+7 指向 a[7] 元素,如下图所示。


图 1 将指针指向一维数组

通过首地址和偏移量,可以定位任意一个数组元素。

【实例 1】指针与一维数组。通过指针变量输出数组中的各元素。具体代码如下:
#include <iostream>
using namespace std;
int main()
{
    int i,a[10];
    int *p;
    for(i=0;i<10;i++) //for 循环,为数组元素赋值
        a[i]=i;
    p=&a[0]; //将 a[0]元素的地址赋给p,也就是将数组的首地址赋给p
    for(i=0;i<10;i++,p++) //for 循环,通过指针输出数组元素
        cout << *p << endl;
}
程序运行结果为:

0
1
2
3
4
5
6
7
8
9

数组名 a、数组第一个元素的地址 &a[0]都表示数组的首地址。将指针 p 指向数组 a,则 p+1 将指向数组元素 a[1]。p+i 和 a+i 都表示元素 a[i] 的地址,*(p+i) 和 *(a+i) 都表示数组元素 a[i]。

因此,可以将实例 1 中的第 9 行代码修改如下:
p = a;  // 将数组的首地址赋给 p

还可以将第 10~11 行代码修改如下,程序运行效果一样:
for(i=0;i<10;i++)    //for 循环,通过*(a+i)输出数组元素
    cout << *(a+i) << endl;

通过指针和自增、自减运算操作数组的说明如下:

C++指针与二维数组

二维数组中各元素在内存中的存储情况如下图所示:


图 2 二维数组元素的存储情况

可见,二维数组在内存中仍然是线性结构。

将二维数组的首地址赋给指针变量,同样可以通过指针引用数组元素,进行各类操作。例如:
int a[4][3]; //声明一个二维数组a
int *p;      //声明一个指针p
p=a[0];      //将数组的首地址赋给指针p
二维数组中,a、a[0]、&a[0][0] 都可以表示数组的首地址,只要将该地址赋给指针变量,就可以使用指针操作二维数组中的元素。

【实例 2】使用指针遍历二维数组。本实例中,将二维数组的首地址赋给指针,然后使用指针自增输出数组元素。代码如下:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
    int a[4][3]={1,2,3,4,5,6,7,8,9,10,11,12}; //定义二维数组a并初始化
    int *p; //定义指针p
    p=a[0]; //将数组的首地址赋给指针
    for(int i=0;i<sizeof(a)/sizeof(int);i++) //for 循环,循环次数为数组元素,感受二维数组的线性存储结构
    {
        cout <<"address:";
        cout << p; //输出当前数组元素的地址
        cout << " is ";
        cout << *p++ << endl; //使用指针输出数组元素的值
    }
}
程序运行结果为:

address:0x6ffde0 is 1
address:0x6ffde4 is 2
address:0x6ffde8 is 3
address:0x6ffdec is 4
address:0x6ffdf0 is 5
address:0x6ffdf4 is 6
address:0x6ffdf8 is 7
address:0x6ffdfc is 8
address:0x6ffe00 is 9
address:0x6ffe04 is 10
address:0x6ffe08 is 11
address:0x6ffe0c is 12

同样,使用数组名和偏移量可以获得二维数组中的元素地址和元素值:
函数名 a 本质上也是一个指向数组的指针,因此通过偏移可以表示任意一行(如 a+m)或任意一个元素(如 (a+m)+n)的地址。

【实例 3】使用数组名和偏移输出二维数组。利用数组名和偏移对二维数组进行输出,具体代码如下:
#include <iostream>
using namespace std;
int main()
{
    int i,j;
    int a[4][3]={{1,2,3},{4,5,6},{7,8,9},{10,11,12}}; //定义二维数组a并初始化
    cout << "the array is: " << endl; //双重 for 循环,遍历该数组
    for(i=0;i<4;i++)
    {
        for(j=0;j<3;j++)
            cout << *(*(a+i)+j) << endl; //使用*(*(a+i)+j)方式输出数组元素
    }
}
程序运行结果为:

the array is:
1
2
3
4
5
6
7
8
9
10
11
12

C++指针与字符数组

使用指针可以引用字符数组。这样的指针称为字符指针,它指向的是字符型内存空间。其定义形式如下:
char *p;

字符数组就是一个字符串,通过字符指针可以指向一个字符串。例如:
char *string;
string="c.biancheng.net";

【实例 4】连接两个字符串。本实例中不使用处理字符串函数 strcat(),通过指针偏移连接两个字符串,具体代码如下:
#include <iostream>
using namespace std;
int main()
{
    char str1[50],str2[30],*p1,*p2; //让两个指针分别指向两个数组
    p1=str1;
    p2=str2;
    cout << "please input string1:" << endl; //给 str1 赋值
    gets(str1);
    cout << "please input string2:" << endl; //给 str2 赋值
    gets(str2);
    while(*p1!='\0') //把 p1 移动到 str1 的末尾
        p1++;
    while(*p2!='\0') //取 p2 指向的值赋给 p1 指向的地址(str1 的末尾),即连接 str1 和 str2
        *p1++=*p2++;
    *p1='\0';
    cout << "the new string is:" << endl; //输出新的 str1
    puts(str1);
}
程序运行结果为:

please input string1:
c.biancheng
please input string2:
.net
the new string is:
c.biancheng.net

相关文章