20.【C/C++ 指针数组和数组指针 (超详版)】

20.【C/C++ 指针数组和数组指针 (超详版)】(一)、指针数组1. 什么是指针数组:2.指针数组的格式:3.指针数组的作用:4.补充:::::::::::::::::::5.指针数组与二维数组的关系6.6.7.小结7.1指针数组名加1,移动多少字节?7.(二)、数组指针:1.什么是数组指针2.数组指针的格式:3.数组指针的作…

指针数组和数组指针(指针重点)

  • (一)、指针数组
    • 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是二维数组ai行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

(0)
上一篇 2023-11-12
下一篇 2023-11-12

相关推荐

  • 阿里巴巴mysql面试_阿里面试

    阿里巴巴mysql面试_阿里面试迎面走来了一个风尘仆仆的身穿格子衫的男子,手里拿着一个MacBook Pro,看着那稀少的发量,和那从容淡定的眼神。 我心里一颤,我去,这是架构师,架构师来面我技术面,我心里顿时不淡定了,表面很稳实则心里慌得一批。 果然,他手里拿着我的简历,快速的扫了一下,然后用眼角余光看了一…

    2023-04-02
    94
  • Python代码笔记——excel格式题库转word格式题库

    Python代码笔记——excel格式题库转word格式题库本篇代码片段是由Python加pandas库,python-docx完成,因为近日,对象的单位需要考试,所以发给他们每个人excel格式的题库,

    2022-12-14
    103
  • java中的executeQuery()方法使用「终于解决」

    java中的executeQuery()方法使用「终于解决」这篇文章主要介绍了java中的executeQuery()方法使用,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

    2023-06-30
    101
  • Python笔记-最小公倍数代码实例(3.9版本)

    Python笔记-最小公倍数代码实例(3.9版本)从Python3.9版本,Math模块新增加了计算最小公倍数的函数lcm函数。在3.9版本中,通过lcm函数可以非常简单地快速得到2个整数的最小

    2022-12-14
    107
  • MySQL事务隔离级别和MVCC

    MySQL事务隔离级别和MVCCMySQL是一个服务器/客户端架构的软件,对于同一个服务器来说,可以有若干个客户端与之连接,每个客户端与服务器连接上之后,就可以称之为一个会话(Session)。我们可以同时在不同的会话里输入各种语句,这些语句可以作为事务的一部分进行处理。不同的会话可以同时发送请求,也就是说服…

    2023-04-03
    121
  • HTML+CSS+JS实现 贪吃蛇游戏源码

    HTML+CSS+JS实现 贪吃蛇游戏源码meta name=”viewport” content=”width=device-width, initial-scale=1.var canvas = document.var ctx = canvas.self.self.self.self.ctx.ctx.fillRe…

    2023-11-14
    84
  • 全栈之路:工具篇 sublime python django

    全栈之路:工具篇 sublime python django全栈之路:工具篇 sublime Text3 for python django
    代码笔记 为一系列的文章,从一个python ,django

    2022-12-14
    100
  • MySQL系列– 1.MySQL架构「建议收藏」

    MySQL系列– 1.MySQL架构「建议收藏」1. 逻辑架构 服务器基于用户名、原始主机信息和密码对客户端进行认证,连接成功后会验证某个特定操作的权限。 用户可以通过特殊的关键字提示(hint)优化器,影响MySQL的决策过程。也可以请求优化器解释(explain)优化过程的各个因素,便于用户重构查询和schema,修改相…

    2023-04-02
    104

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注