指针

        很多人认为指针是C语言中的一大难点。其实弄懂了指针的基础概念,或许也没有那么的难。

我们通过指针的使用,可以更好的操作字符串,数组,还有函数等等······ 我们先来看看下面这个代码——使用交换两个数的值。

void Swap(int A, int B)
{
	int tmp = A;
	A = B;
	B = tmp;
}
int main()
{
	int a = 10;
	int b = 20;
	printf("a=%d b=%d\n", a, b);
	Swap(a, b);
	printf("a=%d b=%d\n", a, b);
	return 0;
}

可以看到,a,b的值并没有发生变换,这是因为A,B仅仅是a,b的副本,它虽然在函数里发生了改变,其实对a,b是没有影响的,我们前面学习函数的时候说过(没看过的同学,可以去下面看看),这个复制是单向的,这种参数的传递方式为值传递。这样即使改变了A,B的值,a,b的值也不会发生变化。所以我们必须用到址传递。https://blog.csdn.net/2305_81151565/article/details/136766603?spm=1001.2014.3001.5501        

对象和地址

首先我们可以理解为指针就是地址,地址就是指针,这样对我们学习指针可能有所帮助,每当我们遇到指针这两个字的时候,就在心里默想它就是地址。首先我们来看看‘&’ 这个操作符,它的名字叫取地址操作符,是一个单目操作符。这个操作我我们从开始学习C语言就遇见过了,当我们需要从键盘输入一个字符或者数字时,使用scanf函数的时候就会用到取地址操作符。取地址运算符&的功能是取得对象的地址。表示对象地址的转换说明为%p。(p就是指针英文pointer的首字母)

这个是在X86(32位)环境下得到的,可以发现a与b之间相差4,16进制的C代表12。

地址

首先 ,我们这样理解地址,我们可以想想一下我们的宿舍楼,每个寝室都一个门牌号,我的寝室的门牌号是463,就代表了四楼63号房间,463就是我们宿舍的地址,就跟我们上网买东西一样,订单上面要写上我们的收货地址,这个地址就是我们的家。同学来我们家玩,你可以告诉他你家的地址,这样他就可以通过地址找到你。而C语言中就是通过指针(地址)来找到我们定义的变量的,每一个变量在定义的时候就会向内存申请空间,就是地址。

指针运算符

在显示的地方,就要用到叫做指针运算符单目操作符*了。将指针运算符*写在指针之前,就可以显示指针指向的内容。

int main()
{
	int a = 10;
	int* p = &a;
	printf("a=%d \np=%X\n*p=%d", a, p, *p);
	return 0;
}

可以看到*p和a的值是相等的,从上述代码可以看到,p是一个整形指针变量,它指向的地址是a的地址。

        可以看到整形变量a的地址是6FFCA4,里面存放是10,也就是a的值,而p是指针变量,里面存的是a的地址。这已经很好理解了,a是一个整形变量,它只能存进去整数。而p是一个整形指针,它的里面存的是整形变量的指针(地址)。我们通过* 对p储存的地址里的变量进行访问的操作叫做解引用,通过对p里面存放的地址间接对a里面储存的值进行修改。

        *p表示的就是a变量,因为p指向的是a变量。这就是通过指针实现的间接访问内存,所以称为间接运算符。

        关于指针变量空间的大小。定义指针变量以后,系统会为该指针变量分配存放一个地址值的储存单元,储存单元的大小与该指针指向内存空间无关,一般情况下,32位系统分配4个字节,64位系统分配8个字节,可以用sizeof计算指针变量所占空间大小。

void Swap(int *A, int *B)
{
	int tmp = *A;
	*A = *B;
	*B = tmp;
}
int main()
{
	int a = 10;
	int b = 20;
	printf("a=%d b=%d\n", a, b);
	Swap(&a, &b);
	printf("a=%d b=%d\n", a, b);
	return 0;
}

我们可以看到和开头的代码比较,这次的a,b的值被修改了。因为我们这次传进去的是地址,通过地址去访问a,b的值,就能够从根本上去把他们修改,就相当于我们从a,b的家里把a送进了b的家里,把b送进了a的家里,这个时候它们两个的值就会被修改了。这种方式叫做传址调用,前面那种代码方式叫做传值调用,A,B只是a,b的一个副本,跟a,b没有太大的关系。所以说我们在使用函数的时候,要想对某个数修改,就必须使用到指针。

而* 就好像是一把钥匙,p是a的地址,我们通过钥匙 *p打开了这个地址的门,然后找到了a,并对a进行一系列的操作,这样应该就能形象的表示指针的概念了吧。

空指针和void指针

空指针

        我们在指针变量定义的时候,如果没有初始化,指针变量就是未定义的,也就是这个指针很可能指向了没有使用权限的内存,程序可能就崩溃了。一般情况下,定义指针时要初始化。

        空指针常量是一个值为0的整数常量表达式,在头文件stdlib.h以及其他文件中,宏NULL被定义为空指针常量。在定义指针变量时,指针变量的值可以初始化为NULL,例如

int *p=NULL;

void指针

        指向void的指针,简称void指针。void指针通常指void*指针,表示未确定类型的指针,因为没有数据是void的,所以void*被称为万能指针。void指针指向一块内存,却没有告诉程序该用何种方式来解释这块内存。因此,不能用这种类型的指针直接获取所指内存的内容,必须强制转换成合适具体类型的指针才行。

        若想声明一个可以接受任何类型指针参数的函数,可以将所需的参数设定为void*指针,比如memeset函数,这是被包含在头文件string.h中,原型如下。

void    memset(void*s,int c ,size_t n);

该函数可以把c赋值到从s开始后的n个字节中。

需要注意的是c对应的是每一个字节,将每一个字节都改为c。

总结

指针就是内存的地址,指针变量就是储存内存地址的变量。指针变量可以存放基本类型变量的地址,也可以存放数组,函数以及其他指针变量的地址(后面我们会讲到)。

在编写代码的过程中,变量名一般表示的是数据本身,但这个变量也是有存储地址的,可以用取地址运算符&获得。

以上就是关于本人对指针的一些理解,如果还有需要改进的地方,请大家能够指出,一起学习进步。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值