组别:普及组
难度: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偏移量为整个数组的大小 */ } |
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; } |
四、指针数组
指针数组 :就是指针的数组,数组的元素是指针;
举例说明:
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; } |
五、指针数组与二维数组
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; } |