二维数组引用出现问题,求帮助

[复制链接]
5461|17
 楼主| sjc_sugar 发表于 2012-1-4 17:25 | 显示全部楼层 |阅读模式
定义如下:INT16U xdata CURVE[][2]=...;
在主函数调用如下:ConctLine(CURVE,Len);
ConctLine原型:
void ConctLine(INT16U *STR,INT8U LEN)

出现两个警告:
SOURCE\MAIN.C(117): warning C182: pointer to different objects

*** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS
    SEGMENT: ?PR?_CONCTLINE?MAIN

希望个位可以给点建议,谢谢!
wookongbun 发表于 2012-1-4 18:06 | 显示全部楼层
类型不匹配
void ConctLine(xdata INT16U *STR,INT8U LEN)
这样定义函数就可以了
不过,我不知道ConctLine是不是只需要操作xdata区的数据
 楼主| sjc_sugar 发表于 2012-1-5 12:02 | 显示全部楼层
2# wookongbun
不是那个问题,代码段没有找到这个警告找到原因了!如果定义CURVE是一维数组,没有警告,二维数组,ConntLine(CURVE,Len)有警告!
wookongbun 发表于 2012-1-5 13:40 | 显示全部楼层
ConctLine(CURVE[0], sizeof(CURVE) / sizeof(CURVE[0][0]));
 楼主| sjc_sugar 发表于 2012-1-5 16:30 | 显示全部楼层
4# wookongbun
既然数组名(二维)是它的首地址,也是起始地址,为什么能传递,但是编译器警告,而且数据传递也对,会有隐藏的BUG么?求解!
wookongbun 发表于 2012-1-6 09:24 | 显示全部楼层
CURVE、CURVE[0]、&CURVE[0][0]这三个表达式的值都是相同的,都代表着这块连续内存空间的首地址。所以CURVE也能传递而且数据不出错。
隐藏的BUG?我觉得不会有。
delin17 发表于 2012-1-6 12:48 | 显示全部楼层
是类型不匹配的原因,一个是二维数组的针,一个是INT16U指针
刘前辈 发表于 2012-1-6 18:58 | 显示全部楼层
本帖最后由 刘前辈 于 2012-1-6 18:59 编辑

很简单啦:
void ConctLine(INT16U  [ ][2],  INT8U LEN);
或者void ConctLine(INT16U (*STR)[2],  INT8U LEN);
或者void ConctLine(INT16U  (*) [2],  INT8U LEN);


//
johnwjl 发表于 2012-1-6 20:44 | 显示全部楼层
调用的时候给它强制一下:
ConctLine((INT16U *)CURVE, Len);
linfuchi 发表于 2012-1-6 22:25 | 显示全部楼层
二维数组的数组名是一个指向数组的指针,CURVE是一个这样的指针 INT16U (*p)[2];
不过ConctLine(&CURVE[0][0], sizeof(CURVE));也可以在子函数里面逐一访问数组的每个元素。
 楼主| sjc_sugar 发表于 2012-1-8 10:13 | 显示全部楼层
6# wookongbun
用CURVE传递时,发现编译器警告!其他都没有问题!前辈们一直告诫不要放过一个警告,怎么会出现这个问题?所以,我用&CURVE[0][0]传递没有问题,怕隐藏不知道的错误!
 楼主| sjc_sugar 发表于 2012-1-8 10:36 | 显示全部楼层
7# delin17
这三种传递方式CURVE、CURVE[0]、&CURVE[0][0]可以得到正确的结果,只是在编译时CURVE,这个会出现警告:MAIN.C(106): warning C182: pointer to different objects
 楼主| sjc_sugar 发表于 2012-1-8 11:16 | 显示全部楼层
8# 刘前辈
按照刘前辈的方法定义成二维数组时没有警告;CURVE、CURVE[0]、&CURVE[0][0]顺利通过编译。如果定义:void ConctLine(INT16U *STR,INT8U LEN)传递,是因为没有理清一维数组和二维数组;但是在此情况下CURVE传递时编译器报错,CURVE[0]、&CURVE[0][0]顺利通过编译,这个又给搞糊涂了;求解!
 楼主| sjc_sugar 发表于 2012-1-8 11:18 | 显示全部楼层
9# johnwjl
不用强调ConctLine((INT16U *)CURVE, Len);直接ConctLine(*CURVE, Len)传递就可以通过编译!问题是ConctLine(CURVE, Len)这样传递,编译器报错!
刘前辈 发表于 2012-1-8 12:20 | 显示全部楼层
很简单的证明:
一维数组时:CURVE=&CURVE[0];  //  & [0]=1
二维数组时:CURVE[0]=&CURVE[0][0];
           CURVE[0]=*CURVE;  //显然 CURVE[0] != CURVE;
wookongbun 发表于 2012-1-8 20:17 | 显示全部楼层
highgear 发表于 2012-1-8 23:49 | 显示全部楼层
CURVE、CURVE[0]、&CURVE[0][0], (INT16U*) CURVE 是同一个地址,但是不同的类型。

curve[0] 是一个指针,指向一个[2]的数组,&CURVE[0][0]指向二维数组的第一个元素。由于二维数组的元素在 c/c++ 基本上是连续存放,可以被当作一个一维数组(c#, java 中的二维是存放了指针,指针指向不同的一维数组,所以不能直接强制为一个一维数组), 所以可以通过CURVE、&CURVE[0][0], (INT16U*) CURVE等等强制转换为 INT16U*.

如果要避免类型错误,则可使用 9 楼的强制:
void ConctLine(INT16U *STR,INT8U LEN)

ConctLine(((INT16U *)CURVE, len)

或者函数原型使用
void ConctLine(INT16U (*STR)[2] ,INT8U LEN)

这里的(*STR)[2]是说明 str 是一个指向一个有两个元素的数组的指针,与 int16u * 的类型不同。 其中: ((int) str[1]) - ((int) str[0]) = sizeof(INT16U) * 2

评分

参与人数 1威望 +1 收起 理由
sjc_sugar + 1

查看全部评分

 楼主| sjc_sugar 发表于 2012-1-30 14:47 | 显示全部楼层
highgear解释比较详细,终于搞明白了;同时也感谢各位前辈的帮助!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

70

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部