2.7 问与答

2.7 问与答

问:使用指针的困难之一是,我们往往会错误的使用它,并且这种错误不是发生在编译时,而是发生在运行时。下列几段代码,哪些会造成编译时错误,哪些会造成运行时错误,为什么?

a)

char *sptr = "abc",*tptr;

*tptr = sptr;

b)

char *sptr = "abc",*tptr;

tptr = sptr;

c)

char *sptr = "abc",*tptr;

*tptr = *sptr;

d)

int *iptr = (int *)10;

*iptr = 11;

e)

int *iptr = 10;

*iptr = 11;

f )

int *iptr = (int *)10;

iptr = NULL;

答:a)编译时错误。*tptr是一个字符,而sptr是一个指向字符的指针,代码试图将一个指针变量分配给一个字符变量,很显然这会产生类型冲突。

b)没有错误。因为tptrsptr都是字符指针。

c)可能产生运行时错误。因为程序并没有为tptr分配存储空间。

d)可能产生运行时错误。因为将一个固定的地址赋值给一个整型指针是很危险的。在代码中,我们会把11写到地址为10的*iptr中,这种操作很可能不合法。

e)可能产生运行时错误或者警告。因为此代码尝试将一个整型赋值给一个整型指针,很多时候这种操作并不合法或会造成类型冲突。

f)没有错误。因为,虽然程序一开始做了一个将固定地址赋值给整型指针iptr的危险操作,但它立刻将此指针设置为NULL,这是正确的操作。

 

问:回想一下,我们用指针的算术运算来计算指针。如果指针p包含地址0x10000000,那么在以下表达式中p将访问哪个内存地址?且p在此地址会访问多少字节的数据?

*(p + 5)

答:这个问题的答案取决的指针p的类型。回想一下,当我们在指针p上加上i时,所得到并不是p指向的地址加上i个字节,而是p指向的地址加上i乘以p所引用的数据类型大小个字节。由于问题中没有说明指针p的类型,所以无法知道以上表达式将访问到哪个地址。同样,p的类型也决定我们要访问多少字节的数据,所以我们也无法知道将会访问多少个字节的数据。

 

问:链表的操作list_rem_next会从链表中删除一个元素(见第5章)。iptr是一个整型指针,如果我们想要把此指针指向从链表中被删除的整型数,那么我们如何调用list_rem_next来替代本章之前所提到的方法?函数的原型如下所示,list为链表,element引用将要删除的元素,并在函数返回时data指向被删除的数据。

int list_rem_next(List *list, ListElmt *element, void **data);

答:另一种调用list_rem_next的方法如下所示。将iptr转换为一个void指针来代替之前的指向void指针的指针。这种调用方式可以被接受因为void指针与其它类型相兼容。但是还是要说明一下,我们之前的调用方式更加清晰,因为这与list_rem_next原型相一致。

retval = list_rem_next(&list, element, (void *)&iptr);


PS:

1、此书(Mastering Algorithms with C)译稿版权归本人(Love_Lei)及好友(bigship)共同所有,未经本人同意谢绝一切转载,并不得抄袭,模仿,盗版!更请大家监督盗版之人!

2、由于本人水平有限,如对译文有任何建议和异议,欢迎大家留言指正,我们共同讨论学习!谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值