发新帖我要提问
12
返回列表
打印

指针啊指针问题。

[复制链接]
楼主: 刚注册
手机看帖
扫描二维码
随时随地手机跟帖
21
本帖最后由 雪山飞狐D 于 2009-8-19 15:56 编辑

简单的说 0x0010 是 int 而不是 int  *
NULL   是随机的 int *  或者是 char * ,由编译器决定,不是起始地址0
也不是int 0

使用特权

评论回复
22
冷漠| | 2009-8-19 17:47 | 只看该作者
回19楼。加上* const   p试试。C51 正确。

void main()   
{
int data *const  p=0x0010;
*p=100;

while(1);
}


有书上讲。《C语言详解》指针部分。

使用特权

评论回复
23
刚注册|  楼主 | 2009-8-19 20:05 | 只看该作者
为什么要加CONST?

没有道理的啊,指向的是RAM区,而且RAM区这个地址上的数据也不是常数,为什么要弄出CONST呢?

不解。。。

使用特权

评论回复
24
冷漠| | 2009-8-19 20:43 | 只看该作者
关键是:加了const以后,通过了吗?

如果通过了,再说其中概念。

如果还是没通过,任何概念都是没道理。

不过,C51加不加都一样。但是你说其它编译器通不过,也许按照ANSI C,应该说明const指针。那么其它编译器是不是更严格遵循ANSI C 标准?请告之其它编译器编译结果,通不过提示的是何种错误或警告?

使用特权

评论回复
25
冷漠| | 2009-8-19 20:47 | 只看该作者
本帖最后由 冷漠 于 2009-8-19 21:11 编辑

再说明一点:const 并不一定是定位code区。例如:

const  char   data   arr[ ]={1,2,3,4,5};

就是在data区定义的常数数组。arr 也是const常量指针。

使用特权

评论回复
26
刚注册|  楼主 | 2009-8-20 09:08 | 只看该作者
回19楼。加上* const   p试试。C51 正确。

void main()   
{
int data *const  p=0x0010;
*p=100;

while(1);
}


有书上讲。《C语言详解》指针部分。
冷漠 发表于 2009-8-19 17:47

------------------------------------------------

经过测试,编译通不过,测试的编译器是PICC和IAR,都提示错误。

使用特权

评论回复
27
刚注册|  楼主 | 2009-8-20 09:09 | 只看该作者
CONST只表示是一个不变化的常量,但没有规定是否一定放在ROM区,也可以放到RAM区的。

使用特权

评论回复
28
冷漠| | 2009-8-20 09:28 | 只看该作者
本帖最后由 冷漠 于 2009-8-20 09:34 编辑

书上(关于ANSI  C)讲得很清楚了:    --摘自《C语言详解》P256  指针初始化
    ......
    指针对象一般不要初始化为除0之外的(注意包括除NULL之外的--冷漠注)其它整数值(直接量),例如,一般不要使用说明:
     int *pi=10000;     // 冷漠注:如若允许,那么 int *pi=10001; 也被允许?--不在整数边界。     
    因为从10000号地址开始的若干个字节中并不一定刚好就分配给一整数对象。但也有一些特殊情况除外,比如要存取某个存储单元的内容时。(冷漠注:存取某个(单个)存储单元....)
    .............
    为安全起见,在说明一个指针对象时最好将它初始化为一个确定的值。如果在说明它时还不能确定它所指向的是哪个对象或函数,那么可以把它初始化为NULL(即0)。例如:
    long  int *pli=NULL;    // 终于找到出处了。--冷漠注。

    在说明全局指针变量(extern)和静态指针对象(static)时,若未带初始化部分,则这些指针对象的值均被(编译器)初始化为NULL。但对于局部指针对象,在说明时若未带初始化部分,则该指针对象的值是不确定的,即必须在说明时显式指明其初值,其后再具有确定的值。

    一个指针的取值范围应为机器所有可用内存的地址,但并不是所有内存地址都可以作为任一指针变量的值。(注意这里的概念。--冷漠)。指针对象的值 必须是属于该指针变量指向对象的类型的某个对象的地址。例如:一个指向整数类型的指针值不得是分配给一个浮点类型对象的内存单元的首地址。(所以LZ必须指明0x0010这个首地址属于何种(存取)对象类型。--冷漠)。
    因此,指针变量可取的值是随着实现的不同、执行的不同而有所不同。

    每一种类型的指针变量都有一个特殊的值NULL。NULL是一个定义在头文件stddef.h中的宏,用于定义一个空指针。空指针表示指针不指向任何位置(而不是LZ 理解的指向0地址。)NULL实际上是一个整数常量,其值为零(理解为空值)。NULL值是有别于指向具体对象的指针值的特殊值(空指针标识符)。

——以上摘自《C语言详解》


至此概念讲的已经很清楚了。若要说明一个指针初值,先要有一个具体类型的对象(以指向)。例如:
   int  a;   //对象说明在先。
   int  *ptr=&a;    //指针初始化在后。

但是如若在指针说明时还没有任何对象所指向,--像LZ那样,那么可以初始为空值,即:
    int  *ptr=NULL;    // 并非指向0地址。NULL是不能作为实际指针使用的空指针值。
如若希望像LZ那样把RAM地址0x0010 说明为指向int变量的指针,则可以在初始化之后,在程序中定义:
    ptr=(int *)0x0010;
或者在说明初值时,指明(未来对象)地址类型:  int *ptr =(int *)0x0010;   // C51  int data *ptr =0x0010;  已经足够信息。

使用特权

评论回复
29
冷漠| | 2009-8-20 10:11 | 只看该作者
严格按照规则的写法:

#include <stddef.h>

void main()   
{
int data *p=NULL;   
p=(int data *)0x0010;

*p=100;
while(1);
}

应该在所有编译器下通过。

使用特权

评论回复
30
123jj| | 2010-8-3 14:05 | 只看该作者
好贴

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则