目录

1.宏定义(#define)

2.问问

malloc 

数组

3.格式

无参宏(对象式宏) #define 宏名 宏体

带参宏(函数式宏) #define 宏名(参数列表) 宏体

4.注意点

# 和 ## 运算符


1.宏定义(#define)

 是 C/C++ 语言中一个非常强大的预处理指令。它属于预处理器的一部分在代码被真正编译之前,预处理器会处理所有的宏。

宏定义的本质是文本替换。它用一个标识符(宏名)来代表一段代码片段(宏体)

2.问问

  1. 预处理工作是系统引用预处理程序对源程序中的预处理部分做处理。--运行之前,不占用资源
  2. 而预处理部分是指以“#”开头的、放在函数之外的、一般放在源文件的前面的预处理命令,如:包括命令 #include,宏命令 #define 等。--指以“#”开头的 
  3. 可以出现在任何一行。--非强制要求第一行
  4. 实现宏定义、条件编译等等  --可以!实现宏定义和条件编译
  5. #define   --而非 #DEFINE ,C语言区分大小写
  6. 一行上只能有一条有效的预处理命令
  7. #define  PI 3.14  ---注意【 #define 宏名 宏体】 三者之间均有一个空格  ,且末尾没有分号
  8. #define AA     --错,没有宏体
    #define AA 11;--错,不可以有分号
    #defineAA11    --错,没有空格
    #define int int--错,使用关键字 
    #Define int int--错,是define,这是关键字,不可Define
    
    
    #define aa 11 --对,习惯宏名(aa )大写,但是没有强制要求大写,大小写均可
    #define Aa 11 --对,定义标识符Aa为11,! 
                  --【 如果说定义标识符Aa值为整数10】,这个说法错误,因【没有类型限制】
                  --【 如果说定义标识符Aa赋值10】,这个说法错误,因【没有赋值】,只是替换
                   --在【预处理程序】中进行替换,而非 【编译程序】或【运行程序】

  9. 输出结果:3,3,3 
    #include <stdio.h>
    #include <stdlib.h>
    main()
    {int *a,*b,*c;
    a=b=c=(int*)malloc(sizeof(int));  //三个指针指向同一块内存地址。
                                     //后续的 *a=1、*b=2、*c=3 会覆盖同一内存位置的值,最终该地址存储的值为 3。
    *a=1;
    *b=2,*c=3;
    a=b;//由于 a b 和 c 已指向同一地址,此操作无实际意义。最终 *a、*b、*c 均为 3
    print"%d,%d,%d\“,*a,*b,*c);
    }
    
    ---*********************-----------
    独立内存分配
    若需存储不同值,应为每个指针分配独立内存:
    a = (int*)malloc(sizeof(int));
    b = (int*)malloc(sizeof(int));
    c = (int*)malloc(sizeof(int));
    
    

    malloc时动态内存分配函数,用于申请一块连续的指定大小的内存块区域以void*类型返回分配的内存区域地址 。它从堆(heap)中分配指定大小的内存块,并返回一个指向该内存块起始地址的指针。如果分配失败,返回 NULL。

        malloc 的函数原型:void* malloc(size_t size);

  • size_t size:需要分配的内存大小,以字节为单位。

  • malloc函数返回值:成功则返回指向被分配内存的指针,否则返回空指针失败NULL。

  • malloc函数头文件:#include<malloc.h> 或 #include<stdlib.h>

  • malloc函数使用注意事项:malloc函数的返回的是无类型指针,在使用时一定要强制转换为所需要的类型。

  • malloc函数使用形式
    malloc所开辟空间类型:mall0c只开辟空间,不进行类型检查,只是在使用的时候进行类型的强转举个例子:"我”开辟你所需要大小的字节大小空间,至于怎么使用是你的事

  • mallo函数返回的实际是一个无类型指针,必须在其前面加上指针类型强制转换才可以使用

  • 指针自身=(指针类型*)malloc(sizeof(指针类型))

          int *ptr = (int *)malloc(sizeof(int));
        

   标准使用形式: 指针变量 = (目标类型*)malloc(分配字节数);

   标准使用形式: 指针变量 = (目标类型*)malloc(sizeof(目标类型) * 元素数量);

// 分配单个int的空间
int *singleInt = (int *)malloc(sizeof(int));

// 分配10个int的数组空间
int *intArray = (int *)malloc(sizeof(int) * 10);

// 分配结构体空间
struct Student *stu = (struct Student *)malloc(sizeof(struct Student));
  • 类型无关:malloc只负责分配指定大小的内存块,不关心这块内存将用于存储什么类型的数据
  • 无初始化:malloc分配的内存区域不会被初始化,其内容是不确定的(可能是随机值)
  • 强制转换:由于malloc返回的是void指针,必须在使用时进行强制类型转换才能安全访问

malloc 

数组

malloc 在运行时动态分配内存,需要手动指定大小,属于动态内存分配数组在编译时分配固定大小的连续内存空间,属于静态内存分配。

申请内存位置不同,malloc在堆区

需手动调用 free 释放,否则可能导致内存泄漏。

数组在栈区
malloc头文件是<stdlib.h>数组头文件是<stdio.h>
malloc 可根据需求动态调整内存大小(需配合 realloc),适合处理不确定数据量的场景。数组的大小必须在编译时确定,不可改变
malloc 分配的内存默认未初始化,需手动赋值或使用 calloc 初始化为零。数组定义时可直接初始化(如 int arr[3] = {1,2,3};)
int *dynamic_arr = (int*)malloc(5 * sizeof(int)); // 堆区分配
dynamic_arr[0] = 10;
free(dynamic_arr); // 需显式释放

int static_arr[5]; // 栈区分配,自动管理
static_arr[0] = 10;

  • 运行时才确定数据大小

  • 需要长期存活的内存(跨函数作用域)

  • 实现动态数据结构(如链表、树)

  • 数据量已知且固定

  • 需要快速栈内存分配

  • 避免手动内存管理

malloc 更灵活但可能引入碎片和分配开销数组的访问通常更快(栈内存局部性优)

3.格式

无参宏(对象式宏) #define 宏名 宏体
#define PI 3.14159
#define ARY_SIZE 100
#define GREETING "Hello, World!"
带参宏(函数式宏) #define 宏名(参数列表) 宏体
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define SQUARE(x) ((x) * (x))
#define SQUARE2(x) x * x

4.注意点

define SQUARE(x) x * x
int result = SQUARE(3 + 2); // 替换为:3 + 2 * 3 + 2,结果是 11,而不是 25
# 和 ## 运算符

#(字符串化运算符):将宏的参数转换为字符串常量。

#define STRINGIFY(x) #x
char* str = STRINGIFY(hello); // 替换为:char* str = "hello";

##(连接运算符):将两个标记连接成一个。

#define CONCAT(a, b) a##b
int xy = CONCAT(10, 20); // 替换为:int xy = 1020;

int var_name = 100;
int CONCAT(var, _name) = 200; // 创建一个名为 var_name 的变量

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