免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: 无风之谷
打印 上一主题 下一主题

对C语言指针的讨论:应当如何理解、使用指针?《狂人C:程序员入门必备》有奖试读 [复制链接]

论坛徽章:
0
371 [报告]
发表于 2011-01-07 21:51 |只看该作者
指针就是一个内存块的地址 指针的指针就是某个内存块的地址的内存块的地址................

论坛徽章:
0
372 [报告]
发表于 2011-01-09 12:13 |只看该作者
本帖最后由 KBTiller 于 2011-01-09 14:33 编辑
计算机科学用一个词概括就是'抽象'。

C是对汇编的抽象, 通过指针获得想要的变量值本质上就是汇编中寄存器的相对寻址方式的一种抽象。
指针的值实质上就是内存中某个单元的编号,这就是地址,但是得到这个地址以后,怎么用依赖于这个指针变量的声明类型。

打个不恰当的比方,
大楼里面每户人家在底楼都有自己的信箱,信箱好比就是指针,信箱上面的编号就是地址
我订了一份报纸,每天早上我去拿, 我得先知道自己信箱的编号,找到自己的信箱,然后再拿,这就好比是通过指针获得想要的变量值。
当然每次打开信箱,我还可能拿到的是信,明信片,包裹,广告, 这就是void类型的指针,不能事先确定你要拿到的东西的类型。
假如寄给你挂号信,你不在家,邮递员会给你留个条子,让你去附近的邮局去取, 你拿到的这个条子其实也是起的指针的作用,这就是指向指针的指针。
假如你取到的是一份菜谱, 你照着他上面的说明,开始学做菜,这就好比是函数指针。
klose911 发表于 2010-12-16 09:50

比喻很生动
只是有一点
信箱大小都是一致的
而指针所指向的“箱子”的大小可能不一样,箱子里的内容的性质也不一样,但统一都用起始位置编号

