C语言易混淆知识点详解

C语言中容易混淆的知识点详解

C语言作为一门基础且强大的编程语言,有许多容易混淆的概念和特性。以下是C语言中一些常见易混淆知识点的详细解析:

1. 指针与数组

相似点:

c

复制

下载

int arr[10];
int *ptr = arr;
  • 都可以使用[]运算符访问元素:arr[3]ptr[3]都合法

  • 数组名在大多数情况下会退化为指向首元素的指针

区别:

特性数组指针
内存分配静态分配固定大小空间动态分配或指向已有空间
sizeof返回数组总大小返回指针本身大小
赋值操作不能直接赋值可以重新指向
作为参数传递退化为指针保持指针特性

关键点sizeof(arr)返回整个数组的字节大小,而sizeof(ptr)返回指针的大小(通常4或8字节)。

2. 指针常量和常量指针

const的不同位置含义不同:

c

复制

下载

int a = 10, b = 20;const int *p1 = &a;  // 指向常量的指针(指针可以改变,指向的值不能改变)
int *const p2 = &a;  // 常量指针(指针不能改变,指向的值可以改变)
const int *const p3 = &a;  // 指向常量的常量指针(都不能改变)

记忆技巧:从右向左读:

  • const int * → "指针指向一个const int"

  • int *const → "const指针指向int"

3. 结构体与联合体

结构体(struct):

c

复制

下载

struct Point {int x;int y;
}; // 占用sizeof(int)*2字节
  • 各成员有独立的内存空间

  • 总大小≥各成员大小之和(可能有内存对齐)

联合体(union):

c

复制

下载

union Data {int i;float f;char str[20];
}; // 占用最大成员的大小(此处为20字节)
  • 所有成员共享同一内存空间

  • 同一时间只能存储一个成员的值

4. 前置++与后置++

c

复制

下载

int i = 5;
int a = i++;  // a=5, i=6(后置:先使用值,再递增)
int b = ++i;  // b=7, i=7(前置:先递增,再使用值)

注意:在复杂表达式中使用可能引发未定义行为,如:

c

复制

下载

int i = 0;
int j = i++ + i++; // 未定义行为

5. 位运算与逻辑运算

位运算(按位操作):

c

复制

下载

&  // 按位与
|  // 按位或
^  // 按位异或
~  // 按位取反
<< // 左移
>> // 右移

逻辑运算(布尔操作):

c

复制

下载

&& // 逻辑与(短路求值)
|| // 逻辑或(短路求值)
!  // 逻辑非

关键区别

  • 位运算操作的是整数的二进制位

  • 逻辑运算操作的是表达式的真值(0为假,非0为真)

6. 数组指针与指针数组

c

复制

下载

int *p1[10];   // 指针数组:包含10个int指针的数组
int (*p2)[10]; // 数组指针:指向包含10个int的数组的指针

解析

  • p1是一个数组,其元素是指向int的指针

  • p2是一个指针,指向一个包含10个int的数组

7. 函数指针与指针函数

c

复制

下载

int *func(int);    // 指针函数:返回int指针的函数
int (*fp)(int);    // 函数指针:指向接受int参数并返回int的函数的指针

使用示例

c

复制

下载

int add(int a) { return a + 1; }
int (*fp)(int) = add;  // fp指向add函数
int result = fp(5);    // 通过函数指针调用

8. 内存分配方式

分配方式特点生命周期示例
静态存储编译时确定大小整个程序运行期间全局变量、static变量
栈存储自动分配释放函数执行期间局部变量
堆存储手动分配释放直到显式释放malloc/free分配

常见错误

c

复制

下载

char *getString() {char str[] = "hello"; // 栈内存,函数返回后无效return str;           // 错误!返回悬垂指针
}

9. 字符串与字符数组

c

复制

下载

char str1[] = "hello";    // 字符数组,可修改内容
char *str2 = "hello";     // 指向字符串常量的指针,内容不可修改str1[0] = 'H';  // 合法
str2[0] = 'H';  // 未定义行为(可能引发段错误)

关键点:字符串字面量存储在只读内存区域。

10. 预处理器与编译器

预处理器指令(编译前处理):

c

复制

下载

#define PI 3.14159    // 宏定义
#include <stdio.h>    // 文件包含
#ifdef DEBUG          // 条件编译
#endif

编译器处理:

  • 变量声明/定义

  • 函数定义

  • 类型检查等

常见混淆

c

复制

下载

#define SQUARE(x) x * x
int a = SQUARE(2+3); // 展开为2+3*2+3=11,而非预期的25

应定义为:

c

复制

下载

#define SQUARE(x) ((x)*(x))

11. 零值表示

类型零值表示
整型0
浮点型0.0
指针NULL或(void*)0
布尔型false
字符'\0'(空字符)

注意:NULL在C中通常是(void*)0,但在C++中是0nullptr

12. 类型转换

隐式类型转换(自动发生):

c

复制

下载

int i = 3.14;  // 3(截断小数部分)
double d = i;  // 3.0

