C語言核心知識點整理:結構體對齊、預處理、文件操作與Makefile

目錄

  1. 結構體的字節對齊
  2. 預處理指令詳解
  3. 文件操作基礎
  4. Makefile自動化構建
  5. 總結

1. 結構體的字節對齊

字節對齊原理

  • 內存對齊:CPU訪問內存時,對齊的地址能提高效率。操作系統要求變量按類型大小對齊。
  • 對齊規則:
    1. 每個成員的起始地址必須是min(成員類型大小, #pragma pack(n))的整數倍。
    2. 結構體總大小必須是最大成員對齊值的整數倍。
    3. 嵌套結構體需遵循相同規則。

示例分析

示例1
struct Test {int a;    // 4字節char b;   // 1字節
};
// 默認對齊(假設為4字節):
// 總大小 = 4(int) + 3字節填充 + 1(char) = 8字節

示例2(嵌套結構體)
struct A {double a;  // 8字節short b;   // 2字節
};struct Test {char a[20]; // 20字節int c;      // 4字節struct A d; // 12字節(8+4填充)char b;     // 1字節
};
// 總大小:20 + 4 + 12 + 1 + 3填充 = 40字節

調整對齊方式

  • #pragma pack(n):手動設置對齊粒度。
    #pragma pack(1) // 緊湊存儲
    struct Test {char a; // 1字節int b;  // 4字節(無填充)
    };
    #pragma pack() // 恢復默認
    


2. 預處理指令詳解

預處理階段

  • 作用:宏定義、頭文件包含、條件編譯等。
  • 流程:預處理 → 編譯 → 匯編 → 鏈接。

頭文件包含

  • 區別:
    • #include <stdio.h>:系統頭文件。
    • #include "test.h":當前目錄或自定義路徑。

頭文件重復包含防護

#ifndef _TEST_H_
#define _TEST_H_
// 頭文件內容
#endif

宏定義與條件編譯

無參宏
#define PI 3.14
#undef PI // 取消定義

有參宏
#define MUL(x,y) ((x)*(y)) // 避免運算優先級問題
#define ADD(x,y) (x + y)

條件編譯
#ifdef DEBUGprintf("Debug mode\n");
#elseprintf("Release mode\n");
#endif


3. 文件操作基礎

文件操作模式

模式描述示例模式
r只讀文本文件fopen("file.txt", "r")
w只寫文本文件(覆蓋)fopen("file.txt", "w")
a追加文本文件fopen("file.txt", "a")
rb只讀二進制文件fopen("file.dat", "rb")
wb只寫二進制文件(覆蓋)fopen("file.dat", "wb")

字符與字符串讀寫

fgetc/fputc
FILE *fp = fopen("file.txt", "w");
fputc('A', fp); // 寫入字符'A'
fclose(fp);

feof判斷文件結束
char ch;
FILE *fp = fopen("file.txt", "r");
while ((ch = fgetc(fp)) != EOF) { // EOF表示文件結束printf("%c", ch);
}
fclose(fp);

fgets/fputs按行讀寫
// 寫入
fputs("Hello World\n", fp);
// 讀取
char buf[256];
fgets(buf, sizeof(buf), fp); // 讀取一行,自動添加'\0'

格式化讀寫(fprintf/fscanf)

// 寫入
fprintf(fp, "a=%d,b=%.2f\n", 100, 3.14);
// 讀取
int a;
float b;
fscanf(fp, "a=%d,b=%f", &a, &b);

二進制文件操作(fread/fwrite)

typedef struct {char name[20];int id;
} STU;STU students[3] = { /* 初始化數據 */ };
// 寫入
FILE *fp = fopen("data.dat", "wb");
fwrite(students, sizeof(STU), 3, fp);
fclose(fp);// 讀取
STU read_data[3];
fp = fopen("data.dat", "rb");
fread(read_data, sizeof(STU), 3, fp);
fclose(fp);

文件隨機讀寫

  • 定位文件指針:

    fseek(fp, 50, SEEK_SET); // 從文件頭移動50字節
    fseek(fp, -50, SEEK_END); // 從文件尾回退50字節
    

  • 獲取當前位置:

    long pos = ftell(fp); // 當前位置偏移量
    rewind(fp); // 快速回到文件開頭
    


4. Makefile自動化構建

Makefile基礎規則

# 目標依賴規則
main: main.o add.o sub.ogcc main.o add.o sub.o -o mainmain.o: main.cgcc -c main.c

變量與自動變量

  • 普通變量:
    CC = gcc
    CFLAGS = -Wall -g
    

  • 自動變量:
    • $@:目標文件名
    • $^:所有依賴文件
    • $<:第一個依賴文件

模式規則與函數

# 通用編譯規則
%.o: %.c$(CC) -c $< -o $@ $(CFLAGS)# 查找所有.c文件
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c, %.o, $(SRCS))

