C语言指针操作(三)通过指针引用数组

这篇具有很好参考价值的文章主要介绍了C语言指针操作(三)通过指针引用数组。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

通过指针引用数组的几种方法的原理和差异;以及利用指针引用数组元素的技巧

关于地址,指针,指针变量可以参考这篇文章:

C语言指针操作(一)地址,指针,指针变量是什么

关于指针变量作为函数参数可以参考这篇文章:

C语言指针操作(二)指针变量作为函数参数

目录

一、数组元素的指针

1.1引入

1.2实例

二、在引用数组元素时指针的运算

2.1引入

2.2实例

2.3详细说明

三、通过指针引用数组元素

3.1引入

3.2举例说明

3.3拓展


一、数组元素的指针

1.1引入

一个数组包含若干元素,每个数组元素都占用存储单元,所以他们都有相应的地址,所谓数组元素的指针就是数组元素的地址。

1.2实例

下面用指针变量指向一个数组元素

int a[10] = { 1,2,3,4,5,6,7,8,9,10 };	//定义包含10个数据的整型数组
int* p;		//定义1个整型指针变量
p = &a[0];	//将数组元素a[0]的地址赋值指针变量

以上是将指针变量 p 指向 a 数组的第 0 号元素。

c语言指针数组的赋值与引用,C语言,数据结构,算法,c语言,c++,指针

引用数组元素可以使用下标法,也可以使用指针法,即通过指向数组元素的指针找到所需的元素,使用指针法能使目标程序质量高(占内存少,运行速度快)。

在 C 语言中,数组名(不包含形参数组名)代表数组中首元素(即序号为 0 的元素)的地址,所以下面两个语句等价

p = &a[0];		//p的值是a[0]的地址
p = a;			//p的值是数组a首元素(即a[0])的地址

注意:数组名不代表整个数组,只代表数组首元素的地址。

二、在引用数组元素时指针的运算

2.1引入

可以对数值型数据进行算数运算,那么可以对指针型数据进行算数运算吗?指针就是地址,显然对地址进行乘和除是没有意义的,只有在一定条件下进行的加和减才有意义。

当指针指向数组元素的时候,能够对指针进行加和减运算;例如指针变量 p 指向数组元素 a[0],则 p+1表示指向下一个数组元素 a[1]。

2.2实例

在指针已指向一个数组元素时,可以对指针进行以下运算:

①加一个整数( p + i ),如 p += 1;

②减一个整数( p - i ),如 p -= 1;

③自加运算,如 p++

④自减运算,如 p--

⑤两个指针相减,如 p1 - p2 (只有p1和p2都指向同一个数组中的元素时才有意义)

2.3详细说明

(1)如果指针变量 p 已指向数组中的一个元素,则 p+1 指向同一数组中的下一个元素,p-1 指向同一数组中的上一个元素。执行 p+1 时并不是将 p 的值(地址)简单地加 1 ,而是加上一个数组元素所占用的字节数。例如,数组元素是 float 型,每个元素占4个字节,则 p+1 意味着使 p 的值(地址)加4个字节,以使它指向下一元素。p+1所代表的地址实际上是 p+1×d ,d 是一个数组元素所占的字节数(在Visual C++ 中,对 int 型,d=4;对 float 和 long 型,d=4;对 char 型,d=1 )。若 p 的值是2000,则 p+1的值不是2001,而是2004。

那么系统怎么知道要把这个 1 转换为 4,然后与 p 的值相加呢?因为在定义指针变量时必须要指定基类型,如:float* p。

(2)如果 p 的初值为 &a[0],则 p+i 和 a+i 就是数组元素 a[i] 的地址,或者说,它们指向 a 数组序号为 i 的元素。 a 代表数组首元素的地址,a+1 也是地址,它的计算方法同 p+1 ,实际地址为 a+1× d。例如,p+9 和 a+9 的值是 &a[9],它指向a[9]。

c语言指针数组的赋值与引用,C语言,数据结构,算法,c语言,c++,指针

(3)*(p+i) 或 *(a+i) 是 p+i 或 a+i 所指向的数组元素,即 a[i],例如 *(p+5),*(a+5) 和 a[5] 三者等价,实际上,在编译时,对数组元素 a[i] 就是按 *(a+i) 处理的,即按数组首元素的地址加上相对位移量得到要找元素的地址,然后取出存储单元中的内容。

[ ]实际上是变址运算符,即将 a[i] 按 a+i 计算地址,然后找出此地址单元中的值。

(4)如果指针变量 p1 和 p2 都指向同一数组中的元素,如执行 p2 - p1,结果是 p2 - p1 的值(两个地址之差)除以该数组元素类型所占的字节长度。假设,p2 指向实型数组元素  a[5],p2 的值为2020;p1 指向 a[3],其值为2012,则 p2-p1 的结果是 (2020-2012)/4 = 2 。这个结果是有意义的,表示 p1 所指向的元素与 p2 所指的元素之间差 2 个元素。这样就不需要具体地知道p1和 p2的值,然后去计算它们的相对位置,而是直接用 p2-p1 就可知道它们所指元素的相对距离。

