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、:一般用来表示继承;

 

已标记关键词 清除标记
相关推荐
一、C语言自我YY<br /> 1)、C语言是许多高级计算机语言的基础,学好C语言能更好的学习其他高级语言,为以后的学习打基础;往深学C语言的话那就是学到C在Linux里的应用,Linux十分强大。<br /> 2)、C语言是一种计算机程序设计语言。具有高级语言的特点,又具有汇编语言的特点。C语言可作为工作系统设计语言,编写系统应用程序,也可以作为应用程序设计语言,编写不依赖计算机硬件的应用程序。<br /> 3)、应用范围广泛,具备很强的数据处理能力,不仅仅是在软件开发上,而且各类科研都需要用到C语言,适于编写系统软件,三维,二维图形和动画。具体应用比如单片机以及嵌入式系统开发。<br /> 4)、C语言是面向过程语言,C语言通过windows/linux平台下编译的,是直接运行在windows/linux平台下的,而XX始终是运行在他的虚拟机之上的;所以理论上C语言能做一些相对于比较底层的工作,像XX就不能编写Windows病毒。<br /> 5)、如果要利用编程来做一些windows优化工作的话,建议还是利用C语言。C语言是目前世界上流行、使用最广泛的高级程序设计语言<br /> 6、很多编译器,几乎所有操作系统Windows,Linux,Unix的大部分代码都是C,C在背后做了很多东西的,也许开发游戏用C++,安卓用XX更为合适,图形界面的用其他语言开发效率更高一些(因为他们封装了很多东西),但同样的原因导致略微接近底层的功能其他语言根本干不了!Windows的API都是按照C语言的格式给的,这也很能说明问题!嵌入式开发更是离不了C语言!纵观电脑发展几十年,C语无所不能呀!
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页