再论C语言指针、地址、赋值的问题,又是一通“扯”

ageratum

来自: ageratum(„Zu den Sachen selbst!“)
2012-06-23 05:55:44

×
加入小组后即可参加投票
  • ageratum

    ageratum („Zu den Sachen selbst!“) 楼主 2012-06-23 09:33:50

    最后,我来解释一下,在这位坛友的例子中,为什么会出现“输出为10”这个“奇怪的现象”。 为了解释清楚这个问题,我们把我上面所举例子的代码延伸一下: #include<stdio.h> int main(void) { int *p; p = (int *) 10; printf("%d\n", p); p = (int *) 'a'; printf("%c\n", p); p = (int *) "I Love C/C++! Oh, Yeah!"; printf("%s\n", p); return 0; } 上面的代码,运行结果为: 10 a I Love C/C++! Oh, Yeah! 怎么样,觉得奇怪吗? 只要我们在 printf函数的第一个参数中,设定了“恰当的”format,程序就会符合我们“奸诈”的预期 —— 我们将p这个指向整数类型数据的指针(这一点自始至终都不会有变化),分别用“%d”、“%c”和“%s”这些format表示出来。而这些format又跟我们对p赋值时的那个“(int *)”右边黏着的“坏东东”的“看上去的样子”相吻合,那么,原来这些“坏东东”看上去是啥样的,现在也原样地被反馈回来。 然而,正如我在上面所强调的那样,p自始至终都是指向整数类型数据的指针,那么,它其实并不是printf函数在被设定了 “%d”、“%c”和“%s”这些format参数之后,所期盼的东东。但那又怎么办呢?我们既然这样写了,老Boss看到了之后,非常生气又无奈地把p的值(并不是p本身)分别强制转换为整数类型、字符类型、指向字符类型数据的指针。在这个过程中,老Boss连骂了三次,您在Warnings中可以看到。 请特别注意,在 printf("%s\n", p); 中,老Boss并不是把p的值,强制转换为所谓的“字符串类型”(根本没有这种类型)。但是,为什么还是达到了我们“奸诈的预期”的结果呢? 当printf函数的第一个参数,被设定为“%s”这个format之后,它所真正期盼的,是一个指向字符类型数据的指针。程序从这个指针所指向的存储器位置开始,连续地读取数据,直到一个被约定为字符串结束标志的数据(\0)为止。 为了使我们奸诈的手段,100%地合法 —— 如同洗钱 —— 我们应当这样写: #include<stdio.h> int main(void) { int *p; p = (int *) 10; printf("%d\n", (int)p); p = (int *) 'a'; printf("%c\n", (char)p); p = (int *) "I Love C/C++! Oh, Yeah!"; printf("%s\n", (char*)p); return 0; } 这麽一来,老Boss就被蒙在鼓里,老老实实地为我们“洗钱”,再也不会骂人了。 之前我一再强调, p自始至终都是指向整数类型数据的指针,那么,为了让printf函数“忠实地”反馈出p原本应有的面貌,我们应当选用“%p”这个format。代码如下: #include<stdio.h> int main(void) { int *p; p = (int *) 10; printf("%p\n", p); p = (int *) 'a'; printf("%p\n", p); p = (int *) "I Love C/C++! Oh, Yeah!"; printf("%p\n", p); return 0; } 运行一下,结果是: 0xa 0x61 0x8048508 看到这几行结果,这位坛友应当有所领悟吧!

  • ageratum

    ageratum („Zu den Sachen selbst!“) 楼主 2012-06-23 09:40:06

    最大的问题在于 printf 的打印指示符。 printf 的指示符只是一个「栈上参数的长度」和「打印 最大的问题在于 printf 的打印指示符。 printf 的指示符只是一个「栈上参数的长度」和「打印方法」的对应,不能指出一个参数的类型。再加上 format 是运行时解释的,更没有任何编译时检查(不过现在的编译器多有对这几个库函数的额外检查,但对于非常量的 format 仍然毫无办法)。结果就是,只要打印方法可用于一个变量,它懒得管这个变量原本是什么类型,也懒得管它得到是不是一个变量。 类型安全,节省运行时解释 format 的开销,这是 C++ 里 stream 库的初衷。不过,stream 的设计有它自己的问题,另一个话题了。 ... lichray

    您说的正在点子上。 赞——!

  • ageratum

    ageratum („Zu den Sachen selbst!“) 楼主 2012-12-28 20:48:08

    在C语言讨论“变量”的概念都不靠谱。把变量和常量放在一起比较更是胡闹。 在C语言讨论“变量”的概念都不靠谱。把变量和常量放在一起比较更是胡闹。 幻の上帝

    啊 —— 大虾你也在这里哦:) 幸会!

  • ageratum

    ageratum („Zu den Sachen selbst!“) 楼主 2015-05-07 04:49:30

    置顶贴的水平怎么这么差。。。 置顶贴的水平怎么这么差。。。 天马流星拳

    哈哈,我老早写的。 就像看许多自己的老帖一样,这帖我都不敢看了。我自己猜想都是:水平太差。 我继续加油吧:)

你的回应

回应请先 , 或 注册

34586 人聚集在这个小组
↑回顶部