免费注册 查看新帖 |

Chinaunix

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

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

论坛徽章:
0
251 [报告]
发表于 2011-01-02 10:26 |只看该作者

论坛徽章:
0
252 [报告]
发表于 2011-01-03 14:24 |只看该作者
我是数学师范,大学毕业六年多了,当时学的是VB,因为第一年我考的最差要补考,我与同学说“VB没有DIAO用”被老师听到了,他说“C语言最有用,你能过C二级我就算你今年过了。不过看你这样子,你VB要一直考到大四才能过”于是乎我后来自己搞了本谭浩强埋头苦学,不但过了C二级,而且还略有感想。
这阵子因没钱买正版WIN,也不想天天受盗版的气,决定改用LINUX,无意来到这里,发现这里还很旺。凭读书和一本古老的谭浩强,回答以上四题。

论坛徽章:
0
253 [报告]
发表于 2011-01-03 14:26 |只看该作者
回复 1# 无风之谷


    1.  一元&运算是否应该翻译成“求指针运算”而不是“求地址运算”
谭浩强把&运算称为取地址运算,我同意谭浩强老师的叫法。至于到底译成什么样子,其实本质讨

论就是对指针与地址的关系讨论——即问题3。
2.  数组名有两种类型吗?
按谭浩强的说法,数组和指针在大多数时候是等价的(谭浩强把[]称为变址运算符,这也就说明数

组也是靠计算地址完成其使命的),几乎在我遇到的情况里数组都能用指针办到。如果我们不考虑

编译过程的话,只是在应用就应该可以认为数组名有两种类型。但事实上我觉得他们还是有差别的

,不能完全等价。用谭浩强的一个例子,如对p初值&a[0],则p+i,a+i都是a的地址,实际编译时

a是从a的位置开始跳过i个,然后再取出a里的值,而*(p+i)或p在编译时是先找到p的位

置,然后取出其中存着的指针值(本例即&a[0])再在指针上加i,然后再取出指向位置的值。至于

p+i实际地址说明谭浩强还是说的很清楚的,我就不多抄书了。
3.  “指针就是地址”的说法是否掩盖了指针的实质?
谭浩强说“变量的指针就是变量的地址”这说法是对,我同意。因此“指针就是地址”的说法说明

了指针的本质是地址是对,但这种说法事实上还是部分掩盖了指针的实质。我认为指针是特殊的有

规则的地址。在数组那一块,我们可以看到谭浩强的说明就可以明白指针不是简单的地址。还用上

面那个例,如里是int a[10],*p,那么p+1就意味着使p的值(是一个地址)加上4个字节,但如果

double a[10],*p,则p+1就意味着使p的值加上8个字节啦!就指针与地址我再说两点:1、对于一个

变量来说指针是它存储位置的起始地址。2、其实我觉得我们提到的指针应分两种情况,一是指针

变量本身,另一个是指针变量里存放的地址值,在大多数时候我们把这两者混着说了。如果指指针

变量本身,那么它是可以运算的量,如果是指指针变量里存放的地址值的话,那么那个地址则是常

量是不可运算的。
4.   void *类型的指针究竟是可以指向任何对象还是不指向任何对象?
void *类型的指针可以用来指向任意一个抽象的数据,只是在操作时要进行合适的强制类型转换,

否则void *类型的指针就不能指向任何对象。另void *类型的指针是不准算术运算的呵。反正要用

void *类型的指针就要强制类型转换,否则它几乎是个废物。

论坛徽章:
0
254 [报告]
发表于 2011-01-03 14:27 |只看该作者
1.  一元&运算是否应该翻译成“求指针运算”而不是“求地址运算”
谭浩强把&运算称为取地址运算,我同意谭浩强老师的叫法。至于到底译成什么样子,其实本质讨

论就是对指针与地址的关系讨论——即问题3。
2.  数组名有两种类型吗?
按谭浩强的说法,数组和指针在大多数时候是等价的(谭浩强把[]称为变址运算符,这也就说明数

组也是靠计算地址完成其使命的),几乎在我遇到的情况里数组都能用指针办到。如果我们不考虑

编译过程的话,只是在应用就应该可以认为数组名有两种类型。但事实上我觉得他们还是有差别的

,不能完全等价。用谭浩强的一个例子,如对p初值&a[0],则p+i,a+i都是a[i]的地址,实际编译时

a[i]是从a的位置开始跳过i个,然后再取出a[i]里的值,而*(p+i)或p[i]在编译时是先找到p的位

置,然后取出其中存着的指针值(本例即&a[0])再在指针上加i,然后再取出指向位置的值。至于

p+i实际地址说明谭浩强还是说的很清楚的,我就不多抄书了。
3.  “指针就是地址”的说法是否掩盖了指针的实质?
谭浩强说“变量的指针就是变量的地址”这说法是对,我同意。因此“指针就是地址”的说法说明

了指针的本质是地址是对,但这种说法事实上还是部分掩盖了指针的实质。我认为指针是特殊的有

规则的地址。在数组那一块,我们可以看到谭浩强的说明就可以明白指针不是简单的地址。还用上

面那个例,如里是int a[10],*p,那么p+1就意味着使p的值(是一个地址)加上4个字节,但如果

double a[10],*p,则p+1就意味着使p的值加上8个字节啦!就指针与地址我再说两点:1、对于一个

变量来说指针是它存储位置的起始地址。2、其实我觉得我们提到的指针应分两种情况,一是指针