论坛徽章:
0
373 [报告]
发表于 2011-01-09 23:02 |只看该作者
回复 365# KBTiller


    (很多人不理解数据类型的重要性,这是我强调C语言源代码中没有地址的一个重要原因。
我的看法,不懂数据类型就不懂得编程
不懂指针,就不懂得C
不懂指针的类型,就等于连指针的皮毛都不懂

===>没有看过c99什么的,以下完全是凭经验和认识来分析!
1.数据类型的重要跟C有没有地址是两回事情:
数据类型是对内存种种数据的应用意义来认定的,同一个数据,可以通过转化定义为不同的使用意义,这个完全是认为抽象的;
地址是对内存如何索引这个角度来说的,属于实在跟计算机硬件体系相关,属于实在的东西,是程序赖以生存的环境;

2.指针实际是一种数据类型,因为指针是存在于内存中的,只是这种数据类型是用来记录一个地址;

3.C语言中没有地址一说,看站在什么角度,对于嵌入式来说,嵌入式中很多时候都会直接通过C操作某个地址的;
另外,&A的使用来说,个人不认为是取A的指针,这个说法个人认为欠妥,原因在于,A是一个变量,变量实际就是内存中的一个数据,&A操作实际是对A的存储单元的位置做查询,
也就是实际在对内存的索引标号做查询,并不是A的地址在内存中有个副本(一个装A的地址的指针),&A把这个副本指针取出来;

以上,个人观点,只求真理!

论坛徽章:
0
374 [报告]
发表于 2011-01-10 10:11 |只看该作者
1.数据类型的重要跟C有没有地址是两回事情:
数据类型是对内存种种数据的应用意义来认定的,同一个数据,可以通过转化定义为不同的使用意义,这个完全是认为抽象的;
地址是对内存如何索引这个角度来说的,属于实在跟计算机硬件体系相关,属于实在的东西,是程序赖以生存的环境;
我基本上同意您的看法,可能在措辞上我们会有点区别。
数据类型是代码层面的东西,是一种抽象。
地址则是代码外部的东西,但需要在代码中表示,这种表示不完全对等于外部的“地址”。
指针是对地址的表示或抽象,但其含义是包含“地址”而不是直接等同于“地址”


2.指针实际是一种数据类型,因为指针是存在于内存中的,只是这种数据类型是用来记录一个地址;
除了“指针是存在于内存中”这句,其他的都同意。想补充的是这种数据类型不仅仅是用来记录一个地址的。

3.C语言中没有地址一说,看站在什么角度,对于嵌入式来说,嵌入式中很多时候都会直接通过C操作某个地址的;
另外,&A的使用来说,个人不认为是取A的指针,这个说法个人认为欠妥,原因在于,A是一个变量,变量实际就是内存中的一个数据,&A操作实际是对A的存储单元的位置做查询,
也就是实际在对内存的索引标号做查询,并不是A的地址在内存中有个副本(一个装A的地址的指针),&A把这个副本指针取出来;

http://bbs.chinaunix.net/viewthread.php?tid=1821644&extra=page%3D1%26amp%3Borderby%3Dviews%26amp%3Bfilter%3D2592000&page=30
的297楼似乎是您所说的“直接通过C操作某个地址”吧
但是在我看来
以 (*(volatile unsigned *)0x56000050) 为例
0x56000050是一个int(你可以把它理解为地址)
操作是对(volatile unsigned *)0x56000050这个指针进行的

此外,&A确实“对A的存储单元的位置做查询”,但绝不仅限于此。
&A本身就是指针类型,如果吧它理解为求地址,是片面的,忽视了它的其他内涵

论坛徽章:
0
375 [报告]
发表于 2011-01-10 15:01 |只看该作者
出书了啊

论坛徽章:
0
376 [报告]
发表于 2011-01-10 17:16 |只看该作者
回复 375# jnjn999


    是啊。请多多指教

论坛徽章:
0
377 [报告]
发表于 2011-01-11 19:33 |只看该作者
指针,就是C的精华!!

论坛徽章:
0
378 [报告]
发表于 2011-01-12 19:33 |只看该作者
9.12.4  标准形式
    为了保证不确定参数函数代码的可移植性,C语言标准库提供了一套宏。尽管这套宏具有很好的可移植性,但使用起来非常笨拙且程式化,含义非常抽象难解,因此本书在每个步骤后都提供了一个不严格的非正式注解,以帮助读者理解。
    这套宏的定义写在stdarg.h文件中,因此需要首先写编译预处理命令。

    (1)#include <stdarg.h>
    (2)va_list ap;/*这个“ap”用于遍历各个“…”中的参数。“va_list”是什么类型?是“…”类型。“…”是什么类型?不清楚。实际上这应该是个“void *”,但这是我猜的。*/
    (3)va_start(ap,最后一个确定参数的类型)/*这是让“ap”获得初始值,也就是指向第一个可变参数。应该是“ap = (void)(&最后一个确定参数+1)”,这也是我猜的。*/
    (4)va_arg(ap,可变参数的类型) /*这句的含义是求当前可变参数的值并把“ap”移至下一个可变参数。大体上应该是“*((可变参数的类型 *)ap)++”,然而“((可变参数的类型 *)ap)++”并不合法,所以这里很可能还需要其他编译手段,比如借助临时变量等。*/
    (5)va_copy(dst,src) /*这是C99新增加的内容,可以复制一个“ap”的副本,在“src”被改变的情况下,一旦需要,还可以从前面重新读取参数。*/
    (6)va_end(ap) /*这是在读完参数后对前面可能用到的临时变量等进行清理。*/

我觉得一本书里不应该这样向读者(或者是像我这样的初学者)来描述

论坛徽章:
0
379 [报告]
发表于 2011-01-12 19:42 |只看该作者
2)va_list ap;/*作为初学者,我只能从一些书里得到一些说法。有的书里认为va_list是这样的一种数据:循环使用且每次指向一个可变的参数。因此该类型的变量就是代表整个参数列表。那么你例中的那个老生长谈的ap就是代表整个参数列表。我觉得你这样说会更好些——虽然我不知道这样到底对不对*/

论坛徽章:
0
380 [报告]
发表于 2011-01-12 20:57 |只看该作者
2)va_list ap;/*作为初学者,我只能从一些书里得到一些说法。有的书里认为va_list是这样的一种数据:循环使用且每次指向一个可变的参数。因此该类型的变量就是代表整个参数列表。那么你例中的那个老生长谈的ap就是代表整个参数列表。我觉得你这样说会更好些——虽然我不知道这样到底对不对*/
hanxuaiztt 发表于 2011-01-12 19:42


非常感谢您提出的意见。我会慎重地再考虑一下
我想和您解释一下当时我的想法,希望您不至于把这理解为一种辩解
语气问题当时是想追求一种风格
就是不想太一本正经,想稍微活泼点
此外我觉得va_list ap;这些东西到底是什么是没有确切答案的
因为不同的编译器可能有不同的实现方式
您说的“有的书里认为va_list是这样的一种数据……”
我是不赞成这书的说法的
因为这种说法很可能顾此失彼,只见树木不见森林,强调了一种实现而忽视了其他实现的可能性
我个人认为追究va_list ap;到底是什么意义不大
写代码时能够很程式化地使用那些宏就可以了
况且前面讲了一点实现的原理性的东西

欢迎您继续提出宝贵意见
谢谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP