[C语言]

遇到一个指针 和sizeof函数的问题,恳求前辈分析一下

[复制链接]
1758|14
手机看帖
扫描二维码
随时随地手机跟帖
hsxs|  楼主 | 2018-8-25 13:44 | 显示全部楼层 |阅读模式
本帖最后由 hsxs 于 2018-8-25 13:45 编辑
void Show_NumString(unsigned char x,unsigned char y,unsigned char *chr)
{
        unsigned char j=0,lenth=0;
        lenth =sizeof(chr)/sizeof(chr[0]);
   for(j=0;j<lenth;j++)
        {
                Show_number32(x,y,chr[j]);
                x = x+10;
        }
}

**********************************************
unsigned char TEMP_num[] = {12,12,12,12,12,12};   /* 99.99*/
******************************************************
这是我OLED 上面显示数字串的函数,入口有一个指针参数,进来的是一个数组,当我填入TEMP_num的时候,我的Show_NumString函数中的lenth算出来始终为3;试过别的数组也是3;所以我屏幕上面显示出来的数据只有3位,应该要显示6位的

相关帖子

hsxs|  楼主 | 2018-8-25 13:48 | 显示全部楼层
在线等。。。。。周末休息就自己在家写写代码,对这个还是不很熟悉

使用特权

评论回复
一叶倾城wwq| | 2018-8-25 13:51 | 显示全部楼层
这个问题我也遇到过,我的也是这样传数组或者字符进来,但sizeof计算后只认3个;还有一个问题,你试着把长度也写在形参里,这个函数就有4个形参,也就是加个len,看看还能不能编译过,调用会不会出问题?

使用特权

评论回复
hsxs|  楼主 | 2018-8-25 13:59 | 显示全部楼层
一叶倾城wwq 发表于 2018-8-25 13:51
这个问题我也遇到过,我的也是这样传数组或者字符进来,但sizeof计算后只认3个;还有一个问题,你试着把长 ...

那样子我还要调用不同长度的数组,要不然太麻烦了,我试着写过加个参数进去,可以用,但是对于接下来的程序不友好,而且重复太多

使用特权

评论回复
评论
icecut 2018-8-26 21:10 回复TA
函数调用要先看功能。不是随便理解。。。。 空间时间转换,如果你不传长度,后面就要计算长度。 定长数组使用指针传递,就失去了数组长度的概念。 
hsxs|  楼主 | 2018-8-25 14:53 | 显示全部楼层
各位走过路过的,提个意见,互相交流一下意见嘛

使用特权

评论回复
john_lee| | 2018-8-25 15:02 | 显示全部楼层
sizeof(指针) 只能得到指针本身的大小,而不能得到数组的长度。至于为什么是 3,说来话长,从这个 3 我能知道楼主使用的 51 CPU。
问题的解决办法,要么增加一个长度参数,要么在数组中设置一个表示结束的特殊项,循环中检测到这个项时,就退出循环。

使用特权

评论回复
hsxs|  楼主 | 2018-8-25 15:17 | 显示全部楼层
john_lee 发表于 2018-8-25 15:02
sizeof(指针) 只能得到指针本身的大小,而不能得到数组的长度。至于为什么是 3,说来话长,从这个 3 我能知 ...

对呀,大神,用的是新唐51单片机;能解释一下为什么是3 吗? 这样可能对于理解大神的方法有帮助

使用特权

评论回复
gnaijnaoul| | 2018-8-25 15:18 | 显示全部楼层
六楼说的对,第一个sizeof求的是指针变量的存储大小。
函数用指针传递数据,子函数只知道数据在哪里,不知道数据有多大,必须传递长度过去。

使用特权

评论回复
hsxs|  楼主 | 2018-8-25 15:19 | 显示全部楼层
hsxs 发表于 2018-8-25 15:17
对呀,大神,用的是新唐51单片机;能解释一下为什么是3 吗? 这样可能对于理解大神的方法有帮助 ...

意思是,这个数组进来,比如每个数组后面添加一个 a,当数组进来的时候,循环检测计数+1 直到有a? 但后就知道数组的个数了吗?

使用特权

评论回复
hsxs|  楼主 | 2018-8-25 15:56 | 显示全部楼层
好的,谢谢各位

使用特权

评论回复
john_lee| | 2018-8-25 16:00 | 显示全部楼层
本帖最后由 john_lee 于 2018-8-25 17:10 编辑

