C语言指针学习笔记2-指针引用数组

3.通过指针引用数组

3.1什么是数组元素的指针

所谓数组元素的指针就是数组元素的地址。可以用一个指针变量指向一个数组元素。例如:

int a[10]={1,2,4,5,6,7,8,9};
int *p;
p=&a[0];

在C语言中,数组名代表数组中首元素的地址。因此,下面两个语句等价:

p=&a[0];
p=a;

程序中的数组名不代表整个数组,只代表数组首元素的地址。上述“p=a”的作用是把a数组的首元素的地址赋给指针变量p

3.2 引用数组元素时指针的运算

	在一定条件下允许对指针进行加和减的运算,但是没有乘除。

那么,在什么情况下需要而且可以对指针进行加和减的运算呢?回答是:当指针指向数组元素的时候。
例如,指针变量p指向数组元素a[0],我们希望用p+1表示指向下一个元素a[1]。
在指针已指向一个数组元素时,可以对指针进行一下运算:
加一个整数(用+或+=),如p+1;
减一个整数,如p-1;
自加运算,如p++,++p;
自减运算。
两个指针相减,如p1-p2(只有p1和p2都指向同一数组中的元素时才有意义)。
如果指针变量已指向数组中的一个元素,则p+1指向同一数组中的下一个元素,p-1指向同一数组中的上一个元素注意

执行p+1时并不是将p的值(地址)简单地加1,而是加上一个数组元素所占用的字节数。

例如,数组元素是float型,每个元素占4个字节,则p+1意味着使p的值(是地址)加4个字节,以使它指向下一元素。

*(p+i)是p+i所指向的数组元素,即a[i]。

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

可以p1-p2,但是不可以p1+p2,这样是无意义的。例如,p2-p1的结果是两个地址之差除以数组元素的长度。p2-p1=(2020-2012)/4=2

3.3 通过指针引用数组元素

  1. 下标法,如a[i]形式;
  2. 指针法,如*(a+i)或*(p+i)。其中a是数组名,p是指向数组元素的指针变量,其初值p=a。

例1、有一个整型数组a,有10个元素,要求输出数组中的全部元素。

#include <stdio.h>
int main()
{
    int a[10];
    int i;
    printf("please enter 10 integer numbers:");
    for(i=0;i<10;i++)
        scanf("%d",&a[i]);  //&a[i]也可以改用(a+i)表示。
    for(i=0;i<10;i++)
        printf("%d",a[i]);
      //printf("%d",*(a+i));   //通过数组名和元素序号计算元素地址,再找到该元素
    printf("\n");
    return 0;
}
//用指针变量指向数组元素
#include <stdio.h>
int main()
{
    int a[10];
    int *p,i;
    printf("please enter 10 integer numbers:");
    for(p=a;p<(a+10);p++)
        scanf("%d",p);
    for(p=a;p<(a+10);p++)
        printf("%d",*p);
    printf("\n");
    return 0;
}
	用指针变量表示数组,提高了执行效率,速度更快。
#include <stdio.h>
int main()
{
    int i,a[10],*p=a;
    printf("please enter 10 integer numbers:");
    for(i=0;i<10;i++)
        scanf("%d",p++);
    p=a;
    for(i=0;i<10;i++,p++)
        printf("%d",*p);
    printf("\n");
    return 0;
}

3.4 用数组名作函数参数

实参数组名代表该数组首元素的地址,而形参是用来接收从实参传递过来的数组首元素地址的。
因此,形参应该是一个指针变量(只有指针变量才能存放地址)。

所以,函数fun的形参是写成数组形式的:

fun(int arr[],int n)

但在程序编译时是将arr按指针变量处理的,相当于将函数fun的首部写成

fun(int *arr,int n)

此时,*(arr+i)和arr[i]是无条件等价的。

从应用的角度看,用户可以认为有一个形参数组,它从实参数组那里得到起始地址,因此形参数组与实参数组共占同一段
内存单元,在调用函数期间,如果改变了形参数组的值,也就是改变了实参数组的值。

