当前位置:网站首页>用指针访问二维数组
用指针访问二维数组
2022-07-24 05:21:00 【Zonggu22】
文章目录
前言
如何理解二维数组?我们以二维的方式理解二维数组,他在存储时却是一维的。
用指针访问二位数组
例:int a[3] [4] = {1,3,5,7,9,11,13,15,17,19,21,23};
| a[0] [0] | a[0] [1] | a[0] [2] | a[0] [3] |
|---|---|---|---|
| a[1] [0] | a[1] [1] | a[1] [2] | a[1] [3] |
| a[2] [0] | a[2] [1] | a[2] [2] | a[2] [3] |
我们想象的二维数组的存储方式:3行4列
| a[0] [0] |
|---|
| a[0] [1] |
| a[0] [2] |
| a[0] [3] |
| a[1] [0] |
| a[1] [1] |
| a[1] [2] |
| a[1] [3] |
| a[2] [0] |
| a[2] [1] |
| a[2] [2] |
| a[2] [3] |
我们认为前四个是一个以a[0]为数组名的一位数组,共有四个int元素
中间四个是名为a[1]的一维数组
最后四个是名为a[2]的一维数组
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xvD4uspk-1649424643293)(C:\Users\17273\AppData\Roaming\Typora\typora-user-images\image-20220408195446474.png)]](/img/79/585f7c39b82ef57fb7ab54f14a65de.png)
通过指针访问二维数组的不同形式

