查看: 2515|回复: 8

[其他] 每天解决一个问题04天 :sizeof引发的小错误

[复制链接]
  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16702
    最后登录
    1970-1-1
    发表于 2015-8-28 21:42:33 | 显示全部楼层 |阅读模式
    本帖最后由 lkl0305 于 2015-9-5 23:59 编辑

    好吧,写了这个标题感觉对不起sizeof。
    其实不是sizeof的错,是我的错,小疏忽

    ==============================================================
    一、问题描述:
    1、看KSDK库错了,发现很多历程打印字符串或数组时,经常用sizeof来计算数组长度,比如uint8_t test[10];
    那test数组的长度是多少?
    sizeof(test)/sizeof(uint8_t)就搞定了,简单吧。
    2、具体sizeof的作用是什么呢?
    每本c语言书上都有:
    sizeof是C语言的一种单目操作符,它并不是函数。
    sizeof操作符以字节形式给出了其操作数的存储大小。
    操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。
    3、来看看一个例子,我在KDS上写的:
    3561.jpg
    输出是什么呢,下面的是输出。没有任何问题。
    3565.jpg
    4、那把数组作为参数传递给函数后,在函数内能使用么?
    如下程序输出什么呢?
    3562.jpg
    答案是如下图:
    3566.jpg
    5、很明显是错误的,为什么呢?

    二、解决办法:
    想要解决问题,首先要知道问题所在,在这里有2点要明白:

    1、数组作为参数传递给函数时,通过数组的指针是没有办法判断数组长度的,除非你的数组中有明显的结束标志。
    2、在函数内部sizeof(test)这个是测试指针的存储空间,当然在32位字长的ARM中是4个字节。
    sizeof(test)/sizeof(uint8_t)=4/1,当然上面打印出4个数组元素。
    3、知道了原因后,解决办法就好了:
    通常的做法是传递数组给函数时,在函数内部想要知道数组长度时,一般要把数组长度使用参数同时传递进来。
    如下图:
    3563.jpg
    在其它地方调用就可以了。
    3564.jpg

    整个测试程序如下:

    1. #include "fsl_device_registers.h"
    2. #include "fsl_debug_console.h"
    3. #include "board.h"
    4. #include "string.h"

    5. void sizeof_Test(uint8_t * test)
    6. {
    7.     uint32_t i;

    8.     for (i = 0; i < sizeof(test)/sizeof(uint8_t); i++)
    9.     {
    10.         PRINTF("%d ", test[i]);
    11.     }
    12.     PRINTF("\r\n");
    13. }

    14. void right_test(uint8_t * test, uint32_t count)
    15. {
    16.     uint32_t i;

    17.     for (i = 0; i < count; i++)
    18.     {
    19.         PRINTF("%d ", test[i]);
    20.     }
    21.     PRINTF("\r\n");
    22. }

    23. int main(void)
    24. {

    25.     /* Write your code here */
    26.     uint32_t i;
    27.     uint8_t test1[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

    28.     hardware_init();

    29.     PRINTF("\r\nSizeof test:\r\n");

    30.     PRINTF("\r\n-----------------Using sizeof in main-----------------\r\n");

    31.     for (i = 0; i < sizeof(test1)/sizeof(uint8_t); i++)
    32.     {
    33.         PRINTF("%d ", test1[i]);
    34.     }
    35.     PRINTF("\r\n");

    36.     PRINTF("\r\n------------Using sizeof in sub function--------------\r\n");

    37.     sizeof_Test(test1);

    38.     PRINTF("\r\n---------------------The right method-----------------\r\n");

    39.     right_test(test1, sizeof(test1)/sizeof(uint8_t));

    40.     /* This for loop should be replaced. By default this loop allows a single stepping. */
    41.     for (;;) {
    42.         ;
    43.     }
    44.     /* Never leave main */
    45.     return 0;
    46. }
    47. ////////////////////////////////////////////////////////////////////////////////
    48. // EOF
    49. ////////////////////////////////////////////////////////////////////////////////
    复制代码

    输出结果如下:

    3560.jpg

    三、感想与收获:
    1、传递数组给函数时,在函数内部使用数组长度时,一般要把数组长度使用参数同时传递进来。


    比如KSDK库中很多这样的函数:
    串口输出函数:
    3567.jpg
    I2C主机输出函数:
    3568.jpg
    SPI主机传输函数:
    3569.jpg

    等等……



    我知道答案 目前已有8人回答

    评分

    参与人数 1NXP金币 +20 收起 理由
    小七 + 20

    查看全部评分

    回复

    使用道具 举报

  • TA的每日心情
    开心
    2016-11-4 11:23
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    9

    主题

    235

    帖子

    0

    高级会员

    Rank: 4

    积分
    598
    最后登录
    2016-12-12
    发表于 2015-10-8 09:50:39 | 显示全部楼层
    谢谢分享
    freescaleic.org.png
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2017-2-9 14:16
  • 签到天数: 17 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    25

    主题

    1785

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2250
    最后登录
    2024-6-11
    发表于 2015-10-8 10:43:46 | 显示全部楼层
    不错,谢谢分享
    freescaleic.org.png
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16702
    最后登录
    1970-1-1
     楼主| 发表于 2015-10-8 22:54:45 | 显示全部楼层

    多谢支持
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-7-23 21:04
  • 签到天数: 103 天

    连续签到: 1 天

    [LV.6]常住居民II

    228

    主题

    5379

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    16702
    最后登录
    1970-1-1
     楼主| 发表于 2015-10-8 22:55:01 | 显示全部楼层

    多谢多谢
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    61

    主题

    965

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    2394
    最后登录
    1970-1-1
    发表于 2015-10-10 15:07:42 | 显示全部楼层
    学习            
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    20

    主题

    331

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1207
    最后登录
    2017-2-27
    发表于 2015-10-14 12:29:01 | 显示全部楼层
    谢谢楼主的分享               
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    11

    主题

    171

    帖子

    0

    中级会员

    Rank: 3Rank: 3

    积分
    386
    最后登录
    2015-10-22
    发表于 2015-10-16 17:39:05 | 显示全部楼层
    多谢分享,详细!!
    回复 支持 反对

    使用道具 举报

    该用户从未签到

    7

    主题

    250

    帖子

    0

    高级会员

    Rank: 4

    积分
    628
    最后登录
    2016-5-3
    发表于 2015-10-16 20:38:03 | 显示全部楼层

    貌似还不错哦,收下了先
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-7-22 10:24 , Processed in 0.108257 second(s), 31 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表