首先,我们来看一看指针有什么用?

讲道理的话,如果你到目前没有发现指针有什么用,那就不用,挺好的。

你看C++程序员做个软件也基本不会把C++的语言特性都用上是吧。你有数组,有结构体,有函数,什么事情做不成呢?

是吧。直到有一天,你遇见了这样一个问题:试编写一个函数swap(x, y)使得其能够交换x和y两个变量的值这个……

很简单嘛。我开始写:

void swap(int x, int y)

{

int tmp = x;

x = y;

y = tmp;

}

然后你调用一下,发现……咦,怎么没用。

啊啊啊啊啊!好难过好难过,怎么回事?

你上网求助,发现大神们告诉你要用指针写,像这样:

void swap(int * x, int * y)

{

int tmp = *x;

*x = *y;

*y = tmp;

}

然后调用的时候swap(&a, &b);就行了。

哇啊啊啊好神奇!

于是,指针的第一个用处出来了:它能使得函数有能力交换两个变量的值。

怎么做到的呢?我们来看看。

我相信你已经知道了,每一个变量都有属于自己的一块空间,那这块空间在哪里呢?

答案是:内存,哦不!准确一点说是虚拟内存 (Virtual Memory) 里。

那计算机怎么知道我要找的是变量b的空间而不是a的空间呢?

是因为每一个变量所属的空间都有一个惟一的地址,计算机只要通过这个“地址”,就可以找到里面的值了。

这种根据一个地址就能直接访问到一块内存空间的方式,我们叫做随机读取。

具体它是如何做到的,可以去看看Charles Petzold的《编码》一书,里面甚至从最基本的电路一步一步讲起,构造一台最基本的计算设备。

还有一个问题是,如果我的变量占有多个空间(字节),但是一个地址只能对应一个空间,那我们又有两个问题:如果我们要用一个地址代表整个变量所占的内存空间(假设4个字节),我这四个空间是从前向后排还是从后向前排?比方说我变量的值是AE 01 08 82,那我在内存里从前向后的排序到底是82 08 01 AE还是AE 01 08 82?我怎么知道我叫这个名字的变量占几个空间?第一个问题显然又是信仰之争。所谓从前向后的,我们叫做大端序 (big-endian);另一种,我们叫做小端序 (little-endian),大端序与小端序的转换在网络传输的时候会用到,Intel的CPU大多采用的都是小端序。

而第二个问题,由于C里每个变量都有自己的类型,所以编译器会根据不同类型的各自尺寸生成相应的代码。说这么多干什么呢?

只是为了让你更好地明白,你在程序里定义的变量乃至函数代码,全都是存储在随机存储器(内存)里的。

每个变量都有自己的起始地址,即属于自己的一块位置。那指针是什么呢?指针当然也是变量咯,指针也跟其他类型的变量一样,有自己的一块空间,空间里的二进制位构成了一个值。

这个值可以是任意的,你甚至可以把它当作整数来用。(没记错的话,指针的本质类型应该是unsigned long。即无符号的长整形数据)

而指针跟其它变量类型的根本性不同在于,它有一个取值的运算符,即*符号。

因为它可以取值,所以指针类型的变量就不仅可以有自己的值,也可以“操纵”其它变量的值了。

无论是多么复杂的指针,本质上它们的存在都跟这个*操作有关。回到我们开始说的那个swap函数。

为什么第一种写法无法达成交换两个变量值的效果?

原因跟指针无关,跟函数参数的传递方式相关。原因可以用一句话来解释:你的swap函数里出现的x和y,跟你传参数进去时候的a和b,根本没有指向同样的内存地址。

当函数调用的时候,a和b被复制了一份给了x和y变量。

你在swap函数里对x和y进行的所有操作,都是对这两块新的内存地址里的值进行操作,影响不到a和b的内容。你不是没有交换东西,只是被交换了的x和y在swap函数调用结束之后空间就被回收了而已。(回收的概念如果不懂得会可以理解为销毁)

这种“把传进去的参数复制一份”的方式叫做值传递。

而在其他一些语言比如C++或者Visual Basic里面,还存在一种传参数的方式叫引用传递,即函数里面的参数和传进去的参数,指向同样的内存地址。(引用的传递是在C++;里面有的,纯C语言没有)

在纯C里面,我们不存在引用传递,因此要模拟引用传递的效果,只能用指针来实现。

第二个函数调用的方法有点不太一样,是swap(&a, &b),比起上一个版本多了&符号。这个符号的意思是“取地址”,函数的形式参数是两个指针,在调用的时候本质上也是值传递,只不过这次复制的不是a和b的值,而是a和b的地址。

在函数内部,我的x和y两个指针也是两块独立的空间,有各自的内存地址。

只是它们的值对应了a和b两个变量的地址,所以我用*操作,就可以完成“操控

c语言指针概述,C语言指针概述.doc相关推荐

  1. C语言二级指针 (清晰易懂 图解概述)

    二级指针:指向指针的指针: 对二级指针进行一次解引用整形输出为被指向指针的地址; 对二级指针进行两次解引用,整形输出为被指向一级指针指向的地址的值; (一级解引用为所指一级指针所指的地址,二级解引用为 ...

  2. c语言 字母 八进制表示'/1011',C语言C语言第一课:C语言概述为什么学习C语言怎样学习C语言.DOC...

    [摘要]C语言 第一课: C语言概述 为什么学习C语言 怎样学习C语言 参考资料 ----------------------------------------------------------- ...

  3. 黑马程序员C语言基础(第六天)指针

    https://www.bilibili.com/video/BV1jW411K7v2/?p=70&spm_id_from=pageDriver 文章目录 指针 概述 内存 物理存储器和存储地 ...

  4. c语言通过指针变量输出10个元素,C语言程序设计第2版指针程序设计(10页)-原创力文档...

    C 语言程序设计 - 理论方法与实践(第 2 版) 7.4.1 简单指针变量作函数参数 例 7-9 用比较交换法 ,将一维数组的最 大值移到数组的最 末元素位置,交换 过程用上述 swap() 函数实 ...

  5. C程序设计语言现代方法12:指针和数组

    目录 1. 指针的算术运算 1.1 概述 1.2 C语言支持的算术运算类型 2. 指针的比较 3. 指针用于数组处理 4. 数组名与指针 4.1 用数组名作指针 4.2 数组取下标操作 4.3 惯用法 ...

  6. C语言学习1——C语言概述

    一.C语言概述 1. C语言历史 1.1 1960年 ALGOL 60 面向问题,离硬件较远,不适合系统程序 1.2 1963年 CPL语言 接近硬件,但太过复杂,难以实现 英国剑桥大学 1.3 19 ...

  7. c语言程序设计 指针 .ppt,C语言程序设计 指针.ppt

    C语言程序设计 指针.ppt 第6章 指 针,C 语言程序设计,北京科技大学 计算机系,2018/8/156.1 概述6.2 指针和指针变量6.3 指针与数组6.4 指针和函数6.5 动态存储分配,第 ...

  8. C语言显示无法添加两个指针,【C语言】两个指针(地址)相减

    两个指针相减,为两个指针之间间隔这两个指针类型的数目. 如:int *p,*q; p-q=(p地址-q地址)/sizeof(int) #include int main() { int a[]={,, ...

  9. 聊城大学c语言实验报告,c语言程序设计(包云)c第1章概述.ppt

    c语言程序设计(包云)c第1章概述.ppt C语言程序设计,讲授包云 单位聊城大学计算机学院,第1章 C语言概述,3,主要内容,1.1 什么是计算机程序 1.2 什么是计算机语言 1.3 C语言的发展 ...

  10. 【C语言】深入浅出理解指针及内存与指针的关系(详细讲解+代码展示)

    目录 概述 内存 内存含义 内存作用: 物理存储器和存储地址空间 物理存储器:实际存在的具体存储器芯片. 存储地址空间:对存储器编码的范围. 内存地址 指针和指针变量 指针基础知识 指针变量的定义和使 ...

最新文章

  1. Windows异常学习笔记(四)—— 编译器扩展SEH
  2. 前端学习 -- 颜色
  3. js页面排序-----基础篇
  4. Amazon Personalize:帮助释放精益数字业务的高级推荐解决方案的功能
  5. mft按钮设计_哈汽机组660MW超临界空冷机组ETS设计及逻辑说明
  6. Magento Helper简介
  7. 使用PostgREST的RestAPI操作之管理与优化
  8. android space边框,Android中的图片视图的边框?
  9. 简述冯诺依曼体系结构计算机的工作原理。
  10. 阿里 3月25日 二维矩阵列选元素最小和
  11. 电脑上面的word文档被删除了怎么办?分享四种亲测恢复方法
  12. Sql server 双机热备份数据库
  13. 免费听歌下载歌曲的几个网站
  14. matlab正弦波占空比怎么调,matlab实现可调节占空比的方波
  15. 塞班专用签名工具_Symbian平台的开源Web开发工具
  16. Odoo与浪潮合资研发PS Cloud之如何处理序列号
  17. 最新的AS下载地址,更新及时
  18. CAP理论为什么不能同时满足
  19. (2021)Top5 免费视频编辑软件,视频剪辑必备工具
  20. 用户使用手册与测试报告(团队作业)

热门文章

  1. view桌面池计算机显示错误,学员问答之3-View桌面问题
  2. java复制图片实现方法
  3. JAVA-封装-静态属性
  4. C++创建 可以实例化但不能继承的类
  5. 文本分类 特征选取之CHI开方检验
  6. 获取 GPG 密钥失败:[Errno 14] 2011-05-26 14:43
  7. UA OPTI501 电磁波 Lorentz Oscillator Model 1 Drude-Lorentz模型
  8. EasyUI datagrid控件的基本使用
  9. idea创建、运行、打包控制台程序
  10. 操作系统机制学习总结