两个地址不能相加,如 p1+p2 是无实际意义的。

三、通过指针引用数组元素

3.1引入

引用数组元素,存在下面两种方法:

①下标法,如 a[i] ;

②指针法(数组名法和指针变量法),如 *(a+i) 或 *(p+i) ,其中 a 是数组名,p 是指向数组元素的指针变量,其初值为 p=a;

3.2举例说明

有一个整型数组 a,有10个元素,要求输出数组的全部元素

(1)下标法

#include<stdio.h>
int main()
{
	int a[10] = { 1,3,5,7,9,2,4,6,8,10 };
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);	//通过下标表示
	}
	printf("\n");
	return 0;
}

(2)通过数组名和元素序号计算数组元素的地址

#include<stdio.h>
int main()
{
	int a[10] = { 1,3,5,7,9,2,4,6,8,10 };
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", *(a + i));	//通过数组名和元素序号计算
	}
	printf("\n");
	return 0;
}

(3)用指针变量指向数组元素

#include<stdio.h>
int main()
{
	int a[10] = { 1,3,5,7,9,2,4,6,8,10 };
	int* p;
	for (p = a; p < (a + 10); p++)
	{
		printf("%d ", *p);		//用指针指向当前的数组元素
	}
	printf("\n");
	return 0;
}

三种方法的比较:

①第(1)和第(2)种方法的执行效率是相同的,编译系统将 a[i] 转换为 *a[i+1] 处理的,第(3)种方法比前面两种更快,用指针直接指向元素,不必每次都重新计算地址,大大提高执行效率。

②用下标法比较直观,能直接知道是第几个元素;用地址法或指针变量的方法不直观,难以很快的判断出当前处理的是哪一个元素。

需要注意的是:不能通过改变数组名a的方式(例如:a++ )来改变所指向的变量,因为 a 代表的是数组首元素的地址,他是一个指针型常量,它的值是固定不变的。

3.3拓展

(1)指向数组元素的指针变量也可以带下标,如 p[i] ;因为程序在编译时,对下标的处理方法是转换为地址,p[i] 处理成 *(p+i) ,需要注意的是此时 p[i] 的指向,若 p 指向 a[0],则 p[2] 代表 a[2],若 p[i] 指向 a[3],则 p[2] 代表 a[5],建议少用,容易出错。

(2)利用指针引用数组元素,比较灵活方便,可以使用一些技巧使程序更加简洁。

① *p++ :由于++和 * 同优先级,结合方向为自右而左,因此它等价于 *(p++),即先引用p的值,实现 *p 的运算,然后再使 p 自加1。

#include<stdio.h>
int main()
{
	int a[3] = { 2,5,8 };
	int* p;
	for (p = a; p < (a + 3);)
	{
		printf("%d ", *p++);
	}
}

c语言指针数组的赋值与引用,C语言,数据结构,算法,c语言,c++,指针

② *(p++) 和 *(++p) 的作用不相同,前者先取 *p 的值,然后再自加 1,后者先使 p+1,再取 *p 的值。

#include<stdio.h>
int main()
{
	int a[3] = { 2,5,8 };
	int b[3] = { 2,5,8 };
	int* p, * q;
	for (p = a; p < (a + 3); )
	{
		printf("%d ", *(p++));
	}
	printf("\n");
	for (q = b; q < (b + 3); )
	{
		printf("%d ", *(++q));
	}
}

c语言指针数组的赋值与引用,C语言,数据结构,算法,c语言,c++,指针

后着因为没有定义数组 b 的第 4 个元素 b[4],所以指向了一个不确定的位置。

③ (*p)++ 和 ++(*p) 作用不相同,但都是先得到 (*p) 所指向元素的值,前者先把 (*p) 所指向的元素值作为表达式的值后,再自加 1;后着是自加 1 后再作为表达式的值。但需要注意的是:他们都是使 p 所指向的元素加 1 ,而不是使指针 p 的值加 1 。

#include<stdio.h>
int main()
{
	int a[3] = { 2,5,8 };
	int b[3] = { 2,5,8 };
	int* p, * q;
	for (p = a; p < (a + 3); p++)
	{
		printf("%d", (*p)++);
	}
	printf("\n");
	for (q = b; q < (b + 3); q++)
	{
		printf("%d", ++(*q));
	}
}

c语言指针数组的赋值与引用,C语言,数据结构,算法,c语言,c++,指针

C语言指针操作系列文章:

C语言指针操作(一)地址,指针,指针变量是什么

C语言指针操作(二)指针变量作为函数参数

C语言指针操作(三)通过指针引用数组

