C語言-柔性數組成員的使用

文章目錄

    • 摘要
    • 柔性數組成員
      • 基本使用
      • 細節探究
    • 零長度數組-定長數組-變長數組

摘要

本文先介紹柔性數組成員(flexible array member)的基本使用,然后介紹其內存結構。最后,補充了一些數組相關的其他概念。


柔性數組成員

基本使用

參考: 【C語言內功修煉】柔性數組的奧秘_數組_Albert Edison_InfoQ寫作社區

C99之后,可以使用 flexible array member。它大概長下面這個樣子。

struct buffer {unsigned int len;char contents[]; // flexible array member
};
  • flexible array member 可以認為是零長度數組實現的一個特例(下文會介紹零長度數組)。sizeof(buffer.contents)的值為0。
  • flexible array member 只能作為結構體的最后一個成員

下面我們看一個demo,來體驗下 flexible array member 帶來的便利。

這個demo比較簡單。分配一個緩沖區,往里面寫內容。這個緩沖區保有緩沖區的大小。

// demo-1.c
#include <stdio.h>
#include <stdlib.h>struct buffer {unsigned int len;char contents[];
};int main(int argc, char *argv[]) {unsigned int buf_len = 100;// construct a bufferstruct buffer *buffer =malloc(sizeof(struct buffer) + buf_len * (sizeof(char)));buffer->len = buf_len;snprintf(buffer->contents, buffer->len, "%s", "hello world");printf("%s\n", buffer->contents);free(buffer);return 0;
}

如果不使用柔性數組,下面這樣,可以實現同樣的功能。而且也非常簡單。

//demo-2.c
#include <stdio.h>
#include <stdlib.h>struct buffer {unsigned int len;char *contents;
};int main(int argc, char *argv[]) {unsigned int buf_len = 100;// construct a bufferstruct buffer *buffer =malloc(sizeof(struct buffer) + buf_len * (sizeof(char)));buffer->contents = (char *)buffer + sizeof(struct buffer);buffer->len = buf_len;snprintf(buffer->contents, buffer->len, "%s", "hello world");printf("%s\n", buffer->contents);free(buffer);return 0;
}

這兩者有什么區別呢?下一節我們來探究下。


細節探究

參考:Zero Length (Using the GNU Compiler Collection (GCC))

首先,上面demo中,struct buffer的大小是不同的。我這里直接給出大小。這個大小可以通過打印或者gdb方式獲取。

// 當前環境
Linux da1234cao 5.15.133.1-microsoft-standard-WSL2 x86_64 GNU/Linux// demo-2中buffer結構體
// sizeof(struct buffer) == 16 ; sizeof(char*) == 8
struct buffer {unsigned int len;char *contents;
};// demo-1中buffer結構體
// sizeof(struct buffer) == 4 ; sizeof(buffer.contents) == 0
struct buffer {unsigned int len;char contents[];
};// 修改下flexible array member的類型
// sizeof(struct buffer) == 8 ; sizeof(buffer.contents) == 0
struct buffer {unsigned int len;long contents[];
};

可以看到 flexible array member 的空間大小為0。但由于尾部填充,flexible array member 可能會導致結構體的空間變大,其空間對齊方式,與 flexible array member 的類型相同。我們知道指針是可以進行加法運算的,同樣,它的偏移量由 flexible array member 的類型決定。

此時,我們來繪制下包含 flexible array member 結構體的內存結構。

在這里插入圖片描述

而上面demo-2.c中的結構體內存則是這樣。

在這里插入圖片描述

最后,我不建議將一個包含 flexible array member 的結構體,嵌套到其他結構體中,雖然這樣做是允許的。如果你想這么做的話,請自行參考官方手冊。我沒太看懂這塊。

Tips: 如果結構體中包含 flexible array member , 可以放心的將結構體進行memset操作。flexible array member 總是指向后面的位置。


零長度數組-定長數組-變長數組

通過上一節,我們已經掌握了 flexible array member 的使用。這里補充些其他相關的基本概念。

零長度數組

可以認為 flexible array member 是零長度數組的一種實現。 flexible array member 是在C99之后出現的。在C99之前,程序員們這樣使用零長度數組。

struct line {int length;char contents[0]; // [] 中多了一個0
};

上面的代碼和 flexible array member 效果相同。但是,在C99之后,請使用 flexible array member 。按照手冊寫代碼,我不知道有沒有什么原因或者好處。

定長數組

在C99之前,數組在創建的時候,必須給定一個常量。這個數組長度在編譯的時候,已經確定。

