聊聊c语言指针那些道道

学习c语言必学的就是学习指针的用法,能不能够用好指针完全可以代表你的c语言能力牛不牛,对于初学者来说,指针理解起来会有一定的难度,但是看得多了用的时间长了就会搞懂了。

指针就是地址,这句话应该是大家听到有关于指针的最多的定义,那指针到底是什么?为什么要用指针?怎么用指针?,接下来咱一块聊聊c语言指针的那些道道。
指针是什么?
为了说清楚什么是指针,必须弄清楚数据在内存中是如何存储的,又是如何读取的。
–>如果在程序中定义一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。编译系统根据程序中定义的变量类型,分配一定长度的空间。例如,一般为整型变量分配2个字节,对单精度浮点型变量分配4个字节,对字符型变量分配1个字节。内存区的每一个字节都有一个编号,这就是“地址”,它相当于旅馆中的房间号。在地址所标志的内存单元中存放数据,这就相当于旅馆房间中居住的旅客一样。

指针的表现形式:
其一般形式为: 类型说明符 *变量名;
其中,*表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指针变量所指向的变量的数据类型。

例如: int *p1;表示p1是一个指针变量,它的值是某个整型变量的地址。 或者说p1指向一个整型变量。至于p1究竟指向哪一个整型变量, 应由向p1赋予的地址来决定。
再如:
staic int p2; /*p2是指向静态整型变量的指针变量/
float p3; /*p3是指向浮点变量的指针变量/

指针的应用
从上面可以看出,我们所创建的指针变量的值就是地址,既然指针变量的值是一个地址, 那么这个地址不仅可以是变量的地址, 也可以是其它数据结构的地址。在一个指针变量中存放一个数组或一个函数的首地址有何意义呢? 因为数组或函数都是连续存放的。通过访问指针变量取得了数组或函数的首地址, 也就找到了该数组或函数。这样一来, 凡是出现数组,函数的地方都可以用一个指针变量来表示, 只要该指针变量中赋予数组或函数的首地址即可。这样做, 将会使程序的概念十分清楚,程序本身也精练,高效。在C语言中, 一种数据类型或数据结构往往都占有一组连续的内存单元。 用“地址”这个概念并不能很好地描述一种数据类型或数据结构, 而“指针”虽然实际上也是一个地址,但它却是一个数据结构的首地址, 它是“指向”一个数据结构的,因而概念更为清楚,表示更为明确。 这也是引入“指针”概念的一个重要原因。在后面会对指针在数组上应用进行实例说明。

指针变量的赋值只能赋予地址, 决不能赋予任何其它数据,否则将引起错误。其一般形式为: & 变量名; 如&a变示变量a的地址,&b表示变量b的地址。 变量本身必须预先说明。设有指向整型变量的指针变量p,如要把整型变量a 的地址赋予p可以有以下两种方式:
(1)指针变量初始化的方法 int a;
int *p=&a;
(2)赋值语句的方法 int a;
int *p;

p=&a;
不允许把一个数赋予指针变量,故下面的赋值是错误的: int p;p=1000; 被赋值的指针变量前不能再加“”说明符,如写为*p=&a 也是错误的。

把数组的首地址赋予指向数组的指针变量。
例如:
char a[2]={1,2};
char *p1=a;(创建指针变量p1,将数组第一个元素的地址给指针变量p1)
//此处数组的名a即为数组的首地址,也可以如下所示将a[0]的地址赋给p1.
P1=&a[0];

指针的运算

//Code1:
    char a[2]={1,2};
    char *p1=a;
    printf("\np1=:%d",p1);  
    printf("\n*p1=%d:\n",*p1);

out:这里写图片描述

这里p1显示的就是数组a的首元素地址或数组的首地址,其实是一个意思;*p1则是首地址所存放的元素“1”。
//Code2:
char a[2]={1,2};
    char *p1=a;
    *p1++;
    printf("\n*p1++:%d",p1);    
    printf("\n*p1++:%d\n",*p1);

这里写图片描述

//code3
char a[2]={1,2};
    char *p1=a;
    (*p1)++;
    printf("\np1:%d",p1);   
    printf("\n*p1:%d\n\n",*p1); 

这里写图片描述

(*p1)++分成两部来看,*p1和++,*p1就是数组中第一个元素"1",所以可以表示为:1++,即为2,但是地址没变,仍然为数组首地址。
//Code4
char a[2]={1,2};
    char *p1=a;
    *(p1++);
    printf("\n   p1:%d",p1);    
    printf("\n   *p1:%d\n\n",*p1);

这里写图片描述
从这里可以看出与Code2的运行输出结果是一致的,所以p++和 (p++)意思是一样的,增加的是地址(6356790–>6356791),所以*p1指向了数组中的第二个元素 2。

指针可以指向一个变量、结构体、数组、字符串,同样也可以指向一个函数,比如常听到的回调函数,回调函数的本质就是函数指针。下面是一个简单的回调函数示例:

#include <stdio.h>
int sum(int a,int b,int(*add1)())
{
    return (* add1)(a,b);
}
int callbackadd(int a  ,int b)
{
    return a+b;
} 
int main(int argc, char *argv[])
{
    int GetResult;
    GetResult=sum(1,2,callbackadd);
    printf("获取的结果为:%d:\n",GetResult);   
    return 0;   
}

callbackadd函数即为定义的回调函数,sum函数的入参有3个,第三个为函数指针,,当主函数想要调用sum函数时,需要将回调函数callbackadd的地址付给sum的第三个参数。
这里只简单的介绍了回调函数的用法,之后会单独详细的介绍回调函数的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值