# 一些函数:
# <stdarg.h >
# 1. 可变参数
int func_name(int num, ...); // 声明方式,num 代表输入的个数,当然也可以加一些其他的要传的变量在前面 |
在函数定义中创建一个 va_list 类型变量,该类型是在 stdarg.h 头文件中定义的。
va_list valist;
使用 int 类型的参数(一般就是上面的 arg1)和 va_start() 宏来初始化 va_list 变量为一个参数列表。宏 va_start() 是在 stdarg.h 头文件中定义的。
// 为 num 个参数初始化 valist | |
va_start(valist, num); |
使用 va_arg() 宏和 va_list 变量来访问参数列表中的每个项。
for (i = 0; i < num; i++){ | |
sum += va_arg(valist, int); // 假设后续输入的都是 int 类型 | |
} |
使用宏 va_end() 来清理赋予 va_list 变量的内存。
var_end(valist);
输出平均值:
#include <stdio.h>
#include <stdarg.h>double average(int num,...)
{
va_list valist;
double sum = 0.0; int i;/* 为 num 个参数初始化 valist */
va_start(valist, num);/* 访问所有赋给 valist 的参数 */
for (i = 0; i < num; i++){
sum += va_arg(valist, int);}
/* 清理为 valist 保留的内存 */
va_end(valist); return sum/num;}
int main()
{
printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5));
printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15));
}
# <string.h>
# 1.memcpy()/memmove()
-
memcpy () 函数:用于从源内存区域复制数据到目标内存区域。它接受三个参数,即目标内存区域的指针、源内存区域的指针和要复制的数据大小(以字节为单位)。
void *memcpy(void *dest, const void *src, size_t n);
//n 是字节数,dest 是要复制到的地方的首地址,src 则是要复制的数据的首地址
复制字符数组数据:
#include <stdio.h>
#include <string.h>
int main() {
char source[] = "Hello, World!";
char target[20];
memcpy(target, source, strlen(source) + 1);// 复制 '\0'
// 其他类型用 sizeof 即可
printf("%s\n", target);
return 0; }
-
memmove () 函数:类似于 memcpy () 函数,但它可以处理重叠的内存区域(对于 memcpy (), 此时行为是未定义的)。它接受三个参数,即目标内存区域的指针、源内存区域的指针和要复制的数据大小(以字节为单位)。
用法同上。如果重叠,就将 src 的对应个数的数据直接复制过去(覆盖导致的变化不会影响后续的复制)
比如
#include <stdio.h>
#include <string.h>
int main() { char arr[11] = "abcdefghij"; memmove(arr + 1, arr + 2, 5); printf("%s\n", arr); return 0;}
// 输出是 acdefgghij
2.memset
# 一些额外的东西:
# 1. 柔性数组(C99 以上)
可以使用它来实现动态可变长的结构体。
定义:
typedef struct FlexibleStruct { | |
int count; | |
int data[];// 相当于 int data [0]; | |
} FlexibleStruct0; |
注意:
一个结构体中只能有一个可变长的成员,并且该成员必须是最后一个成员。
FlexibleStruct *createFlexibleStruct(int numElements) { | |
// 计算总共需要分配的内存大小,包括结构体本身和柔性数组部分 | |
// 柔性数组本身不算在 sizeof 中(这个 data [] 它不占内存) | |
size_t totalSize = sizeof(FlexibleStruct) + numElements * sizeof(int); | |
// 分配内存 | |
FlexibleStruct *fs = (FlexibleStruct *)malloc(totalSize); | |
fs->count = numElements; | |
return fs; | |
} |
要一次性分配内存
排序算法:
1. 插入排序
#include <stdio.h> | |
// 函数声明 | |
void insertion_sort(int arr[], int len); | |
int main() { | |
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 }; | |
int len = sizeof(arr) / sizeof(arr[0]); // 计算数组长度 | |
insertion_sort(arr, len); // 调用插入排序函数 | |
// 打印排序后的数组 | |
for (int i = 0; i < len; i++) { | |
printf("%d ", arr[i]); | |
} | |
return 0; | |
} | |
// 插入排序函数 | |
void insertion_sort(int arr[], int len) { | |
for (int i = 1; i < len; i++) { | |
int temp = arr[i]; // 当前待插入的元素 | |
int j = i; | |
// 向右移动大于 temp 的元素 | |
while (j > 0 && arr[j - 1] > temp) { | |
arr[j] = arr[j - 1]; | |
j--; | |
} | |
arr[j] = temp; // 插入元素到正确位置 | |
} | |
} |
2. 希尔排序
它不是选择而是插入的改进
#include <stdio.h> | |
// 函数声明 | |
void shell_sort(int arr[], int len); | |
int main() { | |
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 }; | |
int len = sizeof(arr) / sizeof(arr[0]); // 计算数组长度 | |
shell_sort(arr, len); // 调用希尔排序函数 | |
// 打印排序后的数组 | |
for (int i = 0; i < len; i++) { | |
printf("%d ", arr[i]); | |
} | |
return 0; | |
} | |
// 希尔排序函数 | |
void shell_sort(int arr[], int len) { | |
// 计算初始间隔 | |
for (int gap = len / 2; gap > 0; gap /= 2) { | |
// 对每个间隔进行插入排序 | |
for (int i = gap; i < len; i++) { | |
int temp = arr[i]; // 当前待插入的元素 | |
int j = i; | |
// 移动大于 temp 的元素 | |
while (j >= gap && arr[j - gap] > temp) { | |
arr[j] = arr[j - gap]; | |
j -= gap; | |
} | |
arr[j] = temp; // 插入元素到正确位置 | |
} | |
} | |
} |
3. 归并排序
迭代法
#include <stdio.h> | |
#include <stdlib.h> | |
// 函数声明 | |
int min(int x, int y); | |
void merge_sort(int arr[], int len); | |
int main() { | |
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 }; | |
int len = sizeof(arr) / sizeof(arr[0]); // 计算数组长度 | |
merge_sort(arr, len); // 调用归并排序函数 | |
// 打印排序后的数组 | |
for (int i = 0; i < len; i++) { | |
printf("%d ", arr[i]); | |
} | |
return 0; | |
} | |
// 返回两个数中的最小值 | |
int min(int x, int y) { | |
return x < y ? x : y; | |
} | |
// 归并排序函数 | |
void merge_sort(int arr[], int len) { | |
int* a = arr; | |
int* b = (int*) malloc(len * sizeof(int)); | |
if (b == NULL) { // 检查内存分配是否成功 | |
fprintf(stderr, "Memory allocation failed\n"); | |
exit(EXIT_FAILURE); | |
} | |
for (int seg = 1; seg < len; seg += seg) { | |
for (int start = 0; start < len; start += seg + seg) { | |
int low = start; | |
int mid = min(start + seg, len); | |
int high = min(start + seg + seg, len); | |
int k = low; | |
int start1 = low, end1 = mid; | |
int start2 = mid, end2 = high; | |
// 合并两个子数组 | |
while (start1 < end1 && start2 < end2) { | |
b[k++] = a[start1] < a[start2] ? a[start1++] : a[start2++]; | |
} | |
while (start1 < end1) { | |
b[k++] = a[start1++]; | |
} | |
while (start2 < end2) { | |
b[k++] = a[start2++]; | |
} | |
} | |
// 交换数组指针 | |
int* temp = a; | |
a = b; | |
b = temp; | |
} | |
// 如果 a 和 arr 不相同,则将 a 的内容复制回 arr | |
if (a != arr) { | |
for (int i = 0; i < len; i++) { | |
b[i] = a[i]; | |
} | |
b = a; | |
} | |
free(b); // 释放内存 | |
} |
递归法
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
// 函数声明 | |
void merge_sort_recursive(int arr[], int reg[], int start, int end); | |
void merge_sort(int arr[], const int len); | |
int main() { | |
int arr[] = { 22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70 }; | |
int len = sizeof(arr) / sizeof(arr[0]); // 计算数组长度 | |
merge_sort(arr, len); // 调用归并排序函数 | |
// 打印排序后的数组 | |
for (int i = 0; i < len; i++) { | |
printf("%d ", arr[i]); | |
} | |
return 0; | |
} | |
// 递归实现归并排序 | |
void merge_sort_recursive(int arr[], int reg[], int start, int end) { | |
if (start >= end) | |
return; | |
int mid = start + (end - start) / 2; | |
int start1 = start, end1 = mid; | |
int start2 = mid + 1, end2 = end; | |
merge_sort_recursive(arr, reg, start1, end1); | |
merge_sort_recursive(arr, reg, start2, end2); | |
int k = start; | |
while (start1 <= end1 && start2 <= end2) { | |
reg[k++] = arr[start1] < arr[start2] ? arr[start1++] : arr[start2++]; | |
} | |
while (start1 <= end1) { | |
reg[k++] = arr[start1++]; | |
} | |
while (start2 <= end2) { | |
reg[k++] = arr[start2++]; | |
} | |
// 使用 memcpy 进行数组复制,提高效率 | |
memcpy(arr + start, reg + start, (end - start + 1) * sizeof(int)); | |
} | |
// 归并排序入口函数 | |
void merge_sort(int arr[], const int len) { | |
int* reg = (int*)malloc(len * sizeof(int)); | |
if (reg == NULL) { // 检查内存分配是否成功 | |
fprintf(stderr, "Memory allocation failed\n"); | |
exit(EXIT_FAILURE); | |
} | |
merge_sort_recursive(arr, reg, 0, len - 1); | |
free(reg); // 释放内存 | |
} |
4. 快速排序
迭代法
#include <stdio.h> | |
// 范围结构体 | |
typedef struct _Range { | |
int start, end; | |
} Range; | |
// 创建新的范围 | |
Range new_Range(int s, int e) { | |
Range r; | |
r.start = s; | |
r.end = e; | |
return r; | |
} | |
// 交换两个整数 | |
void swap(int *x, int *y) { | |
int t = *x; | |
*x = *y; | |
*y = t; | |
} | |
// 快速排序函数 | |
void quick_sort(int arr[], const int len) { | |
if (len <= 0) | |
return; // 避免 len 等于负值时引发段错误(Segment Fault) | |
Range r[len]; | |
int p = 0; | |
r[p++] = new_Range(0, len - 1); | |
while (p > 0) { | |
Range range = r[--p]; | |
if (range.start >= range.end) | |
continue; | |
int mid = arr[(range.start + range.end) / 2]; // 选取中间点为基准点 | |
int left = range.start, right = range.end; | |
do { | |
while (arr[left] < mid) ++left; // 检测基准点左侧是否符合要求 | |
while (arr[right] > mid) --right; // 检测基准点右侧是否符合要求 | |
if (left <= right) { | |
swap(&arr[left], &arr[right]); | |
left++; | |
right--; // 移动指针以继续 | |
} | |
} while (left <= right); | |
if (range.start < right) r[p++] = new_Range(range.start, right); | |
if (range.end > left) r[p++] = new_Range(left, range.end); | |
} | |
} | |
int main() { | |
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70}; | |
int len = sizeof(arr) / sizeof(arr[0]); // 计算数组长度 | |
quick_sort(arr, len); // 调用快速排序函数 | |
// 打印排序后的数组 | |
for (int i = 0; i < len; i++) { | |
printf("%d ", arr[i]); | |
} | |
return 0; | |
} |
递归法
#include <stdio.h> | |
// 交换两个整数 | |
void swap(int *x, int *y) { | |
int t = *x; | |
*x = *y; | |
*y = t; | |
} | |
// 递归实现快速排序 | |
void quick_sort_recursive(int arr[], int start, int end) { | |
if (start >= end) | |
return; | |
int mid = arr[end]; | |
int left = start, right = end - 1; | |
while (left < right) { | |
while (left < right && arr[left] < mid) | |
left++; | |
while (left < right && arr[right] >= mid) | |
right--; | |
swap(&arr[left], &arr[right]); | |
} | |
if (arr[left] >= arr[end]) | |
swap(&arr[left], &arr[end]); | |
else | |
left++; | |
quick_sort_recursive(arr, start, left - 1); | |
quick_sort_recursive(arr, left + 1, end); | |
} | |
// 快速排序入口函数 | |
void quick_sort(int arr[], int len) { | |
quick_sort_recursive(arr, 0, len - 1); | |
} | |
int main() { | |
int arr[] = {22, 34, 3, 32, 82, 55, 89, 50, 37, 5, 64, 35, 9, 70}; | |
int len = sizeof(arr) / sizeof(arr[0]); // 计算数组长度 | |
quick_sort(arr, len); // 调用快速排序函数 | |
// 打印排序后的数组 | |
for (int i = 0; i < len; i++) { | |
printf("%d ", arr[i]); | |
} | |
return 0; | |
} |