51的地址空间有 3 个:
  • 8 位片内 RAM,使用 MOV 指令访问。其中又分为 3 种:
    • 直接寻址,地址范围 0 - 127 字节,在 C51 中使用 data 扩展关键字修饰。
    • 间接寻址,地址范围 0 - 255 字节,在 C51 中使用 idata 扩展关键字修饰。
    • 位寻址,在 C51 中使用 bdata 扩展关键字修饰。
    凡是修饰为 data、idata、bdata 类型的指针,指针大小都是 1 字节。
    例如:
    // 定义间接寻址数组
    char idata TEMP_num[]= {...};
    // 定义指向间接寻址的 char 类型的直接寻址指针,指针大小为 1 字节
    char idata* data ptr = TEMP_num;
  • 16 位扩展 RAM,使用 MOVX 指令访问,地址范围 0 - 65535,在 C51 中使用 xdata 扩展关键字修饰。
    凡是修饰为 xdata 类型的指针,指针大小都是 2 字节。
    例如:
    // 定义扩展 RAM 数组
    char xdata TEMP_num[]= {...};
    // 定义指向扩展 RAM 的 char 类型的直接寻址指针,指针大小为 2 字节
    char xdata* data ptr = TEMP_num;

  • 16 位 ROM,使用 MOVC 指令访问,地址范围 0 - 65535,在 C51 中使用 code 扩展关键字修饰。
    凡是修饰为 code 类型的指针,指针大小都是 2 字节。
    例如:
    // 定义 ROM 数组
    char code TEMP_num[]= {...};
    // 定义指向扩展 RAM 的 char 类型的直接寻址指针,指针大小为 2 字节
    char code* data ptr = TEMP_num;

如果不修饰指针,那么编译器就会统一使用 2 字节来表示寻址大小,并且附加 1 字节表示该指针的修饰类型,指针的大小就是 3 字节。编译器会在程序中为该指针赋值时,根据赋值数据的类型,确定修饰类型,以便在使用该指针访问数据时使用正确的访问指令。例如:
// 定义 idata 修饰类型的数组
char idata TEMP_num1[]= {...};
// 定义 xdata 修饰类型的数组
char xdata TEMP_num2[]= {...};
// 定义 code 修饰类型的数组
char code TEMP_num3[]= {...};

// 定义一般 char 类型指针的直接寻址指针,指针大小为 3 字节
char* data ptr = TEMP_num1;  // 定义并赋值(或者以后赋值也可以),编译器通过 TEMP_num1 的修饰类型确定 ptr 的修饰类型为 idata。
temp_value = *ptr;     // 使用 MOV A, @Rx 指令访问数据
...
ptr = TEMP_num2;    // 编译器通过 TEMP_num2 的修饰类型确定 ptr 的修饰类型为 xdata。
temp_value = *ptr;     // 使用 "MOVX A, @DPTR" 指令访问数据
...
ptr = TEMP_num3;    // 编译器通过 TEMP_num3 的修饰类型确定 ptr 的修饰类型为 code。
temp_value = *ptr;     // 使用 MOVC A, @A+DPTR 或 MOVC A, @A+PC 指令访问数据
      

使用特权

评论回复
评分
参与人数 2威望 +3 收起 理由
小小电子爱好者 + 2 赞一个!
hsxs + 1 很给力!
hsxs|  楼主 | 2018-8-25 18:25 | 显示全部楼层
john_lee 发表于 2018-8-25 16:00
51的地址空间有 3 个:
  • 8 位片内 RAM,使用 MOV 指令访问。其中又分为 3 种:

  • 见识了见识了

    使用特权

    评论回复
    wsmysyn| | 2018-8-25 18:41 | 显示全部楼层
    楼上说的很清楚了。。

    以前反汇编的时候,发现了 指针的存储长度确实是3个字节。。。。
    只是没有查到,修饰类型的具体定是什么,比如十六进制几代表哪种类型的指针。。。

    确实是51单片机是这样。。其他我倒是没看过。。。

    使用特权

    评论回复
    wwdatou| | 2018-8-26 14:27 | 显示全部楼层
    hsxs 发表于 2018-8-25 13:59
    那样子我还要调用不同长度的数组,要不然太麻烦了,我试着写过加个参数进去,可以用,但是对于接下来的程 ...

    不想增加“长度”参数,可以考虑使用strlen计算字节数,只需要每次准备数据的时候,结尾补一个0x00就可以

    使用特权

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

    本版积分规则

    12

    主题

    96

    帖子

    0

    粉丝