C语言——一级指针初识

指针的定义

C语言里,变量存放在内存中,而内存其实就是一组有序字节组成的数组,每个字节有唯一的内存地址。CPU 通过内存寻址对存储在内存中的某个指定数据对象的地址进行定位。这里,数据对象是指存储在内存中的一个指定数据类型的数值或字符串,它们都有一个自己的地址,而指针便是保存这个地址的变量。也就是说:指针是一种保存变量地址的变量

指针的大小只和操作系统有关,在86位操作系统下的指针大小位四个字节,在64位操作系统下为八个字节

例如我们想用函数封装的形式来实现一个两数交换的功能

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
void swap(int a, int b) {
	int temp = a;
	a = b;
	b = temp;
}
int main() {
	int a = 1;
	int b = 2;
	swap(a, b);
	printf("%5d%5d", a, b);

}

那么这个函数会打印出 a b的值为多少呢

我们运行这个程序,得到结果

 可以看到,a为1,b为2,显然两者并没有发生交换,main函数内部没有问题,那么问题就出在了swap函数中,我们输入的参数是元素 a,b。他们的值分别为1,2,在函数内部完成交换后,swap函数的类型为void,因此没有返回值,也就是说在执行完这个交换功能之后,开辟的内存空间就消失了,那么交换后的值也没有保存到a,b当中,通俗的来说就是main函数和swap函数自己干了自己的事,两者用了两块地方,之间除了参数没有别的联系。

那么修改的办法就显而易见了,我们需要让main函数和swap函数共同使用一块内存空间,这样即使swap函数执行完之后,交换后的值已经保存到a,b当中,从而完成了a,b交换的功能。那么我们如何让这两个函数访问同一个内存空间呢,这里我们就要用到指针。

 我们通常这样定义指针

int *p=&a

*代表了这是一个指针变量,其指向的是int类型变量a的地址

我们通过访问p就可以得到a的地址,从而就可以实现在同一个内存空间上完成对a的相关操作

在具体应用指针之前,我们还要了解一个重要的概念——解引用

"*"的作用是引用指针指向的变量值,引用其实就是引用该变量的地址,"解"就是把该地址对应的东西解开,解出来,就像打开一个包裹一样,那就是该变量的值了,所以称为"解引用"。也就是说,解引用是返回内存地址中对应的对象。

比如int a=10; int *p=&a; 前文说到,p指向了int类型变量a的地址,那么*p就指向了int类型变量a的值

也就是说 *p=10

接下来我们就可以使用指针完成上述操作了,那么联系这两个函数的是形式参数和实际参数,因此我们就要在这里就行修改

void swap(int* p, int* q) {
	int temp;
	temp = *p;
	*p = *q;
	*q = temp;
}
int main() {
	int a = 10;
	int b = 20;
	swap(&a, &b);
	printf("%5d%5d", a, b);

}

可以看到我们传入的实际参数为a,b的地址,然后用指针变量接收,再在函数内部解引用,再进行交换操作,从而完成了函数功能的实现

 这里就正确实现了函数功能

接下来就涉及到了当指针指向的数据存入内存中时,它是一种怎么样的形式呢

我们这里就要了解一个新的知识点,Windows数据存储的小端模式

比如说十进制数20在内存中以上16进制存储的,同时是四个字节,那么他在内存中的应该是以

00000014存储的,但是实际上,它在内存中是以14000000存储的

这是为什么呢,首先main函数会开辟一个栈,然后从高地址往低地址

 又因为存储方式是小端存储

数据的低位放在低地址空间,数据的高位放在高地址空间
简记:小端就是低位对应低地址,高位对应高地址

读取数据的时候是从低地址开始读取,所以在内存中显示出来的是14000000

最后要说的就是关于指针的运算

 p + n   ——>
      p向高地址偏移 n*sizeof(元素类型)
      int *p = arr;   //&arr[0]
      p+1             //&arr[1]  <=>  p+1
      *(p+1)  ->  arr[1]
      p+3   -> &arr[3]
      *(p+3) -> arr[3]  

 

 加括号的原因是*与+的优先级问题

这里还涉及到了*号的各种用法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值