一键高效理解指针------一看就会

本文详细阐述了指针在计算机内存中的作用,包括内存单元、地址和指针的关系,以及指针变量的定义、运用、与数组和函数的交互。重点讲解了指针的赋值、运算和在值传递中的角色,强调了指针的理解和使用注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.指针的本质

1.1内存单元、地址、指针的关系

        在计算机中,运行的程序和数据都是放在计算机内存中,内存的基本单元是字节,一般存储器中的一个字节被称为一个内存单元,不同数据类型所占据的内存单元不等,如整型变量占两个单元(有的编译器为4个),字符变量为1个单元等,为了正确的访问内存单元,必须给每个内存单元一个编号,该编号称为该内存单元的地址。程序中的每个变量都有固定的位置,有具体的地址。

        指针是访问变量的地址,过去我们常用的scanf函数,其实是一种直接访问的方法,可以理解为直接取地址进行操作的方式为地址的直接访问,访问变量时需要先访问其地址,如果用一个变量来存储访问变量的地址,那这个变量就是地址变量--->没错,就是我们的主角指针变量了!通过指针访问指向变量的方式称为“间接访问”,访问变量的地址就是指针,存放指针的变量是指针变量,这两个概念不要混淆了。

        为什么我们明明可以用地址去表示,却还要引入指针这个概念呢?问的很好,因为在实际的程序运行过程中,一个函数或者一个数组是占据了一大片地址,这个时候我们用地址去描述函数或者数组对象就会显得很麻烦,但是指针指向了函数或者数组的首地址,我们通过首地址便可以访问这个数组或者函数了,这样一种“数据结构类型”被一个指针完美表达了,对于我们的实际调用和访问简直太棒了!ok,看到这里想必你肯定已经明白了指针本质了。

1.2指针变量的定义及运用

         在C语言中,指针变量和其它变量一样,在使用前必须先定义(不然就是野指针了很危险的),定义的格式为 (类型说明符  *变量名)---->(int *ptr 指向整型变量的指针变量)。

        指针赋值有两种常见方法,第一对指针变量初始化,第二是用赋值语句。C语言中,变量的地址是由编译器系统自动分配的,对于用户来说是完全不透明的,因此必须使用地址运算符&取得变量的地址。

        指针变量的引用形式为 (* 指针变量),其中“*”为取内容运算符,为单目运算符,其结合性为右结合性。注意哦,这个“*”运算符后面的变量只能是指针变量,在指针变量说明中,"*"是类型说明符,表明这是个指针变量,而表达式中的“*”则是指针运算符哦,不要搞混了。

        指针有赋值运算、加减法运算、关系运算、空运算。

    //赋值运算
    int *p, a = 2;
    p = &a;

    //加减法运算  
    int a[5], *pa = a;
    pa += 2;       // P = P + 2,  p之前指向a[0], 加法运算后 p指向a[2]      

    //关系运算
    int *p1, *p2, a1=1 , a2=2; 
    //若运算成立
    p1 < p2;    //p2指向地址更大
    p1 > p2;    //p1指向地址更大
    p1 == p2;   //p1与p2指向地址相对

    //空运算
    int *pm = NULL;

2.指针与数组

2.1指针与一维数组

        众所周知,数组名等于数组的首地址等于数组第一个元素地址(欧克,这里你们先知道,我告诉你们的),所以数据名就可以等价于数组的指针,因此我们常用指针指向数组名,例如:指针ptr就获取到了数组的首地址, ptr = arrays = &arrays[0]。 接下来我们将进行指针与数组的访问,结合之前的*ptr等于取出地址变量的概念,我们可以得出以下关联式*(ptr+n) = arrays[n] = ptr[n];这个公式非常的实用,请务必记住。

    int arrays[10] = {0};
    int *ptr;

    ptr = arrays;

2.2指针与二维数组

        二维数组可以理解是行列组合,如a[2][3]表明2行3列总共6个数组元素,在内存中按行存放,其中a是二维数组的首地址,a+i = &a[i][0] = a[i] = &a[i] = *(a+i) ;这里可能有小伙伴发出灵魂拷问,a[i]这么理解呢?很好,a[i]可以理解为第i行的首地址,所以它肯定和a是等价的,因为a也是第i行的首地址,二维数组可以理解为一维数组的集合,是不是这样就恍然大悟了。同理对于访问可以得出下面的关联式:a[i][[j] = *(a+i)[j] = *(*(a+i)+j)。

int a[3][4];
int *p1;      //一维变量
int (*p2)[4]; //二维数组指针变量


P1 = a[0];
p2 = &a[0][0] = a;

2.3指针与多维数组

        多维指针这里就是在二维基础上叠罗汉了,实际情况几乎用不到三维数组和指针的情况,一方面不方便代码的移植理解,另一方面大大增加了指针误用的概率和风险,这里就不多介绍了。

3.指针与函数

        函数相比大家已经非常清楚了,我这边就简单介绍一下,函数的定义是通常会有形成,比如代码中,函数定义的入口(int a, int b)为形参,mian函数中调用的函数test_fun(a,b),这里的a,b为实参,当形参是指针类型时,这个时候实际是向函数传递变量的地址,而不仅仅是函数的值了,也就是常说的地址传递和值传递。

        注意C语言中,函数的实参与形参始终是“值传递”的方式,只是当形参为指针变量时,我们不能改变指针变量本身的值,但可以通过函数改变指针变量指向的变量值,这并不冲突。函数可以返回一个值,而运用指针变量作为参数,可以得到多个变化的值,这就是参数为指针变量的好处。

        指向函数的指针,每个函数在编译链接后会占用一段连续的内存区,函数名就是该区域的入口地址,每个入口地址就是函数指针。定义函数指针,可以提高程序的通用性和适应性,常用于回调函数中。函数指针的定义为 类型说明符 (* 指针变量名)()--->( int (*pf)() ) , pf为函数指针。



int test_fun(int a, intb)
{

    int c = 0;

    int c = a+b;

    return c;
}


int mian()
{
    int a = 2;
    int b = 4;
    int c = 0; 

    c = tese_fun(a, b);
}

4.指针小结

1.变量的地址就是指针变量;

2.指针运算符在定义是类型符合,在表达式中是间接取值;

3.C语言中,绝大部分变量都可以用指针指向,取值的方法有两种,一个是变量名直接取值,一个是指针变量间接取值;

4.指针变量指向一维数组时,p+1指向下一个元素,p-1指向上一个元素;

5.指针数组的元素是指针;

6.理解指针函数与函数指针;

7.理解指针数组与数组指针;

8.指针的指向一定要明确,防止越界;

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值