搞定 C 语言核心概念:10 大高频对比

C语言核心概念对比解析

目录

1.  全局变量和局部变量的区别

2.  #include<>和#include""的区别

3.  头文件#ifndef、#define、#endif的作用

4.  数组名与指针的区别

5.  const和#define的区别

6.  strcpy与memcpy的区别

7.  sizeof与strlen的区别

8.  结构体和共用体的区别

9.  malloc和calloc的区别

10.  堆和栈的区别


1.  全局变量和局部变量的区别

全局变量:

  • 在函数外部声明的变量,整个程序都可以访问。
  • 声明时会被默认初始化,可以在任何函数中使用。
  • 生命周期长,整个程序执行期间都存在。
  • 全局变量存储在全局数据区(data)中。
#include <stdio.h>

// 全局变量
int count = 0;

// 函数
void add() {
    count = count + 1;  // 函数内部可以直接使用全局变量
}

int main() {
    printf("初始值: %d\n", count);
    
    add();  // 调用函数,count会变成1
    printf("第一次加后: %d\n", count);
    
    add();  // 再调用一次,count会变成2
    printf("第二次加后: %d\n", count);
    
    return 0;
}

局部变量:

  • 在函数内部或代码块内部声明的变量,只能在所属的函数或代码块中访问。
  • 声明时没有默认初始化,需要手动赋值才能使用。
  • 生命周期短,只在所属的函数或代码块的执行期间存在。
  • 局部变量存储在栈区(stack)。
#include <stdio.h>

void function1() {
    int a = 10;  // 局部变量a,只在function1内有效
    printf("function1中的a: %d\n", a);
}

void function2() {
    int a = 20;  // 局部变量a,只在function2内有效(与function1的a无关)
    printf("function2中的a: %d\n", a);
}

int main() {
    int a = 5;  // 局部变量a,只在main函数内有效
    
    printf("main中的a: %d\n", a);
    function1();
    function2();
    printf("main中的a还是: %d\n", a);  // a的值没有改变
    
    return 0;
}

2.  #include<>和#include""的区别

使用#include<>:

  • 用于包含系统提供的标准库头文件。
  • 在编译器的搜索路径中寻找头文件。
  • 编译器会先在系统的标准头文件目录中查找,如果找不到则报错。

使用#include"":

  • 用于包含用户自定义的头文件或项目中使用的其他非系统头文件。
  • 在当前源文件的相对路径或指定的绝对路径中寻找头文件。
  • 编译器会首先在当前源文件所在目录中查找,如果找不到再根据指定的路径查找。

3.  头文件#ifndef、#define、#endif的作用

  • #ifndef:用于判断当前头文件是否已经被包含。如果该宏之前没有被定义过,则继续编译下面的代码。如果该宏之前已被定义过,则跳过下面的代码,直接到 #endif。
  • #define:用于定义一个宏。通过定义一个特定的宏名称,例如MY_HEADER_H表示头文件已被包含。
  • #endif:用于结束 #ifndef / #define / #endif 块。标记了头文件的结束位置。
#ifndef MYHEADER_H     // 如果 MYHEADER_H 还没有被定义
#define MYHEADER_H     // 定义 MYHEADER_H

extern int sum = 100;  // 常量定义

void Hello();       // 函数声明

#endif               // 结束条件编译

4.  数组名与指针的区别

数组名:

  • 是一个常量指针,指向数组的首元素。
  • 大小固定为整个数组的大小。
  • 无法被改变或重新赋值。
  • 无法进行指针运算。

指针:

  • 是一个变量,存储一个内存地址。
  • 大小固定为指针类型的大小。
  • 可以指向任意类型的对象。
  • 可以被改变或重新赋值。
  • 可以进行指针运算,如加法、减法等。

5.  const和#define的区别

  • const是一种编译器关键字,而#define是预处理器指令。const在编译阶段进行处理,而#define在预处理阶段进行处理。
  • const定义的常量具有类型,而#define没有。const在声明时需要指定常量的类型,编译器会进行类型检查。而#define只是简单的文本替换,没有类型检查。
  • const定义的常量有作用域限制,可以根据声明位置的不同而有不同的作用域。而#define定义的常量没有作用域限制,整个程序中都有效。
  • const生成符号表中的一个符号,有明确的名字和类型,可以进行调试和符号查找。而#define没有生成符号表,不会产生对应的符号。
特性const#define
处理阶段编译阶段预处理阶段
类型检查
作用域有作用域限制整个文件有效
调试支持支持,在符号表中不支持,预处理后消失
内存分配分配内存不分配内存,只是替换
安全性更安全容易出错

6.  strcpy与memcpy的区别

strcpy:

  • 用于字符串拷贝。
  • 源字符串中的内容会被复制到目标字符串中,直到遇到字符串结束符 ’\0’。
  • 目标字符串必须有足够的空间来存储被复制的内容,否则可能导致缓冲区溢出。

memcpy:

  • 用于字节级别的内存拷贝。
  • 可以拷贝任意类型的内存块,不仅限于字符串。
  • 不会检查字符串结束符,通过指定要拷贝的字节数进行拷贝。
  • 可以用于拷贝部分或完整的数组、结构体等。

7.  sizeof与strlen的区别

sizeof:

  • 用于获取数据类型或变量的字节大小。
  • 可以接受多种参数,包括数据类型、变量名、数组名等。
  • 返回的是整个数据类型或变量占用的内存空间大小。

strlen:

  • 用于获取以’\0’结尾的字符串的实际长度。
  • 在运行时计算,需要遍历字符串的内容来确定长度。
  • 返回的是字符串中的字符个数,不包括字符串结束符’\0’。

8.  结构体和共用体的区别

结构体:

  • 成员在内存中独立存储,每个成员占用独立的内存空间。
  • 内存占用是成员之和,每个成员都占用独立的空间。
  • 成员可以同时被访问,通过成员名字来访问。
  • 适合存储和处理多个不同类型的数据,如员工信息、图形对象等。

共用体:

  • 成员共享同一块内存空间,只能存储一个成员的值。
  • 内存占用是最大成员的大小,所有成员共享该空间。
  • 成员只能同时访问其中的一个,存取时要明确指定。
  • 适合存储和处理只使用其中一种类型的数据,可以节省内存空间或进行数据类型转换。

9.  malloc和calloc的区别

malloc:

  • malloc 分配的内存是未初始化的,其中的字节内容是不确定的(可能是随机值)。
  • 如果内存分配失败,malloc 返回一个空指针 NULL,可以通过检查返回值来判断是否分配成功。

calloc:

  • calloc 分配的内存会被初始化为全0。
  • calloc 在分配失败时会自动抛出错误(异常),可以使用异常处理机制来捕获和处理错误。

10.  堆和栈的区别

特性栈 (Stack)堆 (Heap)
管理方式自动分配释放手动分配释放
速度快(一级缓存)慢(二级缓存/主存)
生命周期函数作用域内直到手动释放
空间大小较小(通常~2MB)较大(可达GB级别)
碎片问题无碎片可能产生内存碎片
生长方向向低地址生长向高地址生长
使用场景局部变量、函数参数动态数据结构、大内存需求

千题千解·嵌入式工程师八股文详解_时光の尘的博客-优快云博客

C语言_时光の尘的博客-优快云博客

内容概要:本文详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问题,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于转型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照文档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

时光の尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值