多文件項目示例

DIR_SRC = ./src
DIR_OBJ = ./obj
SRCS = $(wildcard $(DIR_SRC)/*.c)
OBJS = $(patsubst $(DIR_SRC)/%.c, $(DIR_OBJ)/%.o, $(SRCS))main: $(OBJS)$(CC) $^ -o main$(DIR_OBJ)/%.o: $(DIR_SRC)/%.c$(CC) -c $< -o $@ -I./include.PHONY: clean
clean:rm -rf $(DIR_OBJ)/*.o main


5. 總結

  • 結構體對齊:通過#pragma pack優化內存布局,避免內存浪費。
  • 預處理:宏定義提升代碼復用性,條件編譯增強跨平臺兼容性。
  • 文件操作:區分文本與二進制模式,靈活使用fseekftell實現隨機讀寫。
  • Makefile:自動化構建簡化編譯流程,支持多文件項目管理。

希望這篇博客能幫助你系統掌握C語言核心知識點!如果有疑問或需要進一步解釋,歡迎在評論區交流!


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

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

相關文章

VBA+BOS單據+插件,解決計劃任務跟蹤的問題之二:導入ERP

第二步&#xff0c;就是要將拆分好的任務導入ERP了 1、將建一個BOS單據叫“任務池”&#xff0c;大概是這樣的 然后在拆分工具中進行導數據&#xff0c;點擊“數據導出準備”&#xff0c;跳轉到“導入ERP”界面&#xff0c;然后點“獲取數據”&#xff0c;將拆分好的數據轉過來…

使用uglifyjs對靜態引入的js文件進行壓縮

前言 因為有時候js文件沒有npm包&#xff0c;或者需要修改&#xff0c;只能引入靜態的js&#xff0c;那么這個時候就可以對js進行壓縮了。我其實想通過vite、webpack等插件進行壓縮的&#xff0c;可是他都不能定位到public目錄下面的文件&#xff0c;所以我只能自己壓縮了。編…

藍橋杯 web 水果拼盤 (css3)

做題步驟&#xff1a; 看結構&#xff1a;html 、css 、f12 分析: f12 查看元素&#xff0c;你會發現水果的高度剛好和拼盤的高度一樣&#xff0c;每一種水果的盤子剛好把頁面填滿了&#xff0c;所以咱們就只要讓元素豎著排列&#xff0c;加上是豎著&#xff0c;排不下的換行…

差分音頻轉單端音頻單電源方案

TI LMV321介紹 TI的LMV321是單通道的低壓軌到軌輸出運算放大器&#xff0c;適用于需要低工作壓、節省空間和低成本的應用。 其中&#xff0c;芯片設計中的軌到軌輸出&#xff08;Rail-to-Rail Output&#xff09; 是指通過特定的電路設計&#xff0c;使芯片&#xff08;如運算…

Pandas 庫

Pandas 是一個開源的數據分析和數據處理庫&#xff0c;它是基于 Python 編程語言的。 Pandas 提供了易于使用的數據結構和數據分析工具&#xff0c;特別適用于處理結構化數據&#xff0c;如表格型數據 Pandas 是數據科學和分析領域中常用的工具之一&#xff0c;它使得用戶能夠…

Vue 3 的<Teleport>功能與用法

Vue 3 的 <Teleport> 功能與用法 1. 基本用法 <Teleport> 是 Vue 3 的一個內置組件&#xff0c;允許將組件的內容渲染到 DOM 中的任意位置&#xff0c;而不改變其邏輯結構。以下是基本用法&#xff1a; 定義目標 DOM 元素&#xff1a;<div id"teleport-…

MySQL隨機獲取記錄之方法(The Method of Randomly Obtaining Records in MySQL)

MySQL中如何隨機獲取一條記錄 隨機獲取一條記錄是在數據庫查詢中常見的需求&#xff0c;特別在需要展示隨機內容或者隨機推薦的場景下。在 MySQL 中&#xff0c;有多種方法可以實現隨機獲取一條記錄&#xff0c;每種方法都有其適用的情況和性能特點。在本文中&#xff0c;我們將…

synchronized鎖升級詳解

synchronized鎖升級詳解 synchronized是Java中實現線程同步的關鍵字&#xff0c;它在JVM內部實現了鎖的升級機制&#xff0c;從偏向鎖到輕量級鎖再到重量級鎖&#xff0c;這種優化是為了減少鎖操作帶來的性能開銷。 1. 鎖的四種狀態 Java對象頭中的Mark Word會記錄鎖的狀態&…

C++函數如何返回多個參數

在編程中&#xff0c;我們經常會遇到需要函數返回多個值的場景。雖然 C 函數不能直接返回多個參數&#xff0c;但通過一些間接的方法&#xff0c;我們可以輕松實現這一需求。本文將詳細介紹幾種常見的實現方式&#xff0c;并分析它們的優缺點和適用場景。 1. 引言 在 C 中&…

最新版PhpStorm超詳細圖文安裝教程,帶補丁包(2025最新版保姆級教程)

目錄 前言 一、PhpStorm最新版下載 二、PhpStorm安裝 三、PhpStorm補丁 四、運行PhpStorm 前言 PhpStorm 是 JetBrains 公司推出的 專業 PHP 集成開發環境&#xff08;IDE&#xff09;&#xff0c;專為提升 PHP 開發效率設計。其核心功能包括智能代碼補全、實時語法錯誤檢…

【雜談】Godot4.4導出到Android平臺(正式導出)

學博而后可約&#xff0c;事歷而后知要。 目錄 一、準備二、Gradle構建三、配置Java SDK四、配置Android SDK五、配置密鑰 一、準備 本文在前文【雜談】Godot4.4導出到安卓平臺&#xff08;調試導出&#xff09;的基礎上&#xff0c;進行正式導出。調試導出并不是真正的編譯導…

隔行換色總結

功能效果展示&#xff1a; 第一種思路&#xff1a; 使用數組&#xff0c;將數組的內容渲染到頁面上&#xff0c;序號也就是將數組的下標輸出到第一個td上&#xff0c;將數組的內容輸出到第二個td上&#xff0c;&#xff08;使用拼接字符串&#xff09; 具體操作&#xff1a; …

使用文本翻譯API打破語言障礙

一、引言 在當今全球化的商業環境中&#xff0c;企業面臨著前所未有的語言挑戰。無論是出口商品、引進技術&#xff0c;還是與國際客戶進行交流&#xff0c;語言障礙始終是一個亟待解決的問題。文本翻譯API作為一款高效、穩定的工具&#xff0c;支持多種語言的翻譯&#xff0c…

【unity游戲開發入門到精通——動畫篇】Animator2D序列幀動畫

考慮到每個人基礎可能不一樣&#xff0c;且并不是所有人都有同時做2D、3D開發的需求&#xff0c;所以我把 【零基礎入門unity游戲開發】 分為成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】&#xff1a;主要講解C#的基礎語法&#xff0c;包括變量、數據類型、運算符、…

深入解析 Jenkins Agent 的 .jnlp 啟動文件

&#x1f9e9; 深入解析 Jenkins Agent 的 .jnlp 啟動文件 在 Jenkins 中&#xff0c;通過 JNLP&#xff08;Java Network Launch Protocol&#xff09;方式連接 Agent 是一種常見且靈活的方式。你可能曾見過類似這樣的命令&#xff1a; java -jar agent.jar -jnlpUrl file:/…

定積分__

practice makes perfect 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 若被積函數在積分區間上是可積的&#xff0c;那么變限積分函數在這個區…

Three.js 系列專題 7:性能優化與最佳實踐

內容概述 隨著 3D 場景復雜度的增加,性能優化變得至關重要。Three.js 項目可能因幾何體數量、紋理大小或渲染設置而變慢。本專題將介紹減少 draw call、優化紋理和使用調試工具的最佳實踐。 學習目標 學會減少 draw call 和幾何體復雜度。掌握紋理壓縮與內存管理。使用 Stat…

CentOS 7安裝Python3.12

文章目錄 使用pyenv安裝python3.12一、gitub下載pyenv二、升級GCC三.升級openssl這樣python3.12.9就完成安裝在CentOS上啦&#xff01; 使用pyenv安裝python3.12 一、gitub下載pyenv https://github.com/pyenv/pyenv 按照README&#xff0c;pyenv教程安裝即可 二、升級GCC 安…

【C++】優先級隊列+反向迭代器

priority_queue的介紹 通常用堆來實現&#xff0c;能在O(log n)的時間復雜度內插入和提取最高&#xff08;或最低&#xff09;優先級的元素。 優先隊列是一種容器適配器&#xff0c;根據嚴格的弱排序標準&#xff0c;它的第一個元素總是它所包含的元素中最大的(默認情況)。此…

mysql鏡像創建docker容器,及其可能遇到的問題

前提&#xff0c;已經弄好基本的docker服務了。 一、基本流程 1、目錄準備 我自己的資料喜歡放在 /data 目錄下&#xff0c;所以老規矩&#xff1a; 先進入 /data 目錄&#xff1a; cd /data 創建 mysql 目錄&#xff1a; mkdir mysql 2、鏡像查找 docker search hub.ra…