一、柔性数组

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

#include<stdio.h>
#include<string.h>
#include<stdlib.h> typedef struct
{
char ucDstMac[];
char ucSrcMac[];
int usType;
int usLen;
char ucCode;
char ucSeq;
char ucSlot;
char ucInfo[];
}DEV_CARD_MSG_S; int main(void)
{
int i = ;
DEV_CARD_MSG_S* DS1;
char data[];
DS1 = (DEV_CARD_MSG_S*)malloc(sizeof(DEV_CARD_MSG_S));
memset(data,,sizeof(data));
DS1 = (DEV_CARD_MSG_S*)data;
DS1-> ucCode = 'A';
DS1-> ucInfo[] = 'B';
printf("DS1-> ucCode=%c\nDS1-> ucInfo[6]=%c\n",DS1-> ucCode,DS1-> ucInfo[]);
for(i=;i<;i++)
printf("data[%d]=%c\n",i,data[i]); return ;
}

好奇怪啊,有木有,结构体中竟然定义了一个包含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 = ;
P = &a;
*P =;
printf(" a = %d\n*P = %d\n",a,*P);
printf("&a = %p\n P = %p\n",&a,P);
return ;
}

程序执行结果如下:

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

(四)C语言柔性数组、指针赋值的更多相关文章

  1. C语言柔性数组和动态数组

    [前言]经常看到C语言里的两个数组,总结一下. 一.柔性数组 参考:https://www.cnblogs.com/veis/p/7073076.html #include<stdio.h> ...

  2. C语言柔性数组讲解

    #include<stdio.h> typedef struct _SoftArray{ int len; int array[]; }SoftArray; int main() { ; ...

  3. C语言柔性数组

    结构中最后一个元素允许是未知大小的数组,这个数组就是柔性数组.但结构中的柔性数组前面必须至少一个其他成员,柔性数组成员允许结构中包含一个大小可变的数组,sizeof返回的这种结构大小不包括柔性数组的内 ...

  4. C++语言中数组指针和指针数组彻底分析

    #################################                              ##       基本知识               ##        ...

  5. C语言的数组指针

    数组(Array)是一系列具有相同类型的数据的集合,每一份数据叫做一个数组元素(Element).数组中的所有元素在内存中是连续排列的,整个数组占用的是一块内存.以int arr[] = { 99, ...

  6. c语言的数组指针与指针数组

    1. 数组指针:指向数组的指针是数组指针 先看下面一段代码: #include <stdio.h> int main(void) { int m[10]; printf("m = ...

  7. [拾零]C语言的数组指针

    为了强化记忆,从而写笔记保留. 数组指针,顾名思义,是在说一个指针,这个指针是指向数组的. 区别于指针数组 int* p[5] = NULL; //指针数组 基类型 int* int (*p)[5] ...

  8. C语言 结构体指针赋值 incompatible types when assigning to type 'char[20]' from type 'char *'

    strcpy(pstudent->name, "guo zhao wei "); 为什么错误,该怎么写,(红色行)     追问 为什么不能直接赋值啊, 追答 用char n ...

  9. C语言提高 (4) 第四天 数组与数组作为参数时的数组指针

    1昨日回顾 const int 和 int const是一样的 const char *p;值不变 char * const p; 指针不能变 编译器对参数的退化: 第三种模型: 三级指针 三级指针局 ...

随机推荐

  1. 每日一九度之 题目1030:毕业bg

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2046 解决:894 题目描述:     每年毕业的季节都会有大量毕业生发起狂欢,好朋友们相约吃散伙饭,网络上称为“bg”.参加不同团体的b ...

  2. prop

    用法:prop(属性|key,value|fn) 用例:点击全选/取消全选 // 全选 和全不选 $("#check_all").click(function () { if ($ ...

  3. c# monitor锁

    当多个线程在并发的时候,难免会碰到相互冲突的事情,比如最经典的ATM机的问题,并发不可怕,可怕的是我们没有能力控制. 线程以我的理解可以分为三种 ① 锁. ② 互斥. ③ 信号. 好,这一篇主要整理“ ...

  4. 山东理工大学第七届ACM校赛-飞花的鱼塘 分类: 比赛 2015-06-26 10:30 43人阅读 评论(0) 收藏

    飞花的鱼塘 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 一日,飞花壕在稷下湖游玩,忽然,飞花巨有了一个养鱼的想法,于是,他大手 ...

  5. JAVA基础知识之网络编程——-基于UDP协议的通信例子

    UDP是一种不可靠的协议,它在通信两端各建立一个socket,这两个socket不会建立持久的通信连接,只会单方面向对方发送数据,不检查发送结果. java中基于UDP协议的通信使用DatagramS ...

  6. ThreadPoolExecutor的学习

    Java多线程之ThreadPoolExecutor 线程池的作用就是使用更少的线程, 来执行更多的任务, 以达到线程的充分利用. 从ThreadPoolExecutor类的构造方法学习: /** * ...

  7. 改变了一下blog的主题,很开心

    调整了一下博客的样式,之前一直想改变下,一直不会这次终于摸索出来一点,不过是最简单的,就是在管理里面的设置,可以定制css代码,修改修改,页面就跟着你的想法走了,有时间好好修改下,暂时这个样子,简单大 ...

  8. Struts2的处理结果(一)——处理结果的配置

    Struts2的处理结果(一) --处理结果的配置 1.处理结果 在Action处理完用户请求之后,并不会直接生成响应,而是把一个字符串返回给Struts2框架,再由框架选择此字符串结果对应的物理视图 ...

  9. .Net文件上传--小数据--un

    文件上传控件:FileUpload - 控件,界面+方法+属性Button/LinkButton/ImageButton FileUpload控件:1.SaveAs("要上传到服务器的绝对路 ...

  10. .Net鼠标随动窗口

    就像QQ宠物或者迅雷悬浮窗口一样,鼠标点下去窗体跟着鼠标动 主要是两个时间的加载 MouseDown和MouseMove事件 MouseDown事件: private int _StartX ;//鼠 ...