注意:实参数组名代表一个固定的地址,或者说是指针常量,但形参数组名并不是一个固定的地址,而是按指针变量来处理。
在函数执行期间,形参的值就是实参数组首元素的地址,它可以再被赋值。例如:

void fun(int arr[],int n)
{
	printf("%d\n",*qrr);
	arr=arr+3;
	printf("%d\n",*qrr);
}

例2、将数组a中n个整数按相反顺序存放,用函数实现。

#include <stdio.h>
int main()
{
    void fun(int *p);
    int a[6]={0,3,5,6,7,4},i;
    for(i=0;i<6;i++)
        printf("%d ",a[i]);
    printf("\n");
    fun(a);
    for(i=0;i<6;i++)
        printf("%d ",a[i]);
}
void fun(int *p)
{
    int temp,i;
    for(i=0;i<6/2;i++)
    {
        temp=*(p+i);
        *(p+i)=*(p+5-i);
        *(p+5-i)=temp;
    }
}

例3、用指针方法对10个整数按由大到小顺序排序。

#include <stdio.h>
int main()
{
    void sort(int x[],int n);
    int i,*p,a[6];
    p=a;
    for(i=0;i<6;i++)
    {
        scanf("%d",p++);
    }
    p=a;
    sort(a,6);
    for(i=0;i<6;i++)
    {
        printf("%d ",*p);
        p++;
    }
    printf("\n");
    return 0;
}
void sort(int x[],int n)
{
    int i,j,t;
    for(i=0;i<n-1;i++)
        for(j=0;j<n-i-1;j++)
            if(x[j]<x[j+1])
            {
                t=x[j];
                x[j]=x[j+1];
                x[j+1]=t;
            }
}

*3.5通过指针引用多维数组

要掌握的是,a,a+i,a[i],*(a+i)+j,a[i]+j都是地址。而*(a[i]+j)和*(*(a+i)+j)是二维数组元素a[i][j]的值。

int (*p)[n]是定义指向包含n个元素的一维数组的指针变量中

用指针变量作形参,以接受实参数组名传递来的地址。可以有两种方法:

  1. 用指向变量的指针变量;
  2. 用指向一维数组的指针变量。
例如:
void ave(int *p,int n) 		
对应实参是
ave(*a,12)
void sort(int (*p)[4],int n)     //这里的p是指向具有4个元素的一维数组的指针
对应实参是
sort(a,2)

详细说明请查阅谭浩强的C语言程序设计第五版P244~P253。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言是一种广泛应用于计算机科学和软件开发的编程语言。它具有强大的功能和灵活性,适用于开发各种类型的应用程序。 C语言专题精讲篇是一个对C语言进行深入学习和讲解的系列文章或课程。它汇总了C语言相关的重要知识点和技巧,旨在帮助学习者更好地理解和运用C语言。 这个专题中的笔记涵盖了C语言的各个方面,包括基本语法、数据类型、运算符、流程控制、函数、数组指针、结构体、文件操作等。通过系统性的学习和总结,这些笔记可以帮助学习者逐步掌握C语言的核心概念和常用技巧。 在这个专题中,学习者可以学到如何编写简单的C程序,如何使用变量和运算符进行计算,如何使用条件和循环语句控制程序流程,如何使用函数进行代码的模块化,如何使用数组指针进行数据的处理,如何使用结构体组织复杂数据,如何进行文件的读写等等。 C语言专题精讲篇的目的是帮助学习者全面、深入地了解C语言的各个方面,并能够独立编写和调试简单到中等难度的C程序。通过反复实践和练习,学习者可以逐渐提高自己的编程能力,并为进一步学习更高级的编程语言打下坚实的基础。 总之,C语言专题精讲篇的笔记汇总是一份重要的学习资料,可以帮助学习者系统地学习和掌握C语言的基础知识和常用技巧,为他们未来的编程之路打下坚实的基石。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值