显式类型转换(强制转换):

c

复制

下载

double d = 3.14;
int i = (int)d;  // C风格
int j = int(d);  // C++风格(在C中无效)

注意:强制转换可能丢失信息或导致未定义行为。

13. 可变参数函数

c

复制

下载

#include <stdarg.h>void printArgs(int count, ...) {va_list args;va_start(args, count);for(int i = 0; i < count; i++) {int val = va_arg(args, int);printf("%d ", val);}va_end(args);
}

注意事项

  • 必须至少有一个固定参数

  • 无法直接知道可变参数的数量和类型

  • 类型不安全,容易出错

14. 复杂声明解析

使用"右左法则"解析复杂声明:

  1. 从标识符开始

  2. 向右看,直到遇到)或声明结束

  3. 向左看,直到遇到(或声明开始

  4. 跳出括号,重复步骤2和3

示例

c

复制

下载

int (*(*func)(int))[10];

解析:

  1. func是一个指针

  2. 指向接受int参数并返回指针的函数

  3. 该指针指向包含10个int的数组

  4. 最终返回int

即:func是一个函数指针,该函数接受int参数并返回指向int数组的指针。

15. 未定义行为(UB)

C语言中有许多未定义行为,编译器不保证其行为:

c

复制

下载

int i = 0;
printf("%d %d\n", i++, i++); // 未定义int arr[5] = {1,2,3,4,5};
int *p = arr;
printf("%d\n", *p++ + *p++); // 未定义int a = 10;
a = a++; // 未定义

原则:避免在同一个表达式中对同一变量多次修改。

掌握这些易混淆知识点有助于编写更可靠、更高效的C代码,并避免常见的陷阱和错误。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/79581.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/79581.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MCP原理详解及实战案例(动嘴出UI稿、3D建模)

文章目录 MCP 原理介绍架构核心组件协议层传输层连接生命周期MCP与function calling: 互补关系 MCP python SDKMCP的优点 怎么用MCP&#xff1a;天气服务参考应用项目&#xff1a; REF 24年11月份&#xff0c;claude推出了模型上下文协议( MCP),作为一种潜在的解决方案&#xf…

2025年深圳杯数学建模(东三省)B题【颜色转换】原论文讲解(含完整python代码)

大家好呀&#xff0c;从发布赛题一直到现在&#xff0c;总算完成了2025年深圳杯数学建模&#xff08;东三省&#xff09;B题【颜色转换】完整的成品论文。 本论文可以保证原创&#xff0c;保证高质量。绝不是随便引用一大堆模型和代码复制粘贴进来完全没有应用糊弄人的垃圾半成…

cpp学习笔记1--class

2年前学过cpp&#xff0c;但是一直没有用到&#xff0c;现在要读研了&#xff0c;终于要用到了&#xff0c;重新拿出来看一看&#xff0c;觉得很多东西都能在c和python上看到影子。 #include "iostream" class Person { private:std::string name;int age;public://…

基于YOLOv的目标检测训练数据构建方法研究—图像采集、标注、划分与增强一体化流程设计

在目标检测任务中,高质量的训练数据是模型性能提升的关键。本文围绕 YOLOv 系列模型,系统性地研究了目标检测训练数据的构建方法,提出了一套从图像采集、标注、数据集划分到数据增强的一体化流程设计 。通过多源图像采集策略确保样本多样性,结合 LabelImg 工具完成 VOC 格式…

SQL数据库操作大全:从基础到高级查询技巧

大家好&#xff0c;欢迎来到程序视点&#xff01;我是你们的老朋友.小二&#xff01; SQL数据库操作核心语法精要 数据库基础操作 创建/删除数据库&#xff1a;CREATE DATABASE / DROP DATABASE 备份SQL Server&#xff1a;使用sp_addumpdevice和BACKUP DATABASE命令 数据库…

[2025]MySQL的事务机制是什么样的?redolog,undolog、binog三种日志的区别?二阶段提交是什么?ACID怎么保证的?主从复制的过程?

MySQL事务机制与日志系统详解 一、MySQL事务机制 1. 事务特性&#xff08;ACID&#xff09; 特性实现机制原子性(Atomicity)undo log回滚,(事务作为一个整体被执行&#xff0c;包含在其中的对数据库的操作要么全部被执行&#xff0c;要么都不执行)。一致性(Consistency)约束…

LLama-v2 权重下载

地址&#xff1a;llama模型 官方github仓库&#xff1a;llama仓库 注意点 网络代理位置&#xff1a;美国下面的国家选择 United States 克隆仓库后 运行bash download.sh输入邮箱收到的URL选择要下载的权重等待下载完成即可 有问题留言&#xff01;&#xff01;&#xff01…

zephyr OS架构下构建Nordic MCU boot

目录 概述 1. 软硬件环境 1.1 软件开发环境 1.2 硬件环境 2 MCU boot 2.1 核心功能 2.2 关键术语 2.3 重要字段介绍 3 VS-Code下创建MCU-BOOT项目 3.1 软件框架结构 3.2 创建测试项目 3.3 编译项目 3.3 固件在Flash中的分布 4 验证 4.1 烧写固件 ​ 4.2 代码…

【Mytais系列】介绍、核心概念

MyBatis 是一款优秀的 持久层框架&#xff0c;它通过简化 JDBC 操作、提供灵活的 SQL 映射能力&#xff0c;成为 Java 开发中处理数据库交互的核心工具之一。以下是 MyBatis 的核心框架和概念解析&#xff1a; 一、MyBatis 框架概述 1. 核心定位 作用&#xff1a;将 Java 对象…

IO模型和多路复用

一、IO模型的基础理解 什么是IO? IO全称是 Input/Output(输入/输出),在计算机科学里主要指程序与外部设备(硬盘、网络、用户终端等)进行数据交换的操作。首要特点是: IO通常很慢(从CPU和内存的视角看)经常需要等待外部设备响应1. 为什么要谈IO模型? 当一个程序需要…

深入理解 Bash 中的 $‘...‘ 字符串语法糖

在 Bash 脚本编程中&#xff0c;字符串处理是不可或缺的一部分。为了让开发者更高效地处理特殊字符和控制字符&#xff0c;Bash 引入了一种独特的字符串语法糖&#xff1a;$&#xff08;带单引号的 ANSI-C 风格字符串&#xff09;。这种语法来源于 C 语言的 ANSI-C 标准&#x…

用Python打造自己的专属命令行工具

在日常的开发和使用过程中&#xff0c;我们常常会编写一些实用的Python脚本&#xff0c;比如用来批量处理文件、获取系统信息等。然而&#xff0c;每次都要输入python script_name.py来运行脚本&#xff0c;时间一长难免觉得繁琐。要是能像使用系统自带的命令&#xff08;如ls、…

【KWDB 创作者计划】KWDB 2.2.0多模融合架构与分布式时序引擎

KWDB介绍 KWDB数据库是由开放原子开源基金会孵化的分布式多模数据库&#xff0c;专为AIoT场景设计&#xff0c;支持时序数据、关系数据和非结构化数据的统一管理。其核心架构采用多模融合引擎&#xff0c;集成列式时序存储、行式关系存储及自适应查询优化器&#xff0c;实现跨模…

学习Linux的第二天

如何在Linux环境下做开发 Linux的一些基操 Tips&#xff1a;平常最表层的是命令行模式&#xff0c;最多见这个默认叫做命令行模式 Vi操作是什么意思呢 就是在提示符输入vi a.c 是可以创建一个a.c这个文件并进入这个输入模式 按i可以输入代码 要退出的时候按esc 再按:(冒号…

链表操作练习

要求 现在有一个双向链表&#xff0c;里面要保存歌曲的名字&#xff1b;例如 蔡琴/渡口.mp3 我们把它定义在一个link.h文件中。 #ifndef LINK_H #define LINK_H #include <stdlib.h> #include <stdio.h> #include <string.h>typedef struct Node {//保存歌…

MATLAB制作散点图:从基础到进阶的三种类型讲解

一、什么是散点图 散点图是一种用来展示两个或多个变量之间关系的图表形式。它可以帮助我们直观地观察变量之间是否存在相关性、趋势或异常值&#xff0c;常用于数据分析的初步探索阶段。 二、三种类型散点图 1. 基本二维散点图&#xff1a;最简单、最常用 基本二维散点图的…

模块方法模式(Module Method Pattern)

&#x1f9e0; 模块方法模式&#xff08;Module Method Pattern&#xff09; 模块方法模式是一种结构型设计模式&#xff0c;它将复杂的操作分解成一系列相对简单、独立且单一职责的模块。每个模块负责完成一种具体的操作&#xff0c;其他模块或系统可以通过调用这些模块的公开…

Python中的JSON库,详细介绍与代码示例

目录 1. 前言 2. json 库基本概念 3. json 的适应场景 4. json 库的基本用法 4.1 导 json入 模块 4.2 将 Python 对象转换为 JSON 字符串 4.3 将 JSON 字符串转换为 Python 对象 4.4 将 Python 对象写入 JSON 文件 4.5 从 JSON 文件读取数据 4.6 json 的其他方法 5.…

网狐旗舰大联盟组件源码私测笔记:结构分层、UI重构与本地实操全流程

作为一套衍生于传统网狐架构的源码版本&#xff0c;大联盟这套源码组件可谓是在经典基础上进行了深度重塑。与老版死板的框架风格不同&#xff0c;它不仅对界面做了大刀阔斧的重构&#xff0c;还在组件层级的组织上做了优化。本文将基于一整套源码进行深度解析&#xff0c;强调…

STM32 PulseSensor心跳传感器驱动代码

STM32CubeMX中准备工作&#xff1a; 1、设置AD 通道 2、设置一个定时器中断&#xff0c;间隔时间2ms&#xff0c;我这里采用的是定时器7 3、代码优化01 PulseSensor.c文件 #include "main.h" #include "PulseSensor/PulseSensor.h"/******************…