深入理解指针(1)

简介: 深入理解指针(1)

1.指针是什么

在理解指针是什么之前,我们首先要知道在计算CPU处理数据的时候,需要从内存中读取数据的,处理后的数据也会放回到内存中,那这些内存空间如何高效的管理呢?

其实是把内存分为一个一个的单元,每个单元的大小是一个字节,其中,每个单元中相当于一个八人间宿舍,每个人就是一个比特位,宿舍的房间号就是地址,而在计算机中房间号就相当于指针。

所以我们可以理解为:内存单元编号==地址==指针。


2.指针变量和地址

2.1取地址操作符(&)

在c语言中我们创建变量就是向内存申请空间,比如:

#include <stdio.h>
int main()
{
  int a = 10;
  return 0;
}


上面代码中我们向内存申请了4个字节的空间,用来存放整数10,其中每个字节都是有地址的。那么我们怎样去得到这4个地址呢?


这里我们就需要学习一个操作符(&)--取地址操作符

#include <stdio.h>
int main()
{
  int a = 10;
   
  printf("%p ", &a);
 
  return 0;
}


baf9fec641ac4c43b1c5d09cc73ef884.png

这里取出来的是a所占4个字节中最小的一个,所以另外三个字节我们也可以顺藤摸瓜得到

00D3FCC9,00D3FCCA,00D3FCCB


2.2指针变量和解引用操作符(*)

我们取出来的地址是一个数值,比如:00D3FCC8。这个数值有时候也是需要存储起来的,那么存储到哪里呢?答案就--指针变量。比如:

#include <stdio.h>
int main()
{
  int a = 10;
   
  printf("%p ", &a);
 
  int* p = &a;
 
  return 0;
}


指针变量也是⼀种变量,这种变量就是用来存放地址的,存放在指针变量中的值都会理解为地址。

我们已经把a的地址给取出来放进指针变量p中了,那么当我们如何通过指针去对a里面存放的数据进行操作呢?这就需要我们再学习一个--解引用操作符(*)。比如:

5faba1d5113741c9a500219c629b5765.png


2.3指针变量的大小

指针变量既然能够用来存放地址,那么说明它也是有大小的。

32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产生的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4 个字节才能存储。

如果指针变量是用来存放地址的,那么指针变的大小就得是4个字节的空间才可以。

同理64位机器,假设有64根地址线,⼀个地址就是64个⼆进制位组成的⼆进制序列,存储起来就需要8个字节。

所以指针变量的大小跟它存放的数据以及本身的类型无关,只与平台环境有关。


3.指针变量的类型和意义

上面我们介绍的内容中只给出了整形的例子,那么如果我们想要创建一个指针变量来存放其他类型的数据其实也是一样的。比如:

字符型指针:char* p=地址

浮点型指针:flaot* p=地址

其中p只是指针名,可以是任意取的,去掉指针名之后就是指针的类型,比如:

字符型指针类型:char*

浮点型指针类型:flaot*


3.1指针的类型的意义

我们知道整形指针在32位平台下占4个字节,那么如果我们用字符指针去存放一个整形数据,再去利用指针去修改这个数据的时候,只能够修改一个字节,而如果用整形指针去存放,利用指针去修改数据的时候就修改4个字节。所以指针的类型决定了我们对指针进行修改数据和进行运算时能有多大的权限(⼀次能操作几个字节)。


3.2指针+-整数

我们先来看一段代码:

#include <stdio.h>
int main()
{
  int n = 10;
  char* pc = (char*)&n;
  int* pi = &n;
 
  printf("%p\n", &n);
  printf("%p\n", pc);
  printf("%p\n", pc + 1);
  printf("%p\n", pi);
  printf("%p\n", pi + 1);
  return 0;
}


运行结果:

b53df96bdb2f43ae93b0b74c6e8cc533.png

我们可以看到,对不同类型的指针进行+-相同的整数,他们+-的大小不一样,对char*类型指针变量跳过了一个字节,对int*类型指针变量跳过了4个字节,其实就是上面说过的,指针类型决定了指针向前或者向后走一步有多大(距离)。

目录
相关文章
|
10月前
|
XML JSON Kubernetes
什么是 YAML?:一种简洁高效的数据序列化格式
什么是 YAML?:一种简洁高效的数据序列化格式
1426 0
【数据结构】遍历二叉树(递归思想)-->赋源码
【数据结构】遍历二叉树(递归思想)-->赋源码
109 4
|
Python
Python中有效地使用global和globals()来管理全局变量
Python中有效地使用global和globals()来管理全局变量
323 1
|
机器学习/深度学习 数据可视化 数据挖掘
PyTorch Geometric (PyG) 入门教程
PyTorch Geometric是PyTorch1的几何图形学深度学习扩展库。本文旨在通过介绍PyTorch Geometric(PyG)中常用的方法等内容,为新手提供一个PyG的入门教程。
PyTorch Geometric (PyG) 入门教程
|
消息中间件 算法 安全
RTOS实时操作系统中RT-Thread、FreeRTOS和uCOS 选择哪一个学习比较好?
RTOS实时操作系统中RT-Thread、FreeRTOS和uCOS 选择哪一个学习比较好?
|
SQL 缓存 网络协议
利用QT实现多平台数据互通
利用QT实现多平台数据互通
388 0
|
设计模式 算法 Java
【数据结构和算法】移动零
给定一个数组nums,编写一个函数将所有0移动到数组的末尾,同时保持非零元素的相对顺序。请注意,必须在不复制数组的情况下原地对数组进行操作。 进阶:你能尽量减少完成的操作次数吗?
155 3
|
存储 C语言
手撕双链表 1
手撕双链表
88 0
|
网络协议 网络虚拟化 网络架构
什么是IGMP?IGMP与ICMP有啥区别?
IGMP 代表 Internet 组播管理协议,是 IPv4 网络上的主机和相邻路由器用来建立多播组成员资格的通信协议,当多播主机希望加入特定多播组并开始接收组流量时,IGMP 消息主要用于向其本地多播路由器发送信号,IGMP有三个版本:版本1、版本2、版本3。
1148 0
什么是IGMP?IGMP与ICMP有啥区别?