所谓数组的指针,即指数组的起始地址,数组元素的指针是指数组元素的地址。
1.一维数组的地址

在C语言中,数组名是个不占内存的地址常量,它代表整个数组的存储首地址。
一维数组元素a[i]的地址可以写成表达式&a[i]或a+i,&a[i]是用下标形式表示的地址,a+i是用指针形式表示的地址,二者结果相同。元素a[i]的地址等于数组首地址向后偏移若干字节,偏移的字节数等于a[i]与首地址之间间隔元素的数目乘以一个元素所占存储单元的字节数。
那么,*(a+i)表示a+i地址中的内容,就是a[i]的值,这就是通过地址常量数组名引用一维数组。
2.一维数组指针的定义
定义一个指向数组的指针变量的方法,与定义指向简单变量的指针变量的方法相同。例如:
int a[10]={1,2,3,4,5,6,7,8,9,10}; /定义a为包含10个整型数据的数组/
int *p; /定义p为指向整型变量的指针变量/
定义了一个整型数组a和一个指向整型变量的指针变量p。这时指针变量p并没有指向任何对象,只有当数组a的起始地址赋值给指针变量p时,指针p才表示指向数组a,称指针p为指向数组a的指针。指向过程可以通过下面两种方法实现:
(1)用数组名做首地址。形式为:
p=a;
表示将数组a的起始地址赋值给指针p,而不是将数组a的所有元素赋值给指针p。

数组a的起始地址赋值给指针,也可以在指针定义的同时进行。例如:
int a[30];
int *p=a; /*指针的初始化*/
在定义指针变量p的同时,将数组a的起始地址赋值给指针变量p,而不是赋值给指针p指向的变量。
(2)用数组第0个元素地址做首地址。形式为:
p=&a[0];
数组名a与数组元素a[0]的地址相同,都是数组的起始地址,因此也可以将&a[0]赋值给指针p。
3.利用指针引用一维数组元素
如果指针变量p指向数组a的第一个元素(即第0号元素),即p=a,则
(1)p+i和a+i就是数组元素a[i]的地址,即它们指向数组a的第i+1个元素,即i号元素。
(2)*(p+i)或*(a+i)就是p+i或a+i所指向的数组元素,即a[i];
(3)指向数组元素的指针变量也可以带下标,如p[i]与*(p+i)等价。所以,a[i]、*(a+i)、p[i]、*(p+i)四种表示方法全部等价。
(4)指针变量可以通过本身值的改变来实现对不同地址的操作,既可以使用p++。因为数组名表示数组的起始地址,所以数组名也可以称为指针,但是数组名是一个特殊的指针,它是指针常量,其值在程序整个运行过程中都不能被改变,只代表数组的起始地址。所以,如果a是一个数组名,它是一个指针常量,像“a++”或者“a=a+2”这些语句都是错误的。

综上所述,把指针与一维数组的联系归纳为下表(针对int a[10],*p=a)

表达式 含义
&a[i],a+i,p+i 引用数组元素a[i]的地址
a[i]、*(a+i)、p[i]、*(p+i) 引用数组元素a[i]
p++、p=p+1 表示p指向下一数组元素,即a[1]
*p++、*(p++) 先取p所指向的存储单元的内容*p,再使p指向下一个存储单元
*++p、*(++p) 先使指针p指向下一个存储单元,然后取改变后的指针p所指向的存储单元内容*p
(*p)++ 取指针p所指的存储单元内容作为该表达式的结果值,然后使p所指对象的值加1,即*p=*p+1;指针p的内容不变

例:
从键盘输入10个数,利用指针法输入、输出数组。

#include<stdio.h>
void main()
{int    i,*p,a[10];p=a;for(i=0;i<10;i++)scanf("%d",p++);printf("\n");p=a;for(i=0;i<10;i++)printf("a[%d]=%d\n",i,*p++);
}

4.指向二维数组的指针

定义一个二维数组:
int a[3][4];

二维数组a的各种表示形式及其含义

