一、枚举
可以一一列举的值
1. 定义
enum Day
{
MON,
TUES,
WHNES,
THURS,
FRI,
SATUR,
SUN
};
enum Day d = FRI;
2. 枚举的优点
增加代码的可读性和可维护性
和#define定义的标识符比较
枚举有类型检查,更加严谨
防止命名污染(封装)
便于调试
test.c--预处理-->编译---->链接---->.exe
预处理阶段:枚举不替换
使用方便,一次可以定义多个常量
二、联合(共用体)
一种特殊的自定义类型
成员共用同一块空间
三、动态内存管理
1. malloc函数
void* malloc(size_t size);
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int arr[10] = { 0 };
//动态内存开辟
int* p = (int*)malloc(40);
if (p == NULL)
{
printf("%s\n", strerror(errno));
}
//使用
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
printf("%d\n", *(p + i));
}
return 0;
}
内存泄漏:拿去不用,又不还
变长数组:数组在指定大小时可以用变量
2.free函数
void free(void* ptr);
释放动态内存开辟的空间
3. calloc函数
void* calloc(size_t num,size_t size)
size_t num:开辟几个元素
size_t size:每个元素大小
开辟空间后会把内容初始化为0
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
//动态内存开辟,开辟10个整型的空间,40字节
int* p = (int*)calloc(10,sizeof(int));
if (p == NULL)
{
printf("%s\n", strerror(errno));
return 1;
}
//使用
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;
printf("%d\n", *(p + i));
}
//释放内存
free(p);
p = NULL;
return 0;
}
4. realloc函数
void* realloc(void* ptr , size_t size);
void* ptr:要调整的空间的起始位置的指针
size_t size:新空间的大小
扩容
情况1:直接追加在原来的空间不够,会覆盖别的内存空间
情况2:直接追加在原来的空间足够
三、常见动态内存相关错误
1. 对空指针的解引用操作
2. 对动态内存空间的越界访问
3. 对非动态空间使用free
4. 使用free释放动态内存开辟的一部分
5. 对同一块动态内存空间多次释放
四、柔性数组
C99中,结构体中
最后一个元素允许是未知大小的数值
叫做柔性数组成员
至少有一个其他成员
示例:
typrdef struct st_type
{
int i;
int a[0]; //柔性数组
//int a[ ]; //柔性数组
}type_a;
struct S
{
int n;
int arr[];//柔性数组
};
//柔性数组的使用
{
struct S* ps = malloc(sizeof(struct S) + 40);
//判断。空指针就不要继续往下走了
if(ps = NULL)
{
return 1;
}
ps->n = 100;
int i = 0;
for(i = 0; i < 10; i++)
{
ps->arr[i] = i;
}
for(i = 0; i < 10; i++)
{
printf("%d ",ps->arr[i]);
}
struct S* ptr = (struct S*)realloc(ps,sizeof(struct S) + 80);
if(ptr != NULL)
{
ps = ptr;
}
//释放
free(ps);
ps = NULL;
}
柔性数组的优势
方便释放内存
有利于访问速度