C语言指针简介

指针基础

首先引用一篇知乎的链接,介绍的挺好的:https://www.zhihu.com/question/24466000/answer/27893272

对于程序员来说内存可以简化成这样一种东西:

你可以把它想象成一条无限长的纸带。纸带上边有一个个的小格子,每个小格子正好是一字节,里边能够存放一个数字。计算机的工作就是对这些小格子里的数字做处理。虽然你在电脑上能够看视频、听音乐,但这些东西本质上都是存在内存这条纸带上的数字。

对于纸带上的每个小格子来说能够采取的操作只有两种「读取」和「写入」。每次执行操作时都必须要指明对于哪一个格子进行操作,为了方便起见人们就给这些格子编了号。如上图所示,第一个就是0号,第二个是1号以此类推(前边的0x代表是16进制的意思)。而这些编号就是我们所说的指针的内容,指针变量里边所记载的就是这些编号。但为什么我们平时看到的指针值都是类似于0xa2cf23c3d这种呢?这是因为,内存非常之大,作为编号的数字也非常大。所以看是来就像是神秘代码一样。

举个例子:

unsigned char a = 1; // unsigned char 类型占一个字节
unsigned char* b = &a; // &a 代表的就是得到变量a所存储的那个小格子的编号。
             // 赋值给变量b后,b格子里存的就是a格子的编号。
printf("%d", *b); //输出1,*b代表的是看看b格子里存储的编号所代表的格子里存的数是什么。

上边代码中的内容变成纸带就是:


ok,如果你觉得这个太简单,我们现在可以深入到一些更加复杂的概念——指针的指针。例如下边的代码:

unsigned char a = 1;
unsigned char* b = &a;
unsigned char** c = &b;

上文中我们提到指针就是格子的编号,那么指针的指针是什么呢?就是指针变量所在格子的编号。如图:

至于什么指针的指针的指针,以此类推。有 时候人们会把这种关系视作是一种指向关系。所以当人们说一个指针指向某个变量时,他们指的是这个指针变量的值是某个变量的格子编号。

 

但是这里有个问题,前文说到 ,每个格子只有一个字节。有些类型的变量需要多个字节来存储,比如int型就需要4个字节(不同平台长度不一致,这里假定是4个)。如果我有一个int型的变量a存在0x01号地址,我必须有方法告诉程序后边的三个格子也是这个变量值的一部分。

为了解决这个问题人们引入了指针类型的概念,对于int型的指针他表示的是从当前格子开始共4个格子都是该变量的值,而对于unsigned char型则只表示当前的格子。例如:

unsigned int c = 257;
unsigned int* a = &c;
unsigned char* b = (unsigned char*)&c;  //必须强制转换一下

printf("%d", *a); // 输出 257
printf("%d", *b); // 输出 1

 

C++ Null 指针

在变量声明的时候,如果没有确切的地址可以赋值,为指针变量赋一个 NULL 值是一个良好的编程习惯。赋为 NULL 值的指针被称为指针。

NULL 指针是一个定义在标准库中的值为零的常量。请看下面的程序:

#include <iostream>

using namespace std;

int main ()
{
   int  *ptr = NULL;

   cout << "ptr 的值是 " << ptr ;
 
   return 0;
}

当上面的代码被编译和执行时,它会产生下列结果:

ptr 的值是 0

在大多数的操作系统上,程序不允许访问地址为 0 的内存,因为该内存是操作系统保留的。然而,内存地址 0 有特别重要的意义,它表明该指针不指向一个可访问的内存位置。但按照惯例,如果指针包含空值(零值),则假定它不指向任何东西。

如需检查一个空指针,您可以使用 if 语句,如下所示:

if(ptr)     /* 如果 p 非空,则完成 */
if(!ptr)    /* 如果 p 为空,则完成 */

因此,如果所有未使用的指针都被赋予空值,同时避免使用空指针,就可以防止误用一个未初始化的指针。很多时候,未初始化的变量存有一些垃圾值,导致程序难以调试。


->

“->”是一个整体,它是用于指向结构体子数据的指针,用来取子数据。

换种说法,如果我们在C语言中定义了一个结构体,然后申明一个指针指向这个结构体,那么我们要用指针取出结构体中的数据,就要用到“->”。

问题中的p=p->next ,意思是将p指向的一个结构体实例中的自数据next赋值给p。

 

 

image.png

C语言中“.”与“->”有什么区别?

首先 a->b 的含义是 (*a).b ,所以他们是不同的

 

  在学习C++的过程中我们经常会用到.和::和:和->,在此整理一下这些常用符号的区别。

    1、A.B则A为对象或者结构体;

    2、A->B则A为指针,->是成员提取,A->B是提取A中的成员B,A只能是指向类、结构、联合的指针;

    3、::是作用域运算符,A::B表示作用域A中的名称B,A可以是名字空间、类、结构;

    4、:一般用来表示继承;

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值