(四)C语言柔性数组、指针赋值

一、柔性数组

今天看了公司的代码,发现一个很奇怪的问题,后来自己写了类似代码,我先把代码贴出来吧。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef struct
{
    char  ucDstMac[6];
    char  ucSrcMac[6];
    int usType;               
    int usLen;              
    char  ucCode;          
    char  ucSeq;             
    char  ucSlot;           
    char  ucInfo[];
}DEV_CARD_MSG_S;

int main(void)
{
    int i = 0;
    DEV_CARD_MSG_S* DS1;
    char data[64];
    DS1 = (DEV_CARD_MSG_S*)malloc(sizeof(DEV_CARD_MSG_S));
    memset(data,0,sizeof(data));
    DS1 = (DEV_CARD_MSG_S*)data;
    DS1-> ucCode = 'A';
    DS1-> ucInfo[6] = 'B';
    printf("DS1-> ucCode=%c\nDS1-> ucInfo[6]=%c\n",DS1-> ucCode,DS1-> ucInfo[6]);
    for(i=0;i<64;i++)
    printf("data[%d]=%c\n",i,data[i]);
    
    return 0;
}

好奇怪啊,有木有,结构体中竟然定义了一个包含0个元素的数组,当时看到这里就晕晕的。后来查找了资料,才知道这就是传说中柔性数组,柔性数组一般应用在结构体中,数组大小可变的场合中。

我们分析上述程序,data是一个占64字节的字符数组,DS1 = (DEV_CARD_MSG_S*)这行代码相当于给DS1结构体分配了64字节的地址,而这个结构体中定义时只申请了23字节的地址,此时还省64-23=41字节的地址会全部分配给DEV_CARD_MSG_S结构体中的ucInfo数组,因此此时即使我们写出DS1->ucInfo[40]='D'也是合法的,因为我们为数组ucInfo申请了41字节的地址空间。

上述程序打印如下,只贴出一部分:

(二)指针赋值

我们看上面代码执行的结果,发现我们代码中只操作了DS1结构体指针,结果data数组的值也跟着变化了,而且地址是对应的。刚开始看到这种神奇的代码我也好好奇。我们看到程序中有这么一行代码:DS1 = (DEV_CARD_MSG_S*)data;这是指针之间的赋值,也就是说结构体DS1和data数组在内存中占用的地址是一样的。其实这个代码和下面这个是类似的,我们看下面的代码就可以很好地理解了。

#include<stdio.h>
int main()
{
    int *P = NULL;
    int a = 10;
    P = &a;
    *P =20;
    printf(" a = %d\n*P = %d\n",a,*P);
    printf("&a = %p\n P = %p\n",&a,P);
    return 0;
}

程序执行结果如下:

我们看到,我们操作P指针也就是操作a变量,同时他们两个占用的内存地址是一样的。因此只要*P的值改变了,a的值也就跟着改变了。这个特点很重要,在工程中应用的还是蛮多的。

 

posted @ 2016-04-08 15:56  xtusir  阅读(1142)  评论(0编辑  收藏  举报