柔性数组笔记

#include <stdio.h>
#include <string.h>
int main()
{

    typedef struct recmd_hd_t_ {
        unsigned short magic;             /*magic(0X8D5D)*/
        unsigned int cmd_id;              /*命令号*/
        unsigned int data_len;            /*数据长度 pdata的长度*/
        int result_value;                 /*返回状态*/
        char result_msg[128];             /*返回消息为字符串log*/
        char pdata[0];                    /*返回数据,柔性数组*/
    }recmd_hd_t;
    recmd_hd_t recmd_hd_s = { 0 };
    recmd_hd_s.magic = 0X8D5D;
    recmd_hd_s.cmd_id = 0X51;
    recmd_hd_s.data_len = 0;
    recmd_hd_s.result_value = 0;
    strcpy(recmd_hd_s.result_msg, "led switch ok");
    printf("51 led switch ok %s",(char*)&recmd_hd_s);
}

 一段代码,牵扯出三个问题:


编译会不会报错?

不会


什么是柔性数组?

结构体的最后一个成员可以是一个大小不确定的数组,这个数组就叫做柔性数组;

https://xie.infoq.cn/article/6f1da2c291b1fb5f361dcb87d
https://juejin.cn/post/7239715688141946936
https://developer.aliyun.com/article/1241746


recmd_hd_t recmd_hd_s = { 0 };这样初始化正确吗?

唯一没有初始化到柔性数组

加一句recmd_hd_s.pdata = {0};试试再次编译

直接报错:

main.c: In function ‘main’:
main.c:14:20: error: expected expression before ‘{’ token
recmd_hd_s.pdata = {0};

那柔性数组应该怎么初始化?

在 C 语言中,不能像这样直接使用{0}来初始化结构体中的柔性数组成员。柔性数组必须在分配了足够的内存空间后,通过其他方式(如memset等函数)或者逐个元素赋值来初始化其内容。


printf打印什么?

51 led switch ok ],去掉柔性数组还是会打印这句话

%s打印的是字符串,直到遇到“\0”才结束,而这个结构体不存在“\0”

那我把柔性数组初始化试试?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
    typedef struct recmd_hd_t_ {
            unsigned short magic;                           /*magic(0X8D5D)*/
            unsigned int cmd_id;                            /*命令号*/
            unsigned int data_len;                          /*数据长度 pdata的长度*/
            int result_value;                               /*返回状态*/
            char result_msg[128];                           /*返回消息为字符串log*/
            char pdata[];                                   /*返回数据,柔性数组*/
    }recmd_hd_t;
    recmd_hd_t recmd_hd_s = { 0 };
    recmd_hd_t* ps = (recmd_hd_t*)malloc(sizeof(recmd_hd_t) + 6* sizeof(char));
    //recmd_hd_s.pdata = {0};
    recmd_hd_s.magic = 0X8D5D;
    recmd_hd_s.cmd_id = 0X51;
    recmd_hd_s.data_len = 0;
    recmd_hd_s.result_value = 0;
    strcpy(recmd_hd_s.result_msg, "led switch ok");
    int i = 0;
    for (i = 0; i < 5; i++)
    {
      ps->pdata[i] = i;
    }
    ps->pdata[6] = '\0';
    //printf("size = %d\n",sizeof(recmd_hd_s.pdata));
    printf("51 led switch ok %s",(char *)&recmd_hd_s);
    free(ps);
    ps = NULL;
}

还是打印51 led switch ok ]

  1. printf("51 led switch ok %s",(char *)&recmd_hd_s);这种打印方式是错误的。你不能直接将结构体的地址强制转换为char*并期望以字符串的方式打印。结构体中除了pdata之外的其他成员可能包含不可打印的字符,并且这种方式也不能正确地识别pdata的结束位置。

  2. 虽然给pdata[6]赋值为'\0'作为结束符,但这并不能保证整个结构体被正确地解释为字符串。

要正确打印结构体中的信息,可以分别打印各个成员,或者使用更合适的方式来处理和打印柔性数组的内

附:

 gcc -S main.c可以生成汇编代码main.s

char test[] = {0};不是不定长数组,它是一个定长数组,只是这个数组被初始化为只有一个元素且该元素值为 0。

char *test = {0};不是不定长数组,并且这种初始化方式严格来说在 C 语言中是错误的,但在某些编译器中可能不会报编译错误而是给出警告。

正确的初始化方式应该是:

  1. char *test = NULL;或者char *test = 0;表示将指针初始化为空指针。
  2. char *test = "some string";表示将指针指向一个字符串常量。

原因是{0}这种初始化方式不是指针的合法初始化语法,因为它试图用一个初始化列表来初始化一个指针,而指针应该被初始化为一个地址值(比如另一个变量的地址、动态分配的内存地址或者字符串常量的地址等)。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值