*a和a 是两个完全不同的概念:
a看待这个数组认为这个数组是一维数组,它自身加一会转向下一个一维数组即a+1
*a指向的是每个元素都是整数的一维数组所以就认为 *a+0 指向的就是整数,加一就是下一个整数
为什么不能用*p=a
int x,*p;
double y,*q;
p=&x;
q=&y;
p=q;//是错的
//p是指向四个字节为存储单元的地址
//q是指向八个字节为存储单元的地址
//两者不可以等价
二维数组元素的访问的四种方式:
1、通过下标访问数组元素
int a[3][4]; for (int i=0; i<3; i++) for (int j=0; j<4; j++) a[i][j] = i+j;int a[3][4]; for (int i=0; i<3; i++) for (int j=0; j<4 ;j++) *(*(a+i)+j)=i+j;
2、通过数组首地址访问数组元素
对于二维数组元素a[i] [j], “【】”实际上是变址运算符,即将元素a[i] [j]的存储地址转换为a[i] + j。
3、通过指针访问数组元素(以一维数组的角度“看待”二维数组”)
int a[3][4];
int *p=&a[0][0];
for (int i=0; i<3; i++)
for(int j=0; j<4; j++)
*(p++) = i+j; //相当于*p=i+j;p++;
在这里,指针p被定义为:“指向int的指针”,也就是说:p指针“认为”它指向的是一个一维数组,每个元素都是int型的,共有12个元素。
4、通过指针访问数组(以二维数组的角度“看待”数组)
int a[3][4]={
1,3,5,7,9,11,13,15,17,19,21,23};
int (*p)[4];
/* 对p指针的理解: *p声明了p的指针。 p是指向什么的指针呢? 指向了一个包含了4个整数的一维数组 */
p=a;
for(int i=0; i<3;i++)
for (int j=0;j < 4;j++)
*(*(p+i)+j)=i+j;
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kABn2WMW-1649424643295)(C:\Users\17273\AppData\Roaming\Typora\typora-user-images\image-20220408203550957.png)]](/img/10/1f72d2e94c21093412e63b0976bab6.png)
指针这样定义之后,==指针p将以和数组a完全相同的“视角”去看待二维数组。==也就是说,a可以怎么使用,p也可以同样怎么使用
//例如:此处*(*(p+i)+j)替换为p[i][j],a[i][j],*(*(a+i)+j)都是等价的
指向字符串的二维数组
char *str[3]={
"Red","Green","Blue"};//方括号的优先级要高于"*"优先级
//意思是str是具有三个元素的数组,数组里面存储的是指向字符的指针
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WhhJAfk3-1649424643296)(C:\Users\17273\AppData\Roaming\Typora\typora-user-images\image-20220408204323760.png)]](/img/8e/65cd1620a88912c6bc88f93340cadc.png)
实例:学生成绩
score数组中存放了3个学生4们功课的成绩
通过调用average函数计算所有学生所有成绩的平均值
通过调用search函数显示第n个学生4门功课的成绩。
思路:
需要定义一个二维数组score,每行存储一个学生的4们功课的成绩。有3行,则存储了3个学生的成绩。
| 65 | 70 | 70 | 60 |
|---|---|---|---|
| 80 | 87 | 90 | 81 |
| 90 | 99 | 100 | 98 |
当编写函数average计算所有学生成绩平均值的时候,可以用一维数组的角度去看待这个score数组,也就是说,“认为”这个数组有12个成绩,直接求和,在计算平均分就行了
当编写函数search显示第n个学生的4门功课的时候,则使用二维数组的角度去看待这个score数组,也就是说,“认为”这个数组有3行,每行4个元素
void average(float *p,int n)
{
//以一维数组的方式看待学生成绩
float *p_end;
float sum=0,aver;
p_end=p+n;
for ( ; p<p_end;p++)
sum=sum+(*p);
aver=sum/n;
printf("平均成绩为:%5.1f\n",aver);
}
void search(float (*p)[4],int n)//可以写成 float p[][4]
{
//以二维数组的方式看待学生成绩,视角与score相同
int i;
printf("第%d个学生的成绩为: ",n);
for (i=0;i<4;i++)
printf("%5.1f",*(*(p+n)+i)); //可以替换成p[n][i]
}
int main()
{
float score[3][4]={
{
65,67,70,60},{
80,87,90,81},{
90,99,100,98}};
average(&score[0][0],12); //可以替换成score[0],*(score+0)
search(score,2);
return 0;
}
思考 (如果看不懂,请回退往前再看)
(1)同是给函数传递score二维数组,为什么average函数和search函数传参时采用了不同的方式?
average(&score[0][0],12); //可以替换成score[0],*(score+0) search(score,2); //显示第二个学生的成绩
二维数组作为函数的参数
1、以一维数组的角度“看待”二维数组
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P2KFzj6W-1649424643296)(C:\Users\17273\AppData\Roaming\Typora\typora-user-images\image-20220408210509696.png)]](/img/35/af319daac9edeed0794bc2a3a41410.png)
2、以二维数组的角度“看待”一维数组
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hblYxFbm-1649424643297)(C:\Users\17273\AppData\Roaming\Typora\typora-user-images\image-20220408210627250.png)]](/img/a7/b58ccd3b34d0e9a9c433b27ccf74b1.png)
课后练习
题目描述:写一个inverse函数,此函数的功能是:将一个 3*4 的二维数组中的值按逆序重新存放。
程序运行结果范例
请输入 3*4 的二维数组:
1 2 3 4
5 6 7 8
9 10 11 12
逆序存放后的结果为:
12 11 10 9
8 7 6 5
4 3 2 1
提示:
这个程序有多种实现思路,尝试使用两种方法实现
答案
方法一:用二维数组的方式看待程序:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AypqDO38-1649424659790)(C:\Users\17273\AppData\Roaming\Typora\typora-user-images\image-20220408211150882.png)]](/img/f8/154b0c173c51f9c6605b42bd1aa2c1.png)
void inverse(int a[][N],int b[][N])
{
int i,j;
for (i=0;i<M;i++)
for (j=0;j<N;j++)
b[M-i-1][N-j-1]=a[i][j]
}
int main()
{
int a[M][N],b[M][N];
int i,j;
printf("请输入 %d*%d 的二维数组:\n",M,N);
for (i=0;i<M;i++)
for (j=0;j<N;j++)
scanf("%d",&a[i][j]);
inverse(a,b);
printf("逆序存放后的结果为:\n");
for (i=0;i<M;i++)
{
for (j=0;j<N;j++)
printf("%d\t",b[i][j]);
}
}
方法二: 用一维数组的方式看待程序:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wbqZDO8I-1649424659791)(C:\Users\17273\AppData\Roaming\Typora\typora-user-images\image-20220408211921472.png)]](/img/89/2a8350bc6f322e19dc81980ba8c9d9.png)
void swap(int *p1,int *p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
//以 int *a 这样的方式传参,使得在子程序中以一维的方式看待数组,
//也就是说,把数组看成了一个具有 M*N 个元素的,每个元素都是 int 的数组
void inverse(int *a,int n)
{
int *p,*q;
for (p=a,q=a+n-1;p<=q;p++,q--)
{
swap(p,q);
}
}
int main()
{
int a[M][N];
int i,j;
printf("请输入 %d * %d 的二维数组: \n");
for (i=0;i<M;i++)
for (j=0;j<M;j++)
scanf("%d",&a[i][j]);
inverse(&a[0][0],M*N);
printf("逆序存放后的结果为: \n");
for (i=0;i<M;i++)
{
for (j=0;j<N;j++)
printf("%d\t",a[i][j]);
printf("\n");
}
return 0;
}
程序用到了M,N两个常量,这样的程序具有良好的灵活性。
边栏推荐
- Likeshop single merchant mall system is built, and the code is open source without encryption
- Introduction to PC mall module of e-commerce system
- 《机器学习》(周志华)第一章 绪论 笔记 学习心得
- 第三章 线性模型总结
- Canal+kafka actual combat (monitor MySQL binlog to realize data synchronization)
- Chapter III summary of linear model
- CRC-16 Modbus代码
- ‘Results do not correspond to current coco set‘
- Typora 安装包2021年11月最后一次免费版本的安装包下载V13.6.1
- systemctl + journalctl
猜你喜欢

多商户商城系统功能拆解04讲-平台端商家入驻

Multi merchant mall system function disassembly Lecture 11 - platform side commodity column

The female colleague of the company asked me to go to her residence to repair the computer at 11 o'clock at night. It turned out that disk C was popular. Look at my move to fix the female colleague's

Zotero Quick Start Guide

AD1256

likeshop单商户商城系统搭建,代码开源无加密

多商户商城系统功能拆解09讲-平台端商品品牌

Connect CRM system and effect advertising, help enterprises with precision marketing, and help enterprises with precision marketing

【深度学习】手写神经网络模型保存

PDF文本合并
随机推荐
Multi merchant mall system function disassembly lecture 06 - platform side merchant settlement agreement
西瓜书/南瓜书--第1,2章总结
vscode 多行注释总是会自动展开的问题
What do programmers often mean by API? What are the API types?
测试数据增强后标签和数据集是否对应
Positional argument after keyword argument
ThreadLocal stores the current login user information
谷歌/火狐浏览器管理后台新增账号时用户名密码自动填入的问题
Multi merchant mall system function disassembly lecture 09 - platform end commodity brands
找数组中出现次数最多的数
How to quickly connect CRM system and ERP system to realize the automatic flow of business processes
[activiti] activiti process engine configuration class
推荐一款完全开源,功能丰富,界面精美的商城系统
OpenWRT快速配置Samba
Machine learning (Zhou Zhihua) Chapter 3 Notes on learning linear models
Zotero快速上手指南
[activiti] personal task
likeshop单商户SAAS商城系统搭建,代码开源无加密。
如何解决训练集和测试集的分布差距过大问题
Could not load library cudnn_cnn_infer64_8.dll. Error code 126Please make sure cudnn_cnn_infer64_8.