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.mzph.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…