指针与数组

组别:普及组
难度:4

一、数组的指针

C++中数组名,在一定意义上可以看成是指针,可以像操作指针一样操作数组名。
数组名都表示数组第一个元素的地址,可将其看作是一个指针常量。而这个指针常量所指向的类型与数组元素的类型一致。也正是因为如此数组名在表达式中不能作为左值,当其作为右值时其意义与&arr[0]是一致的。

指向数组的指针变量称为数组指针变量。一个数组是一块连续的内存单元组成的,数组名就是这块连续内存单元的首地址。一个数组元素的首地址就是指它所占有的几个内存单元 的首地址。一个指针变量即可以指向一个数组,也可以指向一个数组元素,可把数组名或第 一个元素的地址赋予它。如要使指针变量指向第 i 号元素,可以把 i 元素的首地址赋予它, 或把数组名加 i 赋予它。

设有数组 a,指向 a 的指针变量为 pa,则有以下关系:pa、a、&a[0]均指向同一单元, 是数组 a 的首地址,也是 0 号元素 a[0]的首地址。pa+1、a+1、&a[1]均指向 1 号元素 a[1]。 类推可知 pa+i、a+i、&a[i]指向 i 号元素 a[i]。pa 是变量,而 a,&a[i]是常量,在编程时 应予以注意。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
#include <iostream>
using namespace std;
int main()
{
int a[5],*pa=a;
    for(int i=0;i<5;i++){
    cin>>a[i];
    }

    for(int i=0;i<5;i++){
        cout<<*(pa+i)<<' ';
    }
       return 0;
}

说明:
1、直接拿 a 当指针用,a 指向数组的开始元素,a+i 是指向数组的第 i 个元素的指针。
2、指针变量 pa 是变量,可以变的。但数组 a 是静态的变量名,不可变,只能当做常量指针使用。例如:p=p+2;是合法的,a=a+2;是非法的。

数组和指针的偏移操作

 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
#include <iostream>
using namespace std;
int main(){
    int array[3]={3,7,9};  //定义一个有三个整数元素的数组
    int *pointer;          //定义一个指针变量
    pointer=array;         //把数组首元素地址赋值给指针变量
    cout<<"the address of array is "<<array<<endl;
    /* 数组名直接输出第一元素地址  */
    cout<<"the address of first element in array is "<<&array[0]<<endl;
    /* 取数组第一个元素地址,地址同上  */  
    cout<<"the value contained in array[0] is "<<*array<<endl;
    /* 取数组第一个元素的值  */
    cout<<"the address of array+1 is "<<array+1<<endl;
    /* 地址值加+1,这里的1是代表数组一个元素的大小,而不是一个byte数  */
    cout<<"the value contained in array[1] is "<<*(array+1)<<endl;
    /* 地址偏移1个单位后,取值。 */
    cout<<"the value of array[0] +1 is "<<*array+1<<endl;
    /* 地址取值后加1  */
    cout<<"the value contained in pointer is "<<pointer<<endl;
    /*  指针变量的值,是数组的起始地址  */
    cout<<"the value contained in  ++pointer is "<<*(++pointer)<<endl;
    /*  指针变量的值自加1后,取对应地址内保存的值  */
    cout<<"the address of array is "<<&array<<endl;
    /* 取数组地址  */ 
    cout<<"the address of &array+1 is"<<&array+1<<endl;
    /*  数组地址1偏移量为整个数组的大小  */
}

edit & run

a是可以直接当近指针用,a指向数组的开始元素。
p是指针变量,是可以变的;但数组名a是静态的指针变量名,不可以变。

二、数组指针(行指针)

举例:int (*p1)[5];

语句“int(*p1)[5]”,“()”的优先级比“[]”高,“*”号和 p1 构成一个指针的定义,指针变量名为 p1,而 int 修饰的是数组的内容,即数组的每个元素。也就是说,p1 是一个指针,它指向一个包含 5 个 int 类型数据的数组,很显然,它是一个数组指针,数组在这里并没有名字,是个匿名数组。

如要将二维数组赋给一指针,应这样赋值:
int a[3][4];
int (*p)[4]; //该语句是定义一个数组指针,指向含4个元素的一维数组。
 p=a;        //将该二维数组的首地址赋给p,也就是a[0]或&a[0][0]
 p++;       //该语句执行过后,也就是p=p+1;p跨过行a[0][]指向了行a[1][]

所以数组指针也称指向一维数组的指针,亦称行指针。

 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
#include <iostream>
using namespace std;

int main() {

    int a[3][4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} };
    int (*p)[4]; 

    /* 移动p指针 */

    p = a; // p指向了二维数组a的第1行
        cout << "p指向第1行地址:" << p << endl;

    p++;  // 现在p指向了第2行
        cout << "p指向第2行地址:" << p << endl;

    p = p + 1; // 现在p指向了第3行
        cout << "p指向第3行地址:" << p << endl;

    p -= 2; // p又移回了a的第1行
        cout << "p移回第1行地址:" << p << endl;

    /* 取值 */
    int b;
    b =**p; // b现在等于a的第1行第1列元素
        cout << "第1行第1列元素:" <<  b << endl;

    b = *(*(p+1)+2); // b现在等于第2行第3列元素
        cout << "第2行第3列元素:" << b << endl;

    b = *(*(p+2)+1); // b现在等于第3行第2列元素
        cout << "第3行第2列元素:" << b << endl;

    return 0;
}

三、动态数组

很多情况下,在预编译过程阶段,数组的长度是不能预先知道的,必须在程序运行时动态的给出,但是问题是,c++要求定义数组时,必须明确给定数组的大小,要不然编译通不过。那么,我们该如何解决定义长度未知的数组呢?   答案是:new 动态定义数组 。   因为new 就是用来动态开辟空间的,所以当然可以用来开辟一个数组空间。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
int main(){
     int n,sum=0;
     int *p;
   
    cout<<"please input the number of array "; 
    cin>>n;
    p=new int[n];
    for(int i=0;i<n;i++){
        cin>>p[i];
        //cin>>*(p+i);
    }
    
    for(int i=0;i<n;i++){
        sum+=p[i];
        //sum+=*(p+i);
    }
    cout<<sum;
   // delete[] p;
   //p=NULL;
    return 0;
}

edit & run

四、指针数组

指针数组 :就是指针的数组,数组的元素是指针;
举例说明:
int *p1[5];    声明了一个数组,数组的元素是int型的指针。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
#include <iostream>
using namespace std;
const int MAX = 3;
int main ()
{
    int  var[MAX] = {10, 100, 200};
    int *ptr[MAX];       //定义指针数组
    for (int i = 0; i < MAX; i++)
    {
        ptr[i] = &var[i]; 
    }
    for (int i = 0; i < MAX; i++)
    {
        cout << "Value of var[" << i << "] = ";
        cout << *ptr[i] << endl;
    }
    return 0;
}

edit & run

五、指针数组与二维数组

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

int main (){
    int a[2][3]={{1,2,3},{3,4,5}};
    int *p[2];
   
    cout<<a<<'\n';
    cout<<a[0]<<'\n';
    cout<<a[1]<<'\n';
    cout<<*(a[1]+2)<<'\n'; 
    for (int i = 0; i < 2; i++){
        p[i]=a[i];
    }
    cout<<*(p[0]+1);
    return 0;
}

edit & run

Scroll to Top