大家好,我是考100分的小小码 ,祝大家学习进步,加薪顺利呀。今天说一说20.【C/C++ 指针数组和数组指针 (超详版)】,希望您对编程的造诣更进一步.
指针数组和数组指针(指针重点)
- (一)、指针数组
-
- 1. 什么是指针数组:
- 2.指针数组的格式:
- 3.指针数组的作用:
- 4.指针数组与一维数组的关系:
- 补充:::::::::::::::::::
-
- 5.指针数组与二维数组的关系
- 6.指针数组申请动态二维数组
-
-
- 指针数组申请动态二维数组格式:
-
- 6.实战项目:
-
-
- 代码展示:
- 效果展示:
-
- 7.小结
-
-
- 7.1指针数组名加1,移动多少字节?
- 7.2指针数组名相当于什么样的指针?
-
- (二)、数组指针:
-
- 1.什么是数组指针
- 2.数组指针的格式:
- 3.数组指针的作用:
- 4.数组指针与二维数组的关系:
- 补充:::::::::::::::::::
- 多数组有关概念
- 4.实战项目:
-
-
- 代码展示:
- 效果展示:
-
- (三)、数组指针和指针数组
(一)、指针数组
1. 什么是指针数组:
在C语言和C++等语言中,数组元素全为指针变量的数组称为指针数组,指针数组中的元素都必须具有相同的存储类型、指向相同数据类型的指针变量。指针数组是数组元素为指针的数组(例如 int *p[3] ,定义了p[0],p[1],p[2]三个指针),其本质为数组。
2.指针数组的格式:
数据类型 *首地址[];
3.指针数组的作用:
指针数组比较适合用来指向若干个字符串,使字符串处理更加方便、灵活。
4.指针数组与一维数组的关系:
指针数组每个元素都是指针,一维数组的地址可以赋值给指针。然后进行操作.
#include<iostream>
using namespace std;
int main() {
int* p[3]; //定义一个指针数组
int a[] = { 3,6,1,9,10 }; //定义一个整型数组
p[0] = a; //p[0]是一个类型为int* 指向int的指针,a是一个int*,指向int
p[1] = a + 1;
p[2] = a + 3;
cout << (*p[0]) << " " << (*p[1]) << " " << (*p[2]) << endl; //[]优先级比()高,所以()没起到作用
cout << a[0] << " " << a[1] << " " << a[3] << endl;
int* q; //普通指针
q = a + 1;
cout << *q;
}
补充:::::::::::::::::::
如果是 二维数组a[0]+1;代表a[0][1]; 这时候a[0]是行数组名它代表这一行的首地址就是a[0][0],+1就等于加它类型的字节数1x字节数,(+2就是2x字数)结果就是a[0][1];如果是一维的话,更简单;+1就等于加它类型的字节数x1;结果是a[1];
5.指针数组与二维数组的关系
#include<iostream>
using namespace std;
int main() {
int* p[3]; //定义一个指针数组
int a[2][3] = {{3,6,1} ,{12,9,10}}; //定义一个二维整型数组
p[0] = a[0]; //a[0]=&a[0][0]
p[1] = a[1]; // a[1]=&a[1][0]
cout << a[0][1] << endl; //输出a[0][1]
cout << *(a[0] + 1) << endl; //输出a[0][1],(a[0]+1)这样代表地址
cout << *(p[0] + 1) << endl; //输出a[0][1],指针+1代表移动一个数(列)
cout << *(p[0] + 2) << endl; //输出a[0][2],指针+1代表移动一个数(列)
return 0;
}
接下来让我们练习一道题:(二维数组全部元素求和)
#include<iostream>
using namespace std;
int main() {
int sum=0;
int* p[3]; //定义一个指针数组
int a[2][3] = {{3,6,1} ,{12,9,10}}; //定义一个二维整型数组
p[0] = a[0]; //a[0]=&a[0][0]
p[1] = a[1]; // a[1]=&a[1][0]
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
sum += *(p[i] + j);//或者 *(*(p+i)+j) 或者 p[i][j]
}
}
cout << "求和后得:" << sum << endl;
return 0;
}
6.指针数组申请动态二维数组
指针数组申请动态二维数组格式:
【方法1基本格式】
int **p; //指针类型是int** 型,指向int*型的指针变量
p=new int*[列]
for(int i=0;i<列;i++)
{
p[i]=new int [列]
}
6.实战项目:
代码展示:
1.错误示范:
【指针指向二维数组不能用*p=a[0]】
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
int a[2][2] = {1,2,3,4};
int* p;
*p = a[0];
for (int i = 0; i < 4; i++)
{
cout << setw(2) << *(p+i) ;
}
return 0;
}
2.指针数组申请动态二维数组
#include <iostream>
using namespace std;
int main() {
int m, n;
cout << "请输入行数为:" << endl;
cin >> m;
cout << "请输入列数:" << endl;
cin >> n;
int**p; //
p = new int*[n];
for (int i = 0; i < n; i++)
{
p[i] = new int[n]; //左边行,右边列
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> p[i][j];
}
}
cout << "输出为:" << endl;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cout<< p[i][j]<<" ";
}
}
delete[]p;
return 0;
}
效果展示:
1.错误示范效果展示:
2.申请动态二维数组正确效果
7.小结
7.1指针数组名加1,移动多少字节?
* (p+1):走了一行; * (p+1)+1走了一列
7.2指针数组名相当于什么样的指针?
指针数组名就是元素地址相当于一级指针取地址就是二级指针,故指针数组名相当于二级指针“数据类型 * p” 本身就是一个指针,而它的数据类型是int * 也是一个指针,故称为二级指针。
(二)、数组指针:
1.什么是数组指针
数组指针,指的是数组名的指针,即数组首元素地址的指针。即是指向数组的指针。例:int (*p)[10] ; p即为指向数组的指针,又称数组指针。
2.数组指针的格式:
数据类型(*p)[];
3.数组指针的作用:
数组指针是指向数组地址的指针,其本质为指针;
4.数组指针与二维数组的关系:
#include<iostream>
using namespace std;
int main() {
int(* p)[3]; //定义一个数组指针
int a[2][3] = {{3,6,1} ,{12,9,10}}; //定义一个二维整型数组
return 0;
}
这里a是个二维数组的数组名,相当于一个二级指针常量;//二维数组名与二级指针毫无关系(初学者常常混淆)。
p是一个指针变量,它指向包含5个int元素的一维数组,此时p的增量以它所指向的一维数组长度为单位;
补充:::::::::::::::::::
p+i是一维数组a[i]的地址,即p+i==&a[i] ;对该式两边作取内容运算( )得(p+i)a[i],由于二维数组中a[i]&a[i][0], 则 * (p+i)表示a[i][0]的地址,即 * (p+i)==&a[i][0] (p+2)+3表示a[2][3]地址(第一行为0行,第一列为0列), (*(p+2)+3)表示a[2][3]的值。
多数组有关概念
注意a[0],a[1],a[2]表示的都是对应那行的数组首地址,和数组名,而不是一个元素,(这里得到*号不是指针,而是取地址)!!!!!!!!!!!
多维数组地址的表示方法
设有整型二维数组a[3][4]如下:
1000 1001 1002 1003
1004 1005 1006 1007
1008 1009 1010 1011
设数组a的首地址为1000,各下标变量的首地址及其值。C语言允许把一个二维数组分解为多个一维数组来处理。因此数组a可分解为三个一维数组,即a[0],a[1],a[2]。 每一个一维数组又含有四个元素。例如a[0]数组,含有a[0][0],a[0][1],a[0][2],a[0][3]四个元素。数组及数组元素的地址表示如下: a是二维数组名,也是二维数组0行的首地址,等于1000。a[0]是第一个一维数组的数组名和首地址,因此也为1000。 (a+0)或a是与a[0]等效的,它表示一维数组a[0]0号元素的首地址。也为1000。&a[0][0]是二维数组a的0行0列元素首地址,同样是1000。因此,a,a[0] ,*(a+0), * a,&a[0][0]是相等的。同理,a+1是二维数组1行的首地址,等于1004。a[1]是第二个一维数组的数组名和首地址,因此也为1004。&a[1][0]是二维数组a的1行0列元素地址,也是1004。因此a+1,a[1],* (a+1),&a[1][0]是等同的。由此可得出:a+i,a[i], * (a+i),&a[i][0]是等同的。此外,&a[i]和a[i]也是等同的。因为在二维数组中不能把&a[i]理解为元素a[i]的地址,不存在元素a[i]。
C语言规定,它是一种地址计算方法,表示数组a第i行首地址。由此,我们得出:a[i],&a[i], * (a+i)和a+i也都是等同的。另外,a[0]也可以看成是a[0]+0是一维数组a[0]的0号元素的首地址,而a[0]+1则是a[0]的1号元素首地址,由此可得出a[i]+j则是一维数组a[i]的j号元素首地址,它等于&a[i][j]。
由a[i]= * (a+i)得a[i]+j= * ( a+i)+j,由于 * (a+i)+j是二维数组a的i行j列元素的首地址,该元素的值等于 * ( * (a+i)+j)。
4.实战项目:
代码展示:
1.数组指针和二维数组的联用
#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 = (int(*)[4])a; //目的是为了把a看作参数
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++) printf("%d ", p[i][j]); //或者 *(*(p+i)+j) 或者 *(p[i]+j)
printf("\n");
}
}
2.数组指针创建动态二维数组
#include <iostream>
using namespace std;
int main() {
int m, n;
cout << "请输入行数为:" << endl;
cin >> m;
int(*p)[3];
p = new int[m][3]; //列数是实参,否则报错哦
for (int i = 0; i < m; i++)
{
for (int j = 0; j < 3; j++)
{
cout << "请输入p[" << i << "][" << j << "]的值" << endl;
cin >> p[i][j];
}
}
cout << "输出为:" << endl;
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 3; j++)
{
cout<< p[i][j]<<" ";
}
}
return 0;
}
效果展示:
1.数组指针和二维数组联用
2.数组指针和动态二维数组
(三)、数组指针和指针数组
祝君更上一层楼!!!!!!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/36796.html