指针你掌握了多少?(一)

引言

今天我们一起来探讨一下指针的基础应用。我们先了解一些基本的知识。我们都知道参数的传递有两种形式,一种是按值传递的,另一种就是按地址传递的。我们平时用的最多的就是按值传递,至于地址传递,只有在数组和我们今天的指针上看得到。我们之前了解的数据类型有int、char、float、double、void这五个数据类型,而数据结构呢,当然包括结构体和数组以及指针。还有就是我们在内存中是如何储存变量的?我们是把变量放进一个存储空间里面,这个存储空间在内存中有一个对应的地址,而我们要使用这个数据或者变量时,那么系统就会按照这个地址去寻找到我们需要的东西。而这个地址是什么呢?其实就像是一个编号一样,内存区每一个字节都有一个编号对应。我们访问数据的方式有两种,一种是直接访问,另一种是间接访问。直接访问是我们用的最多的,它按变量地址存取变量值。例如:printf(“%d”,i);这里访问i的方式就是直接访问的。而间接访问是我们通过“第三方”去访问这个内容,这个“第三方”就是指针。

①指针变量的定义及初始化

指针,我们先来说说指针是什么,我们上面说这个指针是“第三方”对吧,那么你想下,我们访问一个内容是不是要知道他的地址,如此联想一下,你应该可以知道,这个指针就是地址了。那如何保存一个地址呢?这就需要我们C语言的一个特殊的变量—指针变量。到此我们清楚了,指针是指地址,而指针变量是储存地址的变量。那么变量都是需要定义的,我们应该如何定义呢?上面说这是一个特殊的变量,那么它应该有它特殊的地方。而这个地方就是*。定义一个指针变量的格式是:基类型 *变量名;这个基类型就是我们一开始说的数据类型。
例如:

int *ptr;
//指针变量的类型(int):指明了该指针指向的内存空间所存储的数据类型。
//定义中的“*”表示所定义的变量是指针变量。变量名是ptr,而非*ptr。
//*ptr是指地址,仅仅在这里而言。后面有介绍

这里还有个初始化的问题,因为我们的指针变量只能储存地址,那么我们就需要给它一个地址就算初始化了,就需要用到取地址符(&),例如:

int a=10; 
int *ptr=&a;//将a的地址给了ptr
//当然我们也可以给一个空地址
int *ptr = NULL;
//我们还可以给一个常量的地址
int *ptr = 10;
//这里这样给是没有问题的,因为这里的ptr是指这个常量在内存中的地址,这
//个地址是常量区的,要注意一下你这里只能使用这个常量,并不可以修改这个常量。

指针变量在内存中的存储大小:任何指针变量在内存中的大小都是占4个字节。为什么呢?因为这个我们的地址是整型的,所以我们指针变量的大小是占4字节。

②指针的赋值

之前我们是说如何定义一个指针,那么如何给它赋值呢?还记得我们在给指针初始化的时候有一个&的例子,这个例子就是可以用来指针的赋值。因为我们指针是需要一个地址,而&是取地址符。所以有:

int val=10;
ptr = &val;
//这样我们就给ptr赋值了
//当然如果是一个指针那么就有
int *p=&val;
ptr = p;//指针之间可以直接等于

③指针运算符

前面我们又讲到一个取地址运算符(&),是一个用来取数据地址的运算符。相对应的也有取内容的运算符(*)。这里大家可能会有疑惑了,这个在前面定义的时候有一个int *ptr;这里的*ptr是指地址,而我们现在却是内容。我们要记住一点这个*如果是与基类型在一起的话那么这个就是指地址(一般是指定义的时候),如果没有那么这就是指取内容。*和&这两个都是自右向左运算的。另外记得*的右边只能是地址(除定义之外的地方)
再讲下加加减减运算。我们都知道++这个会让变量自加1,–这个会让变量自减1。如果将其用在指针上那会如何呢?我们来试试,我们先来看看这个(*ptr)++;,很显然我们有括号的先算括号里面的,所以我们先取ptr的内容10,然后进行++,那val这个变量就变成了11.不信可以用下面代码去试试

int val=10;
int *ptr=&val;
(*ptr)++;
printf(%d”, val);

我们再来看一个 *ptr++; 这个与上面的那个有所不同,怎么说呢?这是按自右向左的运算,那么我们先算ptr++,所以我们先输出ptr,在加加,输出ptr后我们对其取内容,执行完后,因为ptr他是一个地址,那么它如何加加呢?答案是他的地址会发生偏移,那么偏移多少呢?这个就取决于他的数据类型,如果像我们这里的int的话,会偏移4个字节。如果是char那么只会偏移一个字节。如此一说你应该明白了。
如果我们要先发生偏移在输出的话,那么你可以把++放前面,变成*++ptr;
如果你遇到了–,那么也是一样的。
这个加加减减的运算会应用在下面的数组当中。牢记!!!
还有就是指针±整数 或者 指针 - 指针
指针与整型值加减的结果是指针,表示使该指针指向该指针下移(-)或上移(+)存储单元个数(整型值)之后的内存地址。存储单元的大小就是该指针的数据类型所需的内存大小。这也就是偏移
指针与指针的减运算要求相减的两个指针属于同一类型,其结果是整数,表示两个指针之间的数据的个数。也就是地址(十进制)之间的差。

④指针的比较

前提:两个指针都指向相同类型的变量
这个也是一个地址的比较

操作意义
ptr_a < ptr_b如果a存储在b的前面则返回true
ptr_a <= ptr_b如果a存储在b的前面,或两个指针指向同一位置则返回true
ptr_a == ptr_b如果两个指针指向同一位置则返回true
ptr_a != ptr_b如果两个指针指向不同位置则返回true
ptr_a == NULL如果ptr_a是空值则返回true

⑤一维普通数组和指针

我们都知道,数组的首地址是指一个地址,那么我们如果使用指针的时候就可以直接赋值了,不需要取地址符了。

int num[6]={1,2,3,4,5,6};
int *p=num;

这样也就是将num的地址给了p,那么我们就可以对其进行操作了,我们可以使用偏移的方式来访问num中的元素,不一定要使用下标了。

for(; p<num+6;p++)
{
	printf(%d”, *p);
}
//这是一个一个访问,我们也可以指定访问,比如我们访问第3个元素
printf(%d”, p+2);

⑥字符串数组和指针

这个就是和普通数组和指针是一样的,都是有地址偏移的现象。如果我们是使用一个常量的字符串去给指针变量,那么我们要知道,我们可以调用这个数据,不过我们不能修改这个字符串。这个的更多应用还是在下一次的分享——指针高级应用,二维数组中比较多。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值