表示形式 含义
a 数组a的起始地址,也是数组第0行的首地址
a+i、&a[i] 第i行的起始地址
*(a+i)、a[i] 第i行第0列元素的起始地址
*(a+i)+j、a[i]+j,&a[i][j] 第i行第j列元素的起始地址
*( *(a+i)+j)、*(a[i]+j)、a[i] [j] 第i行第j列元素的值

注意:基于一维数组有a[0]和*(a+0)等价,a[1]和*(a+1)等价,a[2]和*(a+2)等价,因此第i行第j列地址也可以表示为*(a+i)+j,即&a[i][j]=a[i]+j=*(a+i)+j。
利用指向二维数组元素的指针变量,可以完成二维数组数据的操作处理。
(1)定义与二维数组相同类型的指针变量;
(2)在指针变量与要处理的数组元素之间建立关联;
(3)使用指针的运算就可以访问到任何一个数组元素,完成操作处理。

例1:
利用指针变量及指针变量的自增运算,输出二维数组所有元素的值。

#include“stdio.h”
void main()
{int    a[3][3]={{0,1,2},{3,4,5},{6,7,8}};int  *p,*q;p=a[0];q=&a[2][2];while(p<=q){ printf("%d   ",*p);p++;}printf("\n");
}

例2:

利用数组指针求给定nxn矩阵的转置矩阵,并计算对角线元素之和。
分析:

数组指针是指向数组的指针变量,也叫行指针变量。

如有数组指针变量p和二维数组a[3][4],p=a或p=&a[0]说明p指向了数组a的第0行,p+1指向了数组的第一行,p+i指向了数组的第i行,也说明了p+i等价于&a[i]。
*(p+i)等价于a[i]或*(a+i),*((p+i)+j)等价于*(a[i]+j)、*((a+i)+j)、a[i][j]。

要将一个矩阵转置,只要将这一个矩阵的上三角矩阵与其关于主对角线对称的下三角阵交换即可,也就是将a[i][j]和a[j][i]交换。

源程序:

#include<stdio.h>
#define N 4
void mian()
{int a[N][N],(*p)[N];int i,jjt,s=0;printf("input a:\");for(i=0;i<N;i++){ printf("input the %dth row:\n",i+1);for(j=0;j<N;j++)scanf("%d",&a[i][j]);}p=a;for(i=0;i<N;i++){s+=*(*(p+i)+i);              /*累加对角线上的元素*/for(j=i+1;j<N;j++)          /*交换a[i][j]和a[j][i]*/{t=*(*(p+i)+j);*(*(p+i)+j)=*(*(p+j)+i);*(*(p+j)+i)=t;}}for(i=0;i<N;i++)                       /*输出转置后的矩阵*/{for(j=0;j<N;j++)printf("%4d",*(*(p+i)+j));printf("\n");}printf("s=%d\n",s)
}

(九)指向一维数组和二维数组的指针(数组指针)相关推荐

  1. 【蓝桥杯Java_C组·从零开始卷】第四节、一维数组与二维数组

    整篇文章为对java数组的完整理解以及部分排序,并有一些简单的demo,经典的案例与蓝桥杯的一些经典数组题有专门的文章梳理. 目录 数组概述 什么是数组 数组的结构 数组的特点: 数组分类 一维数组声 ...

  2. 【C语言】指针表达进阶:指针在一维数组、二维数组的应用(如何用指针表达一维数组、二维数组的元素的地址、元素值)

    指针可以替代数组名 1.在一维数组中:int a[9]; int *p=a; 一维数组名指向的是列!(后面总结,迷得话不用慌) 则想要获取a[i]的地址方法:a+i; .p+i; .p[i]; 获取a ...

  3. Java 中的一维数组以及二维数组(8千字零基础超全详解)

    文章目录 前言 一.一维数组 1. 数组的初始化 1.1 动态初始化一 1.2 动态初始化二 1.3 静态初始化 2. 数组使用的注意事项和细节 3. 经典例题 4. 数组赋值机制(重难点!) 5. ...

  4. c/c++ 一维数组、二维数组作为函数参数、返回值

    c/c++ 一维数组.二维数组作为函数参数.返回值 一.一维数组作为参数 传入数组 int [] 为了规范,常常需要将数组的size一同传入,这是因为C++/C遇到参数为数组时,不会去一个个拷贝数组内 ...

  5. c语言三维数组 三维指针,C语言 通过指针访问一维数组,二维数组,三维数组。...

    /** 通过指针来访问一维数组,二维数组,多维数组 */ #include const int COLS=3; const int COUNT=4; //通过一级指针,计算偏移量来遍历一维数组 voi ...

  6. Java数组介绍(一维数组和二维数组)

    Java数组介绍(一维数组和二维数组) 1. 概述 · 数组是存储多个变量的容器. · 存储的多个变量必须是同一种数据类型. · 数组既可以存储基本数据类型,也可以存储引用数据类型. 2. 数组定义的 ...

  7. java基本语法(三)——一维数组和二维数组

    数组是最常见的数据结构,每个数组元素存放一个数据,通过数组元素的索引来访问数组元素. 一维数组 数组的定义 java支持两种方式来定义数组 1) type[] arrayName; 2) type a ...

  8. c语言bool怎么用_C语言中的一维数组和二维数组什么?怎么用?

    C++| 匠心之作 从0到1入门学编程[免费]​yun.itheima.com C语言除了基本数据类型之外,还提供了构造类型的数据,构造类型的数据包括数组类型.结构体类型和共用体类型.下面我们详细介绍 ...

  9. android 一维数组遍历,$.each()循环遍历一维数组、二维数组、JSON数据和DOM元素

    本文介绍$.each()循环遍历一维数组.二维数组.JSON数据和DOM元素. 请注意在使用JQuery $.each()方法前,要首先引用jquery库文件. $.each()循环遍历一维数组 Jq ...

  10. php 数组与数组之间去重,PHP开发中一维数组与二维数组去重功能实现教程

    本篇文章讲述了PHP实现一维数组与二维数组去重功能示例.希望对在php学习和开发的同学有所帮助! 数组中重复项的去除 一维数组的重复项: 使用array_unique函数即可,使用实例如下: ? $a ...