C语言指针操作(四)用数组名作函数参数

C语言指针操作(五)通过指针引用多维数组

C语言指针操作(六)通过指针引用字符串

C语言指针操作(七)指向函数的指针

C语言指针操作(八)返回指针值的函数

C语言指针操作(九)指针数组和多重指针

C语言指针操作(十)动态内存分配与指向它的指针变量

C语言指针操作(十一)有关指针的小结文章来源地址https://www.toymoban.com/news/detail-759154.html

到了这里,关于C语言指针操作(三)通过指针引用数组的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 8.4 【C语言】通过指针引用字符串

    在C程序中,字符串是存放在字符数组中的。想引用一个字符串,可以用以下两种方法。 (1)用字符数组存放一个字符串,可以通过数组名和下标引用字符串中一个字符,也可以通过数组名和格式声明“%s”输出该字符串。 例:定义一个字符数组,在其中存放字符串“I love

    2024年02月11日
    浏览(35)
  • C++【4】指针与引用;数组指针;指针数组

    /*     指针变量作为函数参数         函数的参数可以是指针类型,它的作用是将一个变量的地址传送到另一个函数中。         指针变量作为函数参数与变量本身作为函数参数不同,变量作函数参数传递的是具体值。         而指针作为函数参数传递的是内存的地址

    2024年02月07日
    浏览(38)
  • C语言之通过指针操作字符串

    下面我们来学习通过指针来灵活操作字符串的方法 我们用对指针的遍历来实现判断字符串的长度 在函数形参的声明中由使用[ ]变为*,这些声明方式是一样的,只是表面上的一些变化,实质上并没有什么变化。 程序中发生实质性变化的事函数体,让我们结合下图来看(以输入

    2024年01月19日
    浏览(45)
  • 厦大2021届大一小学期C语言作业1 数组+字符串+指针+位操作

    题目描述: 1.程序要求:实现对5个数(a[0]~a[4],数组元素从键盘读入)进行从大到小起泡法排序。输入第一组数据:1 2 3 4 5;输入第二组数据:3 5 4 1 2;验证程序的正确性。 题目描述: 2.程序要求:实现三阶方阵转置,并打印转置后的方阵。 测试主函数为: int main() { in

    2024年02月15日
    浏览(48)
  • 【Rust】——通过Deref trait将智能指针当作常规引用处理

    💻博主现有专栏:                 C51单片机(STC89C516),c语言,c++,离散数学,算法设计与分析,数据结构,Python,Java基础,MySQL,linux,基于HTML5的网页设计及应用,Rust(官方文档重点总结),jQuery,前端vue.js,Javaweb开发,Python机器学习等 🥏主页链接:     

    2024年04月26日
    浏览(37)
  • 通过数组的指针获得数组个数

      这几天学习智能指针时,自己在练习写个管理数组指针的类时碰到了通过数组指针获取数组个数的问题 1.在网上查询了通过数组指针获取数组个数的方法,对于自定义数据在前四个节点保存了数组个数   测试是成功的,但是是对于内置数据类型int,double,char等就不成功了 2.又晕菜

    2024年02月08日
    浏览(36)
  • 0063__关于C语言的数组赋值和数组下标越界问题

    关于C语言的数组赋值和数组下标越界问题_c语言 下标越界_为什么我不是源代码的博客-CSDN博客 C语言——数组越界导致程序的死循环_数组对于程序的影响_Violet青莲的博客-CSDN博客

    2024年02月10日
    浏览(40)
  • C语言通过ODBC函数操作Access数据库(mdb和accdb格式)(char字符数组)

    编译环境:Windows XP + Visual Studio 2010 数据库:Access 2010,accdb格式 本例程只使用char[]字符数组,不使用wchar_t[]字符数组,更适合C语言初学者。 如果读取字符串时,db_bind_str提供的字符数组空间小了,db_fetch会执行失败返回-2。 由于Windows系统设计原因,char[]字符数组只能存储G

    2024年02月02日
    浏览(50)
  • C通过指针访问数组元素

    在C语言中,数组除了通过数组索引访问,也可以通过指针来访问数组中的元素。下面是一个简单的例子: 在这个例子中,我们首先定义了一个包含5个元素的整数数组 array 。然后,我们定义了一个指向 array 的第一个元素的指针 ptr 。在 for 循环中,我们使用 *(ptr + i) 来访问数

    2024年02月05日
    浏览(43)
  • C语言 - 最简单,最易懂的指针、引用讲解

    输出结果如下: 先看这一行 都知道 是取址符是吧,好,h 是取h结构体的地址,结果没问题,参照上图。 接着,hp,hp是一个指针,指向了h所在的地址(hp = h),注意:hp是取hp变量的地址,而不是h的地址,所以打印出来的是 6290920。(printf %d是打印数字,这里输出的是10进制

    2024年02月02日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包