// 定長數組
char array[10];// 下面這個也是定長數組
// 可以參考下 《C語言程序設計 -- 現代方法》8.1.2 數組初始化
// 如果給定了初始化式,可以省略掉數組的長度; 編譯器利用初始化式的長度來確定數組的大小。數組仍然有固定數量的元素;
char array[] = {'a', 'b', 'c'};

變長數組

參考: Variable Length (Using the GNU Compiler Collection (GCC))

數組長度在運行時確定。

int n = 10;
char array[n];

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/718207.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/718207.shtml
英文地址,請注明出處:http://en.pswp.cn/news/718207.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[項目設計] 從零實現的高并發內存池(一)

&#x1f308; 博客個人主頁&#xff1a;Chris在Coding &#x1f3a5; 本文所屬專欄&#xff1a;[高并發內存池] ?? 前置學習專欄&#xff1a;[Linux學習] ? 我們仍在旅途 ? 目錄 前言 項目介紹 1.內存池 1.1 什么是內存池 池化技術 內存池 1.2 為什…

word使用bib添加參考文獻

文章目錄 安裝TexLive安裝bibtex4word使用在word中添加參考文獻使用bibtex4word在word中添加參考文獻設置參考文獻格式為畢業論文格式 參考 安裝TexLive 從下載地址下載鏡像iso文件texlive2023.iso雙擊打開iso鏡像文件運行 install-tl-windows.bat點擊安裝非常非常非常耐心地安…

Shell學習 - 2.20 Shell exit命令:退出當前進程

exit 是一個 Shell 內置命令&#xff0c;用來退出當前 Shell 進程&#xff0c;并返回一個退出狀態&#xff1b;使用$?可以接收這個退出狀態&#xff0c;這一點已在《Shell $?》中進行了講解。 exit 命令可以接受一個整數值作為參數&#xff0c;代表退出狀態。如果不指定&…

Linux命令-clock命令(用于調整 RTC 時間)

說明 clock命令用于調整 RTC 時間。 RTC 是電腦內建的硬件時間&#xff0c;執行這項指令可以顯示現在時刻&#xff0c;調整硬件時鐘的時間&#xff0c;將系統時間設成與硬件時鐘之時間一致&#xff0c;或是把系統時間回存到硬件時鐘。 語法 clock [--adjust][--debug][--dir…

客戶端/服務器協議是啥意思?

客戶端/服務器協議是指在網絡通信中&#xff0c;客戶端和服務器之間進行數據傳輸時所使用的規定。簡單來說&#xff0c;客戶端是用戶使用的設備&#xff0c;如電腦或手機&#xff0c;而服務器則是提供數據或服務的遠程計算機。當客戶端需要獲取數據或服務時&#xff0c;它會向服…

【RT-DETR有效改進】結合SOTA思想利用雙主干網絡改進RT-DETR(全網獨家創新,重磅更新)

一、本文介紹 本文給大家帶來的改進機制是結合目前SOTAYOLOv9的思想利用雙主干網絡來改進RT-DETR&#xff08;本專欄目前發布以來改進最大的內容&#xff0c;同時本文內容為我個人一手整理全網獨家首發 | 就連V9官方不支持的模型寬度和深度修改我都均已提供&#xff0c;本文內…

【活動】金三銀四,前端工程師如何把握求職黃金期

隨著春意盎然的氣息彌漫大地&#xff0c;程序員群體中也迎來了一年一度的“金三銀四”求職熱潮。這個時間段對于廣大前端工程師而言&#xff0c;不僅象征著生機勃發的新起點&#xff0c;更是他們職業生涯中至關重要的轉折點。眾多知名公司在這一時期大規模開啟招聘通道&#xf…

ChatGPT 4.0使用之論文閱讀

文章目錄 閱讀環境準備打開AskYourPDF進入主站 粗讀論文直接通過右側邊框進行提問選中文章內容翻譯或概括插圖的理解 總結 擁有了GPT4.0之后&#xff0c;最重要的就是學會如何充分發揮它的強大功能&#xff0c;不然一個月20美元的費用花費的可太心疼了&#xff08;家境貧寒&…

WP外貿營銷型網站模板

WordPress外貿獨立站主題 簡潔實用的WordPress外貿獨立站主題&#xff0c;適合時尚服裝行業搭建wordpress企業官網使用。 零件配件WordPress外貿建站模板 汽車行業零配件WordPress外貿建站模板&#xff0c;賣配件、零件的外貿公司可以使用的WordPress主題。 https://www.jia…

RocketMQ—消費者的兩種消費模式