最新文章

  1. 设计模式C++实现——组合模式
  2. 检查一列数据的重复项 vba_提取重复值,但字典不是重点。
  3. 文件已经上传到服务器翻译,服务器接受上传的优化 翻译+源码分析
  4. 268 missing number
  5. python 无头浏览器xhr 文件_Python对Selenium调用浏览器进行封装包括启用无头浏览器,及对应的浏览器配置文件...
  6. raspberry pi_如何购买Raspberry Pi
  7. cookie和session机制之间的区别与联系
  8. 在普通用户下进入root用户
  9. E盾网络验证企业版个人版离线版对接好的自绘界面4加密防破解易语言源码加密
  10. 嵌入式软件硬件比例_嵌入式软件硬件常识
  11. 文书档案管理系统服务器版,文书档案管理系统
  12. 基于STM32单片机的智能药盒定时提示吃药喂水蓝牙APP方案原理图设计
  13. 1、什么是软件危机?它是哪些典型表现?为什么会出现软件危机?
  14. 大数据时代网络舆情与社会治理研究
  15. html中添加ie兼容性视图,IE11浏览器添加到兼容性视图中的网站无法保存怎么办?...
  16. 推荐低保真原型设计软件 Balsamiq Mockup
  17. 如何解决PDFcopy文本乱码的问题!
  18. opencv学习---计算图像的水平积分投影和垂直积分投影
  19. 学习PLC有什么好方法吗
  20. mysql 游标大小_Mysql游标入门

热门文章

  1. 怎么把优酷的kux格式转换成avi格式
  2. 让XP系统也支持微软雅黑字体
  3. oracle11 ssd 补丁,新装Oracle 11gR2 11.2.0.2重要说明——Patchset p10098816(附补丁下载地址).docx...
  4. 构建一套完整高效的供应链系统体系
  5. 数据挖掘十大经典算法
  6. ActiveX 部件不能创建对象
  7. word打开wps文件乱码_word文件打不开,打开时遇到错误用文本修复器打开文件 WPS打开时是乱码...
  8. Python——百度识图-相似图片爬虫下载解决方案
  9. 3d显卡2003测试软件,3DMark 2003
  10. STM32:FSMC驱动TFTLCD(ST7789)