变量本身,另一个是指针变量里存放的地址值,在大多数时候我们把这两者混着说了。如果指指针

变量本身,那么它是可以运算的量,如果是指指针变量里存放的地址值的话,那么那个地址则是常

量是不可运算的。
4.   void *类型的指针究竟是可以指向任何对象还是不指向任何对象?
void *类型的指针可以用来指向任意一个抽象的数据,只是在操作时要进行合适的强制类型转换,

否则void *类型的指针就不能指向任何对象。另void *类型的指针是不准算术运算的呵。反正要用

void *类型的指针就要强制类型转换,否则它几乎是个废物。

论坛徽章:
0
255 [报告]
发表于 2011-01-03 14:28 |只看该作者
TXT打好后,因为不熟悉,所以才多发了几遍~~~

论坛徽章:
0
256 [报告]
发表于 2011-01-03 15:23 |只看该作者
本帖最后由 KBTiller 于 2011-01-03 15:48 编辑

回复 254# hanxuaiztt

    呵呵,来的都是客。索性回一下

   
void *类型的指针可以用来指向任意一个抽象的数据,只是在操作时要进行合适的强制类型转换,否则void *类型的指针就不能指向任何对象


    这段文字里有逻辑错误,不知道你发现没有。一方面你说“可以指向任意一个抽象的数据对象”,同时又说“不能指向任何对象”。
    我觉得数学专业的人不应该说出这样的话。
    我认为你没有搞清楚究竟到底是谁指向对象。

    ==========================
    此外我很想请教一下,什么叫“抽象的数据”

论坛徽章:
0
257 [报告]
发表于 2011-01-03 17:16 |只看该作者
我是数学师范,大学毕业六年多了,当时学的是VB,因为第一年我考的最差要补考,我与同学说“VB没有DIAO用”被老师听到了,他说“C语言最有用,你能过C二级我就算你今年过了。不过看你这样子,你VB要一直考到大四才能过”于是乎我后来自己搞了本谭浩强埋头苦学,不但过了C二级,而且还略有感想。
这阵子因没钱买正版WIN,也不想天天受盗版的气,决定改用LINUX,无意来到这里,发现这里还很旺。凭读书和一本古老的谭浩强,回答以上四题。hanxuaiztt 发表于 2011-01-03 14:24


我非常惊讶你的老师竟然用通过二级考试来激励你
而且在我的印象中,CU论坛从来没有人拿通过二级来说事

论坛徽章:
0
258 [报告]
发表于 2011-01-03 18:28 |只看该作者
/*
  题目:21点36分23秒后再过3小时28分47秒是几点几分几秒?
*/
#include <stdio.h>
#include <stdlib.h>
#define MSX 60
#define FSX 60
#define SSX 24
struct shijian {
                  int shi ;
                  int fen ;
                  int miao;
                  } ;

struct shijian jg( struct shijian, struct shijian );
struct shijian fz( int  ,int ,int );
int main ( void )
{
   
  struct shijian cs , zl , zzsj ;
cs=fz(21,36,23);
zl=fz(3,28,47);
  printf ( " %d 点 %d 分 %d 秒后再过" , cs.shi , cs.fen , cs.miao ) ;
  printf ( "%d 小时 %d 分 %d 秒是" , zl.shi , zl.fen , zl.miao ) ;
  zzsj = jg ( cs , zl ) ;
  printf ( "%d 点 %d 分 %d 秒\n" , zzsj.shi , zzsj.fen , zzsj.miao ) ;
  system("PAUSE");
  return 0;
}
/*fz()函数功能:
  专用来给时间付值
*/
struct shijian fz( int shi,int fen,int miao)
{
  struct shijian zz;
  zz.shi  =  shi ;
  zz.fen  =  fen ;
  zz.miao =  miao ;
return zz;
}
struct shijian jg( struct shijian sj , struct shijian zl)
{
  struct shijian zz;
  zz.shi  =  sj.shi + zl.shi ;
  zz.fen  =  sj.fen + zl.fen ;
  zz.miao =  sj.miao + zl.miao ;
  zz.fen  += zz.miao / MSX ;
  zz.miao %= MSX ;
  zz.shi  += zz.fen / FSX ;
  zz.fen  %= FSX ;
  zz.shi  %= SSX ;
  return zz;
}

我在想为什么不把初始时间,最终时间的付值操作也用一个函数装起来呢?

论坛徽章:
0
259 [报告]
发表于 2011-01-03 18:33 |只看该作者
我非常惊讶你的老师竟然用通过二级考试来激励你
而且在我的印象中,CU论坛从来没有人拿通过二级来说事
KBTiller 发表于 2011-01-03 17:16



    你不晓得,师范生是不用学C语言的,VB也就是考着玩的。全校几乎全报VB的。报C语言的一个考场都坐不满
我知道我这点小反对对CU来说太小儿科了,但我是全自己学的——没有老师教没有同学讨论,回想起来,大学中我也就自己认真学了这么一点东西

论坛徽章:
0
260 [报告]
发表于 2011-01-03 18:36 |只看该作者
回复  hanxuaiztt

    呵呵,来的都是客。索性回一下

   

    这段文字里有逻辑错误,不知道你发 ...
KBTiller 发表于 2011-01-03 15:23



否则前面还有一句话呵,“在操作时要进行合适的强制类型转换“,也就是说如果不强制类型转换,那么void *类型的指针就不能指向任何对象。但只要强制类型转换了就可以指向任何类型。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP