本文为原创,欢迎转发!

最近在研读C primer plus 5版中文版,老外写的,还是很经典的,推荐给读者们,有需要的朋友可以在这里购买:C primer plus 5版中文版

指针,传说中是C语言中的一个难点,且是难点中的难点。本文在教材的基础上,再详细地谈谈“指针”这个东东,力争让大家能理解它。

一、指针的概念

关于指针的定义,很多教材一般给出“它是一个地址”,“存储的是变量的地址”,“指向了一个值”等等描述。这样描述其实也没错,但是就是不那么好理解。我觉得要理解指针,无需给出什么定义,只需讲透如下5个点,我认为基本就可以理解一个指针了。这5个点我总结如下:

1. 指针是一个普通的变量;

2. 既然指针是变量,那么肯定有自己的类型;

3. 既然指针是变量,那么肯定有自己的值;

4. 只不过指针的值跟一般变量的值不太一样,指针的值是一个“地址”。

5. 指针指向的数据

为了讲透这5个点,下面列举一段代码,如下。

二、代码来说明

请欣赏以下代码

#include <stdio.h>
#include <string.h> int main(void)
{
char string[15] = "ShiXP love C!";
char c = string[0];
char *pointer; pointer = &string[0];
printf("指针pointer的值是%p \n", pointer); for(int index = 0;index < strlen(string); index++)
{
printf("第%d个字符是:%c \n", index + 1, *(pointer + index));
} return 0;
}

运行结果是:

三、下面结合代码我来谈谈那5个点:

1. 指针是一个普通的变量

本例中,有一个字符变量“c”,它的值是string[0],也就是“S”,这个大家都很好理解。

还有一个指针“pointer”,注意,它也是一个变量,和字符“c”一样,就是一个普通的变量而已,它也有一个值,它的值是“&string[0]”,从运行结果来看,就是“0022FED9”,这是一个16进制的数。

2. 指针自己的类型

本例中,字符变量“c”的类型是“char”,数组string的类型也是“char”,那么指针“pointer”的类型也是“char”。不过与c和string的类型char相比,pointer类型的char却有一点小区别。

变量c的类型char说明了c的值“S”是一个字符数据,数组string的类型char说明了其每一个数组元素也是字符数据,但是指针pointer的类型char是不是也说明“0022FED9”是一个字符数据呢?傻子都知道当然不是啦!那么pointer的char类型到底是在说谁呢?这就是指针的一个诡异的地方。等讲完第5点指针指向的数据你就知道了。

3. 指针自己的值

上面已经说了,指针既然也是一个变量,那么肯定有自己的值,在本例中,指针自己的值就是“0022FED9”,是一个16进制的数,这个值哪来的?是“&string[0]”赋予给指针的。

“0022FED9”这个东东也是很多教材中提到的“地址”。很多人会想,你告诉我“0022FED9”是一个值我还好理解,你告诉我它还是一个什么地址,这就让人晕菜了,下面第4点就来说说这个“0022FED9”。

4. 指针的值

不知大家发现没有,在C程序中,如果定义了int,char等变量,那么在代码中很多地方都会用到这些变量的值。比如在本例中,定义了数组string,则接下来的代码就用到了数组的元素,也就是printf函数输出来。如果定义了一个指针变量,可能大家很少看到在代码中会用到指针的值,比如在本例中,大家就没有看到用到“0022FED9”。

确实,相比一般类型变量的值被频繁使用而言,指针的值很少会被直接用到。注意,这里说的很少被直接用到,是指写代码的人,也就是程序猿会很少用到,但有一个角色用指针的值用的非常多,就是操作系统。

比如在本例中,输出数组的每一个元素时,我表面上是用的*(pointer + index)来输出的,其实在背后,操作系统在执行这个语句时,都是利用指针的值“0022FED9”来找到数组的每一个元素的,所以程序最终能正确输出数组的每一个字符。

上面也说了,“0022FED9”是被系统用的最多,为啥被系统用的最多呢?因为“0022FED9”是一个地址,是string数组的第一个元素“S”的地址。说的再通俗一点,字符“S”放在一个大小为1BYTE的内存块里,这个内存块的地址就是“0022FED9”。

5. 指针指向的数据

在第4点说到,字符“S”放在一个大小为1BYTE的内存块里,这个内存块的地址就是“0022FED9”,那么,我们就说,指针“pointer”的值是“0022FED9”,在地址为“0022FED9”的地方放了一个字符“S”,这个“S”就是指针“pointer”指向的数据,且通过“*pointer”这种写法来获取“S”,从某种意义上来说:

pointer 等于 0022FED9;

*pointer等于“S”,加上*号,就是直捣黄龙,拿到“S”。

此时我们可以说说第2点中提到的指针的类型是来修饰谁的问题了。在本例中,pointer的类型char显然不是来修饰“0022FED9”的,它是来告诉操作系统,我pointer认为“0022FED9”这个地方存放的是字符,是字符,是字符,且占1个BYTE的大小。

如果pointer的类型改为int,我pointer就认为“0022FED9”这个地方存放的是整数,是整数,是整数字符,且占4个BYTE的大小。

C语言指针专题——如何理解指针的更多相关文章

  1. C语言指针专题——为何要学习指针

    欢迎转发本文! 之前的文章与各位谈论了指针是什么,以及指针为何这那么难学.不少知友留言说看了我的文章对指针了解了不少,这给我继续创作提供了莫大的动力啊.指针其实就是一个纸老虎,你看着可怕,等你了解其本 ...

  2. C语言指针专题——序

    看到好多的C语言初学者学到指针时,都觉得指针怎么那么难啊!我也想起了我当时学习指针时遇到的困难,确实很难!到底是教程写的不好呢,还是老师教的不好呢?我觉得都有. 网上搜索指针讲解的资料很多,我也看了不 ...

  3. 深入理解C语言中的指针与数组之指针篇

    转载于http://blog.csdn.net/hinyunsin/article/details/6662851     前言 其实很早就想要写一篇关于指针和数组的文章,毕竟可以认为这是C语言的根本 ...

  4. 深入理解C语言中的指针与数组之指针篇(转载)

    前言 其实很早就想要写一篇关于指针和数组的文章,毕竟可以认为这是C语言的根本所在.相信,任意一家公司如果想要考察一个人对C语言的理解,指针和数组绝对是必考的一部分. 但是之前一方面之前一直在忙各种事情 ...

  5. C语言一维指针的深入理解

    指针是C语言中广泛使用的一种数据类型.运用指针编程是C语言最主要的风格之一. 利用指针变量可以表示各种数据结构:能很方便地使用数组和字符串:并能象汇编语言一样处理内存地址,从而编出精练而高效的程序.指 ...

  6. C语言指针专题——指针怎么就很灵活?

    最近在研读 C Primer pkus(第五版)中文版,老外写的还是很经典的,推荐给朋友们,购买地址:C primer plus 5版中文版购买 另外再推荐两本书: 1. 2017年9月全国计算机二级 ...

  7. C语言指针专题——指针难学的4点原因

    前一篇跟大家聊了聊指针的概念,可是就算了解了指针是什么,为什么依然感觉难学?我试着从几个点切入,聊聊指针难学之处. 文末会给大家推荐几本书,有需要的朋友可以看看! 难点1. 讨厌的星号 定义指针变量p ...

  8. C语言的指针移动怎么理解

    C Primer pkus(第五版)中文版,老外写的还是很经典的,推荐给朋友们,购买地址:C primer plus 5版中文版购买 另外再推荐本书: 程序员面试宝典(第5版)第五版:程序员面试宝典( ...

  9. 深入理解C语言-深入理解指针

    关于指针,其是C语言的重点,C语言学的好坏,其实就是指针学的好坏.其实指针并不复杂,学习指针,要正确的理解指针. 指针是一种数据类型 指针也是一种变量,占有内存空间,用来保存内存地址 指针就是告诉编译 ...

随机推荐

  1. WPF的点击穿透

    1.background 为{x:null} 或  鼠标点击会穿透,如果不想让一个透明的border点击穿透,设置透明色Transparent时就可以点到这个看起来透明的border 2.当依赖属性I ...

  2. volatile变量理解 via《Java并发编程实战》

    第3章:对象的共享 volatile关键字的理解 volatile变量,用来确保将变量的更行操作通知到其他线程.当变量申明为volatile类型后,编译器与运行时都会注意带这个变量时共享的,因此不会将 ...

  3. Java Web系列:Spring Boot 基础 Spring Security基本使用

    @OneToOne or @ManyToOne Caused by: org.hibernate.AnnotationException: @OneToOne or @ManyToOne on com ...

  4. windows qt 使用c++ posix接口编写多线程程序(真神奇)good

    一.多线程是多任务处理的一种特殊形式,多任务处理允许让电脑同时运行两个或两个以上的程序.一般情况下,两种类型的多任务处理:基于进程和基于线程.基于进程的多任务处理是程序的并发执行.基于线程的多任务处理 ...

  5. Qt项目里的源代码默认都是Unicode,原因大概是因为qmake.conf里的定义

    MAKEFILE_GENERATOR = MINGWQMAKE_PLATFORM = win32 mingwCONFIG += debug_and_release debug_and_release_ ...

  6. C#调用Delphi Dll返回字符串的示例(使用Move才能拷贝字符串)

    //----------------------Delphi------------------- procedure GetSqlData(ASource: PChar; ADest: PChar; ...

  7. 插件化二(Android)

    插件化二(Android) 上一篇文章<插件化一(android)>里大概构思了下插件加载与校验的流程和一些大体设计,这次就具体展开,在<动态加载与插件化>里提到以apk形式开 ...

  8. Windows下OSGEarth的编译过程

    目录 1. 依赖 1) OpenSceneGraph 2) GDAL 3) CURL 4) GEOS 5) 其他 2. 编译 1) 设置参数 2) 配置路径 3) 生成编译 3. 参考文献 1. 依赖 ...

  9. Git 所有常用命令

    写的很细致,存: https://blog.csdn.net/Mr_Lewis/article/details/85547057

  10. 【dockerFile配置jvm 启动参数】dockerFile 参数解释

    最近比较忙,实际也没有用得上.仅仅记录几个链接: Dockerfile reference:https://docs.docker.com/engine/reference/builder/#usag ...