不定长的指针数组 里面存字符串_c-柔性数组学习

bb88f95ff8f9831bf43848dde90984a5.png

在学习PHP的字符串时,我们知道存储在zend_string中,来看一下

struct _zend_string {zend_refcounted_h gc;zend_ulong        h;                /* hash value */size_t            len;char              val[1];};

这里 char val[1] 只占一个字节内存,我们可能会感到奇怪,长度为1的数组如何存的下大于1长度的字符串呢,其实这里利用了C的柔性数组。

柔性数组可以认为是边长数组,只能出现在结构体的最后一个成员位置,它可以自动扩容。


上面是柔性数组的一种形式,柔性数组还有一种形式 char val[], 这是由于遵循的标准不一样。

来看例子

int main(){    /**     * 柔性数组可以理解为非定长数组,实际的长度是动态的     * 1、必须要声明在结构体的结尾     * 2、不占用内存     * 3、使用内存缓冲区     * 4、自动扩容     */    struct User    {        int age;        int stuID;        char address[]; // 结构体结尾    };    // 8 两个int 4 + 4    // char address[] 不占内存    printf("size of user %lu ", sizeof(struct User));    struct User jack;    // address赋值    jack.address[0] = 'b';    jack.address[1] = 'e';    jack.address[2] = 'i';    jack.address[3] = 'j';    jack.address[4] = 'i';    jack.address[5] = 'n';    jack.address[6] = 'g';    jack.stuID = 1;    // 8 说明  address并没有占用内存    printf("size of jack %lu ", sizeof(jack));    // beijing    printf("address is %s ", jack.address);    printf("*************下面使用指针来************ ");    struct Stu    {        int age;        int stdID;        char *address;    };    // 16 int + int + char的指针 4+4+8    // 明显指针是占用内存的    printf("size of std %lu ", sizeof(struct Stu));    char myAddress[7];    myAddress[0] = 't';    myAddress[1] = 'i';    myAddress[2] = 'a';    myAddress[3] = 'n';    myAddress[4] = 'j';    myAddress[5] = 'i';    myAddress[6] = 'n';    struct Stu rose;    rose.address = myAddress;    rose.stdID = 2;    printf("size of rose %lu ", sizeof(rose));    printf("address is %p ", rose.address);    printf("address[0] is %c ", *(rose.address));    printf("address[1] is %c ", *(rose.address+1));    printf("*************柔性数组的第二种方式************ ");    struct zend_string    {        int refcount;        int len;        char val[1];    };    // 12 字节   int +int + char内存对齐  4*3    printf("size of zend_string %lu ", sizeof(struct zend_string));    struct zend_string str1;    str1.len = 5;    str1.val[0] = 'h';    str1.val[1] = 'e';    str1.val[2] = 'l';    str1.val[3] = 'l';    str1.val[4] = 'o';    // 12  val赋值之后仍然内存空间没有变化    printf("size of zend_string %lu ", sizeof(str1));    // hello    printf("size of zend_string.val %s ", str1.val);    /**     *    struct _zend_string { *           zend_refcounted_h gc; *           zend_ulong        h; *           size_t            len; *           char              val[1];     *    };     *     *     *     *     *     */    /**     *  val[] 与 val[1] 两种实现方式不太一样,因为标准不一样     *  c99 标准中允许 char val[] 这种定义作为柔性(不定长)数组出现,他不占用内存空间     *  c99之前只支持 char val[1]这种格式,占用1个字节     */    return 0;}

总结:

柔性数组可以理解为非定长数组,实际的长度是动态的

  • 必须要声明在结构体的结尾
  • 不占用内存
  • 使用内存缓冲区
  • 自动扩容
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值