RocketMQ—消費者的兩種消費模式 RocketMQ消息消費的模式分為兩種&#xff1a;負載均衡模式和廣播模式&#xff0c;負載均衡模式表示多個消費者交替消費同一個主題里面的消息&#xff1b;廣播模式表示每個每個消費者都消費一遍訂閱的主題的消息。 負載均衡模式 CLUSTERING 集…

vue2 element 實現表格點擊詳情,返回時保留查詢參數

先直觀一點&#xff0c;上圖 列表共5條數據&#xff0c;準備輸入Author過濾條件進行查詢 進入查看詳情頁&#xff0c;就隨便搞了個按鈕 啥都沒調啦 點擊返回后 一開始準備用vuex做這個功能&#xff0c;后來放棄了&#xff0c;想到直接用路由去做可能也不錯。有時間再整一套…

一篇文章了解和使用Map和Set(HashMap/TreeMap/HashSet/TreeSet)

[本節目標] *掌握HashMap/TreeMap/HashSet/TreeSet的使用 *掌握了解HashSet和HashSet背后的哈希原理和簡單的實現 1. 搜索樹 1.1 概念 二叉搜索樹又稱二叉排序樹,它或者是一顆空樹,或者是具有以下性質的二叉樹: 1.若它的左子樹不為空&#xff0c;則左子樹上所有節點的值都…

【一起學習Arcade】(2):Geometry函數

第二篇記錄下Geometry函數&#xff0c;相對于其它語言&#xff0c;Arcade對Geometry的支持是一大亮點&#xff0c;這使得它的上限被大大提高了。 三、Geometry函數 1、Angle【角度】 單位為度&#xff08;0-360&#xff09;&#xff0c;正北為90度&#xff0c;只考慮x-y平面。…

07OpenCV 圖像模糊

文章目錄 圖像掩膜操作模糊原理均值濾波高斯濾波中值濾波雙邊濾波算子代碼 圖像掩膜操作 圖像掩膜操作 模糊原理 Smooth/Blur是圖像處理中最簡單和常用的操作之一 使用操作的原因之一就是為了給圖像預處理時候減低噪聲 圖像噪聲是指存在于圖像數據中的不必要的或多余的干擾信…

RK3568開發筆記-qt程序運行報錯Failed to move cursor on screen

目錄 前言 一、qt程序運行報錯 二、異常解決 總結 前言 最近在進行 RK3568 平臺上的 Qt 程序開發時&

使用 Docker 部署 MrDoc 在線文檔管理系統

1&#xff09;MrDoc 介紹 MrDoc 簡介 MrDoc 覓思文檔&#xff1a;https://mrdoc.pro/ MrDoc 使用手冊&#xff1a;https://doc.mrdoc.pro/p/user-guide/ MrDoc 可以創建各類私有化部署的文檔應用。你可以使用它進行知識管理、構建團隊文庫、制作產品手冊以及在線教程等。 Mr…

在Java中如何使用Lambda表達式進行函數式編程

在Java中如何使用Lambda表達式進行函數式編程 在Java中&#xff0c;使用Lambda表達式進行函數式編程主要涉及以下幾個步驟&#xff1a; 理解函數式接口&#xff1a; 函數式接口是一個只有一個抽象方法的接口。Java 8引入了FunctionalInterface注解&#xff0c;用于標記這樣的接…

linux安全--DNS欺騙,釣魚網站搭建

目錄 一&#xff0c;實驗準備 首先讓client能上網 1&#xff09;實現全網互通&#xff0c;實現全網互通過程請看 2&#xff09;SNAT源地址轉換 3&#xff09;部署DHCP服務 4)配置DHCP服務 5&#xff09;啟動服務 6&#xff09;安裝DNS服務 7&#xff09;DNS配置 8)啟動DNS…

【Python筆記-設計模式】策略模式

一、說明 策略模式是一種行為設計模式&#xff0c;它定義了一系列算法&#xff0c;將每個算法封裝起來&#xff0c;并使它們可以互相替換。 (一) 解決問題 在需要根據不同情況選擇不同算法或策略&#xff0c;規避不斷開發新需求后&#xff0c;代碼變得非常臃腫難以維護管理。…

如何將圖片保存成視頻(imageio、opencv和ffmpeg)

測試下來發現&#xff0c;imageio 速度比 cv2 的要慢&#xff0c;所以普通保存推薦 cv2&#xff0c;要gpu加速需要額外配置或者修改 imageio 底層也是調用的ffmpeg&#xff0c;以下是python代碼 import imageio import os# 讀取要保存為視頻的圖片 images [] for filename …