1、输入三个字符串按照字母顺序从小到大输出
#include <cstdio> // 包含cstdio头文件,用于输入输出函数
#include <cstring> // 包含cstring头文件,用于字符串处理函数
#define N 20 // 定义字符串的最大长度为20
// 函数:交换两个字符串的内容
void sort(char* strA, char* strB) {
char temp[N]; // 定义一个临时数组,用于存储其中一个字符串的内容
strcpy(temp, strA); // 将strA的内容复制到临时数组temp中
strcpy(strA, strB); // 将strB的内容复制到strA中
strcpy(strB, temp); // 将临时数组temp的内容(原来的strA)复制到strB中
}
int main() {
char str1[N], str2[N], str3[N]; // 定义三个字符串,用于存储用户输入
puts("input the str1,str2,str3:"); // 提示用户输入三个字符串
scanf("%s %s %s", str1, str2, str3); // 读取用户输入的三个字符串
// 如果第一个字符串比第二个大,交换它们
if (stricmp(str1, str2) > 0) { // 使用stricmp进行不区分大小写的比较
sort(str1, str2); // 调用sort函数交换str1和str2的内容
}
// 如果第二个字符串比第三个大,交换它们
if (stricmp(str2, str3) > 0) {
sort(str2, str3); // 调用sort函数交换str2和str3的内容
}
// 如果第一个字符串比第三个大,交换它们
if (stricmp(str1, str3) > 0) {
sort(str1, str3); // 调用sort函数交换str1和str3的内容
}
// 输出排序后的字符串
printf("%s %s %s", str1, str2, str3);
return 0; // 程序结束
}
在C中,数组名在大多数情况下会被视为指向数组第一个元素的指针。当将数组作为参数传递给函数时,实际上传递的是数组的首地址,也就是指针的值传递。这时候函数内部的指针是原指针的一个副本,但它们指向的是同一块内存地址。
当使用strcpy函数时,比如strcpy(strA, strB),这里的strA和strB是传入的指针,指向main函数中的数组。strcpy的作用是将strB指向的字符串内容复制到strA指向的内存空间中。因此,操作的是指针所指向的内存区域,而不是指针本身的值。这样,原数组的内容就被修改了。
虽然指针本身是副本,但它们指向的是同一块内存地址。通过副本指针去修改内存中的数据,自然会影响原数据,因为原指针也指向同一块内存。
图解:
1、初始状态
2、strcpy(temp,strA);
3、strcpy(strA,strB);
4、strcpy(strB,temp);
2、输入10个数,最小的数和第一个数交换,最大的数和最后一个数交换
#include <cstdio>
#define N 5 // 定义数组长度
// 输入函数:为数组元素赋值
void input(int* num) {
for (int i = 0; i < N; ++i) {
printf("input the No.%d num:", i + 1);
scanf("%d", num + i); // 等价于 &num[i],指针偏移方式访问数组元素
}
}
// 获取最小值索引函数
int getMinIndex(int* num) {
int minIndex = 0; // 初始化为首元素索引
int min = *num; // 初始化为首元素值
for (int i = 0; i < N; ++i) {
if (min > *(num + i)) { // 发现更小值时更新
min = *(num + i);
minIndex = i;
}
}
return minIndex;
}
// 获取最大值索引函数
int getMaxIndex(int* num) {
int maxIndex = 0; // 初始化为首元素索引
int max = *num; // 初始化为首元素值
for (int i = 0; i < N; ++i) {
if (max < *(num + i)) { // 发现更大值时更新
max = *(num + i);
maxIndex = i;
}
}
return maxIndex;
}
/**
* 极值交换函数(已修复原逻辑问题)
* 执行顺序:
* 1. 交换最小值到数组首部
* 2. 在更新后的数组中重新获取最大值位置
* 3. 交换最大值到数组末尾
*/
void minAndMax(int* num) {
// 第一阶段:处理最小值交换 --------------------------
int minIndex = getMinIndex(num); // 获取原始最小值位置
int temp;
// 执行最小值交换操作
temp = *num; // 暂存原首元素值
*num = *(num + minIndex); // 将最小值写入首元素位置
*(num + minIndex) = temp; // 将原首元素值写入原最小值位置
// 第二阶段:处理最大值交换 --------------------------
/* 关键改进点:在交换最小值后重新获取最大值位置
* 解决原版本最大值可能被意外移动的问题
*/
int maxIndex = getMaxIndex(num); // 获取当前数组最大值位置
// 执行最大值交换操作
temp = *(num + maxIndex); // 暂存当前最大值
*(num + maxIndex) = *(num + N-1); // 将末元素值写入原最大值位置
*(num + N-1) = temp; // 将最大值写入末元素位置
}
// 输出数组内容
void output(int* num) {
for (int i = 0; i < N; ++i) {
printf("%d ", num[i]); // 使用数组下标方式访问元素
}
}
int main() {
int num[N]; // 声明整型数组
input(num); // 调用输入函数
minAndMax(num); // 执行极值交换
output(num); // 输出结果
return 0; // 程序正常退出
}
3、输入n个整数实现向后或者向前移动m个单位
#include <cstdio>
#define N 10 // 定义数组最大容量(最多存储10个元素)
/**
* 实现数组循环右移操作
* @param a 要操作的数组指针(会被修改)
* @param len 数组实际使用的有效长度(必须小于等于N)
* @param place 实际移动的位置数(经过规范化处理后的值)
*
* 实现原理:
* 1. 创建临时数组存储移动后的结果
* 2. 通过取模运算实现循环右移
* 3. 将结果复制回原数组
*/
void move(int* a, int len, int place) {
int temp[len]; // 创建临时数组用于存储移动后的元素
// 核心循环:将每个元素移动到新位置
for (int i = 0; i < len; ++i) {
// 计算新下标公式:(原下标+移动位数)%数组长度
// 当计算结果超过数组长度时,自动从数组开头继续计算
temp[(i + place) % len] = a[i]; // 例:len=5,place=7时等同于place=2
}
// 将排序结果写回原数组
for (int i = 0; i < len; ++i) {
a[i] = temp[i]; // 逐个元素复制回原数组
}
}
/**
* 输出数组元素
* @param a 要输出的数组指针
* @param len 数组实际有效长度
*
* 输出格式:元素间用空格分隔,最后换行
*/
void output(int* a, int len) {
for (int i = 0; i < len; ++i) {
printf("%d ", a[i]); // 遍历输出每个元素
}
printf("\n"); // 输出完成后换行
}
int main() {
int a[N]; // 存储数据的数组(物理容量为10)
int len = 0; // 用户实际使用的元素个数
int place = 0; // 原始输入的移动位数
// 第一阶段:获取用户输入
puts("how many number?");
scanf("%d", &len); // 注意:此处未校验len>10的情况
printf("input the %d numbers:", len);
for (int i = 0; i < len; ++i) {
scanf("%d", &a[i]); // 连续读取指定数量的整数
}
// 第二阶段:获取并处理移动位数
printf("how many place do you want move?");
scanf("%d", &place);
// 关键处理:位移规范化(支持负数和超长位移)
// 1. place % len 处理过大位移(如place=15,len=10→5)
// 2. +len 保证结果非负(处理负数位移)
// 3. 再次%len 确保最终值在[0,len-1]范围内
place = (place % len + len) % len; // 示例:place=-3,len=5→2
// 第三阶段:执行移动并输出结果
move(a, len, place);
output(a, len);
return 0; // 正常退出程序
}
4、N个人围成一圈按照顺序排号。从第一个开始报数(1到3)凡是报号为3的出圈,最后剩下的那个是刚开始的几号?(约瑟夫环问题)😒
#include <cstdio> // 包含标准输入输出库
#define N 10 // 定义数组的最大容量为10
int main() {
int arr[N]; // 定义一个大小为N的数组,用于标记每个人的状态(1表示在场,0表示出局)
int totalPeople = 0; // 总人数
int current = 0; // 当前的位置指针(从0开始)
int count = 0; // 报数计数器(记录当前数到第几个人)
printf("How many people? "); // 提示用户输入总人数
scanf("%d", &totalPeople); // 读取用户输入的总人数
int remaining = totalPeople; // 剩余人数,初始值等于总人数
for (int i = 0; i < totalPeople; ++i) {
arr[i] = 1; // 初始化数组,所有人的状态设置为1(在场)
}
// 模拟报数过程,直到只剩1人
while (remaining > 1) {
if (arr[current] == 1) { // 如果当前位置的人在场
count++; // 报数加1
if (count == 3) { // 如果报数到3
arr[current] = 0; // 将当前位置的人标记为出局
remaining--; // 剩余人数减1
count = 0; // 重置报数计数器
printf("%d out ", current); // 输出出局的人的编号
}
}
current = (current + 1) % totalPeople; // 移动到下一个位置(环形移动)
}
printf("\n"); // 换行
for (int i = 0; i < totalPeople; ++i) {
if (arr[i] == 1) { // 查找最后剩下的那个人
printf("The last survivor is %d\n", i + 1); // 输出最后剩下的人的编号(加1是为了将索引转换为实际编号)
}
}
return 0; // 程序结束
}
5、求字符串长度
#include <cstdio>
#define N 20
int getLength(char* p){
int i = 0,length = 0;
while(p[i] != '\0' && i < N){
length++;
i++;
}
return length;
}
int main(){
char str[N];
printf("input the string:");
scanf("%s",str);
printf("the length of string is:%d", getLength(str));
}
6、将包含N个字符的字符串从第M个位置开始复制到另一个字符数组,并输出
#include <cstdio> // 包含标准输入输出库
#define N 20 // 定义数组的最大容量为20
// 复制字符串的部分功能
void copy(char* p1, char* p2, int start) {
int i = start - 1; // 从用户指定的起始位置开始(注意:数组索引从0开始,所以需要减1)
int j = 0; // 目标字符串的索引
// 从起始位置开始复制,直到遇到字符串结束符'\0'或超出数组范围
while (p1[i] != '\0' && i < N) {
p2[j++] = p1[i++]; // 将源字符串p1的字符复制到目标字符串p2中
}
p2[j] = '\0'; // 在目标字符串末尾添加字符串结束符'\0'
}
int main() {
char str1[N]; // 定义第一个字符串数组,用于存储用户输入的源字符串
char str2[N]; // 定义第二个字符串数组,用于存储复制后的结果字符串
int start = 0; // 用户指定的起始位置
// 提示用户输入源字符串
printf("input the str1: ");
scanf("%s", str1); // 读取用户输入的源字符串
// 提示用户输入起始位置
printf("input the start: ");
scanf("%d", &start); // 读取用户输入的起始位置
// 调用复制函数,从起始位置开始复制字符串
copy(str1, str2, start);
// 输出目标字符串(复制后的结果)
printf("%s", str2);
return 0; // 程序结束
}
7、输入5x5矩阵,最大的元素放在中心,四个角上是最小的元素,大小顺序是从左到右,从上到下放😒
#include <cstdio>
#define N 5 // 定义矩阵的大小为5x5
// 函数作用:处理矩阵,把最大值放到中心,四个角放最小值
void change(int (*point)[N]) {
int a[4]; // 用于存储四个最小值
int b[4]; // 用于存储四个角的原始值
// 1. 找到最大的元素并放到中心位置
int max = point[0][0]; // 假设第一个元素是最大值
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (point[i][j] > max) { // 如果当前矩阵的值比假设的最大值更大
max = point[i][j]; // 更新最大值
}
}
}
point[2][2] = max; // 将最大值放置到矩阵中心(即坐标 [2][2])
// 2. 保存四个角的原始值
b[0] = point[0][0]; // 左上角
b[1] = point[0][4]; // 右上角
b[2] = point[4][0]; // 左下角
b[3] = point[4][4]; // 右下角
// 3. 找到四个最小值,并将它们替换到四个角的位置
for (int k = 0; k < 4; ++k) { // 多次循环找到四个最小值
int min_val = 1000000; // 假设矩阵值不会超过这个数值
int row = -1, col = -1; // 记录最小值的位置
// 遍历矩阵,找到当前最小值
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
if (point[i][j] < min_val) { // 如果当前值比假设的最小值更小
min_val = point[i][j]; // 更新最小值
row = i; // 记录最小值的行号
col = j; // 记录最小值的列号
}
}
}
a[k] = min_val; // 保存当前最小值
point[row][col] = b[k]; // 将最小值的位置替换为原始角的值
}
// 4. 将四个最小值放置到四个角
point[0][0] = a[0]; // 左上角
point[0][4] = a[1]; // 右上角
point[4][0] = a[2]; // 左下角
point[4][4] = a[3]; // 右下角
}
int main() {
int arr[N][N]; // 定义一个5x5的整数矩阵
// 输入矩阵
printf("Enter the 5x5 matrix:\n");
for (int i = 0; i < N; ++i) {
printf("Enter row %d (numbers separated by spaces):\n", i + 1);
for (int j = 0; j < N; ++j) {
scanf("%d", &arr[i][j]); // 读取每一行的数值
}
}
// 打印原始矩阵
printf("\nThe original matrix is:\n");
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
printf("%d ", arr[i][j]); // 打印每一行的数值
}
printf("\n");
}
// 调用函数处理矩阵
change(arr); // 调用change函数,处理矩阵
// 打印修改后的矩阵
printf("\nThe modified matrix is:\n");
for (int i = 0; i < N; ++i) {
for (int j = 0; j < N; ++j) {
printf("%d ", arr[i][j]); // 打印处理后的矩阵
}
printf("\n");
}
return 0; // 程序正常结束
}
书上写的有点难懂哦,呜呜呜。
8、输入十个等长的字符串,对字符串排序并输出排序好的字符串
#include <cstdio>
#include <cstring>
#define N 3
#define M 6
// 折半插入排序
void sort(char (*p)[M]) {
int high, low, mid;
char temp[M]; // 使用临时数组保存当前待插入的字符串
for (int i = 1; i < N; ++i) {
high = i - 1;
low = 0;
strcpy(temp, p[i]); // 将当前字符串复制到临时数组
while (low <= high) {
mid = (low + high) / 2;
if (stricmp(p[mid], temp) > 0) {
high = mid - 1;
} else {
low = mid + 1;
}
}
// 将 [low, i-1] 区间的字符串后移一位
for (int j = i - 1; j >= low; j--) {
strcpy(p[j + 1], p[j]); // 复制字符串内容
}
strcpy(p[low], temp); // 将临时字符串插入到正确位置
}
}
int main() {
char str[N][M], (*point)[M];
for (int i = 0; i < N; ++i) {
printf("Enter string %d (max length %d): ", i + 1, M - 1);
scanf("%s", str[i]); // 输入字符串
}
printf("\nUnsorted array of strings:\n");
for (int i = 0; i < N; ++i) {
printf("%s\n", str[i]); // 输出未排序的数组
}
point = str;
sort(point); // 调用排序函数
printf("\nSorted array of strings:\n");
for (int i = 0; i < N; ++i) {
printf("%s\n", str[i]); // 输出排序后的数组
}
return 0;
}
在代码中,
strcpy(p[j + 1], p[j]);
的作用是将字符串p[j]
复制到p[j + 1]
。这是因为数组中的元素是字符数组(即字符串),而直接赋值p[j + 1] = p[j]
是不允许的,因为数组名是常量指针,不能直接被赋值。
9、矩阵法求如下定积分
10、一个班4个学生5门课程,实现下面的函数
(1)求第一门课程的平均分
(2)算出两门课不及格的学生的总分和平均分
(3)输出全部成绩在85以上的学生或者是平均分在90以上的学生
#include <cstdio> // 包含标准输入输出库
// 定义学生数量(N)、课程数量(M)和课程名称的最大长度(L)
#define N 4 // 学生数量
#define M 5 // 课程数量
#define L 20 // 课程名称最大长度
// 计算第一门课程的平均分
float getNo1ScoreAverage(float (*point)[M]) {
float sum = 0; // 用于存储第一门课程的总成绩
// 遍历所有学生,累加第一门课程的成绩
for (int i = 0; i < N; ++i) {
sum += *(*(point + i)); // point是一个指向二维数组的指针,*(*(point+i))相当于访问第i个学生的第1门课程的成绩
}
return sum / N; // 返回第一门课程的平均分
}
// 找出至少有两门课程不及格的学生
void getTwoFail(float (*point)[M]) {
int count = 0; // 不及格课程的数量
float score = 0; // 单门课程成绩
float arr[M]; // 用于存储学生的成绩
float sum = 0; // 总成绩
float average = 0; // 平均分
bool flag = true; // 标记是否找到不合格学生
// 遍历所有学生
for (int i = 0; i < N; ++i) {
count = 0; // 重置不及格课程计数
// 遍历每个学生的课程成绩
for (int j = 0; j < M; ++j) {
score = *(*(point + i) + j); // 获取当前课程成绩
arr[j] = score; // 将成绩存入数组
if (score < 60) { // 如果成绩低于60分,表示不及格
count++; // 不及格课程计数加1
}
}
// 如果不及格课程数量大于等于2
if (count >= 2) {
flag = !flag; // 设置标记为找到不合格学生
// 输出该学生的编号和所有成绩信息
printf("The fail student is No.%d\n", i + 1);
sum = 0; // 重置总成绩
// 计算总成绩和平均分
for (int k = 0; k < M; ++k) {
sum += arr[k];
}
average = sum / M;
printf("His score is :%3.2f and average is:%3.2f\n", sum, average);
}
}
// 如果没有找到不合格学生
if (flag) {
printf("No fail student!!!\n");
}
}
// 找出平均分在90分以上或者每门成绩都在85分以上的学生
void getGood(float (*point)[M]) {
float score = 0; // 单门课程成绩
int count = 0; // 单门成绩在85以上的课程数
float sum = 0; // 总成绩
float average = 0; // 平均分
// 遍历所有学生
for (int i = 0; i < N; ++i) {
count = 0; // 重置课程计数
sum = 0; // 重置总成绩
// 遍历每个学生的课程成绩
for (int j = 0; j < M; ++j) {
score = *(*(point + i) + j); // 获取当前课程成绩
if (score > 85) { // 如果成绩超过85分
count++; // 计数加1
}
sum += score; // 累加总成绩
}
// 如果每门成绩都超过85分
if (count == M) {
printf("No.%d student's score all above 85\n!", i + 1);
}
average = sum / M; // 计算平均分
// 如果平均分超过90分
if (average > 90) {
printf("No.%d student's average above 90!\n", i + 1);
}
}
}
int main() {
float scores[N][M], (*p)[M]; // 定义学生成绩的二维数组和指向它的指针
// 输入学生成绩
for (int i = 0; i < N; ++i) {
printf("input the No.%d's student's scores:\n", i + 1); // 提示输入第i个学生的成绩
for (int j = 0; j < M; ++j) {
printf("input the score %d:", j + 1); // 提示输入第j门课程的成绩
scanf("%f", &scores[i][j]); // 输入成绩并存入数组
}
}
p = scores; // 指针p指向学生成绩数组
printf("\n");
// 输出第一门课程的平均分
printf("The score 1's average is:%3.2f\n", getNo1ScoreAverage(p));
// 查找并输出至少有两门课程不及格的学生信息
getTwoFail(p);
// 查找并输出平均分在90分以上或者每门成绩都在85分以上的学生信息
getGood(p);
return 0; // 程序结束
}
11、输入一堆字符串,有数字和非数字,将连续的数字视为一个整数并存放到数组,输出数组的元素
例如A123x456 1760? 302TAB5876
输出123 456 1760 302 5876这几个整数
#include <cstdio>
#include <cstring>
#include <cstdlib> // 包含 atoi 函数
#define N 30 // 定义字符串和数组的最大长度
/**
* @brief 将字符数组转换为整数
* @param temp 存储数字字符的数组(必须以'\0'结尾)
* @return 转换后的整数值
* @note 使用 atoi 实现转换,但需注意:
* - 若 temp 包含非数字字符,atoi 会截断前面的数字部分(如 "123a" 转成 123)
* - 若数值超出 int 范围,行为未定义
*/
int convert(char temp[N]) {
return atoi(temp); // 标准库函数,ASCII to integer
}
/**
* @brief 从字符串中提取连续数字并存入整数数组
* @param str 输入的原始字符串
* @param arr 用于存储提取结果的整数数组
* @param strLen 输入字符串的长度
* @param validCount 引用参数,用于返回实际提取的数字个数
* @note 逻辑说明:
* 1. 遍历字符串每个字符
* 2. 当发现数字字符时,开始收集连续数字
* 3. 将连续数字字符存入临时数组 temp
* 4. 调用 convert 转换为整数并存入结果数组
*/
void getData(char str[], int arr[], int strLen, int &validCount) {
char temp[N]; // 临时存储数字字符的缓冲区
int tempIndex = 0; // temp 数组的当前索引
int arrIndex = 0; // arr 数组的当前索引
for (int i = 0; i < strLen; ++i) {
// 发现数字字符时开始收集
if (str[i] >= '0' && str[i] <= '9') {
tempIndex = 0; // 重置临时数组索引
// 收集连续数字字符(注意:未处理负数符号)
while (i < strLen && (str[i] >= '0' && str[i] <= '9')) {
// 潜在问题:若连续数字超过 N-1 个会导致缓冲区溢出
// 建议添加:&& tempIndex < N-1
temp[tempIndex++] = str[i++];
}
temp[tempIndex] = '\0'; // 添加字符串结束符
// 转换并存储结果
arr[arrIndex++] = convert(temp);
validCount++; // 更新有效数字计数
i--; // 回退一个字符,因为外层循环会执行 i++
}
}
}
int main() {
char str[N]; // 输入字符串缓冲区
int arr[N]; // 存储提取结果的数组
int validCount = 0; // 实际提取的有效数字个数
// 输入处理
puts("input the string:");
gets(str); // 警告:存在缓冲区溢出风险!建议改用 fgets(str, N, stdin)
// 计算有效长度(去除可能的换行符)
int len = strlen(str);
printf("Length: %d\n", len);
// 执行核心提取逻辑
getData(str, arr, len, validCount);
// 输出结果(仅打印有效数据)
printf("Extracted numbers: ");
for (int i = 0; i < validCount; ++i) {
printf("%d ", arr[i]);
}
return 0;
}
`atoi`是C标准库中的一个函数,用于将字符串转换为整数。用户可能在代码中看到它被用来处理从字符串中提取的数字部分,比如将"123"转换为123。但是字符数组的结尾必须是‘\0’
12、编写函数实现两个字符串的比较
#include <cstdio> // 包含标准输入输出库的头文件
#define N 10 // 定义宏 N,表示字符串的最大长度为 10
// 定义一个函数 compare,用于比较两个字符串
int compare(char str1[], char str2[]) {
int result = 0; // 初始化比较结果为 0
for (int i = 0; i < N && (str1[i] != '\0' && str2[i] != '\0'); ++i) {
// 遍历字符串,直到遇到字符 '\0' 或超过 N 的长度
if (str1[i] != str2[i]) { // 如果当前字符不相等
result = str1[i] - str2[i]; // 计算ASCII码的差值,并赋值给 result
break; // 找到第一个不相等的字符后,跳出循环
}
}
return result; // 返回比较结果
}
int main() {
char str1[N], str2[N]; // 定义两个字符数组 str1 和 str2,用于存储用户输入的字符串
puts("input the str1:"); // 提示用户输入第一个字符串
gets(str1); // 读取用户输入的字符串,存储到 str1 中
puts("input the str2:"); // 提示用户输入第二个字符串
gets(str2); // 读取用户输入的字符串,存储到 str2 中
int result = compare(str1, str2); // 调用 compare 函数,比较两个字符串
printf("result:%d", result); // 输出比较结果
return 0; // 程序正常结束
}
13、指针数组实现输入月号,输出英文月号
#include <cstdio>
int main() {
// 定义一个字符串数组,存储12个月的英文名称
const char* months[] = {
"January", // 1月
"February", // 2月
"March", // 3月
"April", // 4月
"May", // 5月
"June", // 6月
"July", // 7月
"August", // 8月
"September",// 9月
"October", // 10月
"November", // 11月
"December" // 12月
};
puts("input the month:");
int month;
scanf("%d", &month);
// 检查输入是否在有效范围内
if (month >= 1 && month <= 12) {
printf("%s\n", months[month - 1]); // 使用 month - 1 调整索引
} else {
printf("Invalid month number. Please enter a number between 1 and 12.\n");
}
return 0;
}
15、使用双重指针实现对5个字符串排序输出
#include <cstdio> // 输入输出函数
#include <cstdlib> // 动态内存管理函数
#include <cstring> // 字符串操作函数
#define N 5 // 要处理的字符串数量
#define max 10 // 每个字符串的最大长度(包含空终止符)
// 折半插入排序函数,对字符串指针数组进行不区分大小写排序
void sort(char** str) {
int low, mid, high; // 二分查找的区间指针
char* temp; // 临时保存当前待插入字符串指针
// 从第二个元素开始逐个插入到前面已排序序列
for (int i = 0; i < N; ++i) {
low = 0; // 初始化查找区间起始位置
high = i - 1; // 初始化查找区间结束位置
temp = str[i]; // 保存当前待插入的字符串指针
// 二分查找插入位置(升序排列)
while (low <= high) {
mid = (low + high) / 2;
// 使用不区分大小写的比较(注意:stricmp是Windows特有,Linux可用strcasecmp)
if (stricmp(str[mid], temp) > 0) {
high = mid - 1; // 中间值更大,调整上限
} else {
low = mid + 1; // 中间值更小,调整下限
}
}
// 将插入位置后的元素后移(移动指针而不是复制字符串内容)
for (int j = i - 1; j >= low; j--) {
str[j + 1] = str[j]; // 直接移动指针位置
}
// 将当前元素插入到正确位置
str[low] = temp;
}
}
int main() {
char* str[N]; // 字符串指针数组
// 输入处理:为每个字符串动态分配内存
for (int i = 0; i < N; ++i) {
printf("input the string %d:", i + 1);
str[i] = (char*)malloc(max * sizeof(char)); // 分配max字节内存
scanf("%s", str[i]); // 注意:实际最多读取max-1个字符,需用户保证输入合规
}
// 调用排序函数对指针数组进行排序
sort(str);
// 输出排序结果
puts("\nthe result:");
for (int i = 0; i < N; ++i) {
printf("%s ", str[i]);
}
// 改进建议:应在此处添加内存释放
// for (int i = 0; i < N; ++i) {
// free(str[i]);
// }
return 0;
}
16、双重指针对输入的数字排序
#include <cstdio> // 包含标准输入输出库
#define N 5 // 定义数组的大小,这里为5
// 折半插入排序函数,参数为指向指针的指针
void sort(int** pInt) {
int low, mid, high; // 定义二分查找所需的变量
int* temp; // 用于临时存储当前元素
// 从第二个元素开始进行排序
for (int i = 1; i < N; ++i) {
low = 0; // 初始化二分查找的下边界
high = i - 1; // 初始化二分查找的上边界
temp = *(pInt + i); // 当前要插入的元素
// 使用二分查找确定当前元素的插入位置
while (low <= high) {
mid = (low + high) / 2; // 计算中间位置
if (*pInt[mid] > *temp) { // 如果中间位置的元素大于当前元素
high = mid - 1; // 调整上边界
} else {
low = mid + 1; // 调整下边界
}
}
// 将插入位置之后的元素后移一位,为当前元素腾出空间
for (int j = i - 1; j >= low; --j) {
pInt[j + 1] = pInt[j];
}
// 将当前元素插入到正确的位置
pInt[low] = temp;
}
}
int main() {
int arr[N]; // 定义一个存储输入数字的数组
int* point[N]; // 指向数组元素的指针数组
int** pInt; // 指向指针数组的指针
// 读取用户输入的数字
for (int i = 0; i < N; ++i) {
printf("input the num%d:", i + 1); // 提示用户输入第i个数字
scanf("%d", &arr[i]); // 读取用户输入的数字
point[i] = &arr[i]; // 将指针数组的第i个元素指向数组的第i个元素
}
pInt = point; // 使 pInt 指向指针数组
// 调用排序函数对指针数组进行排序
sort(pInt);
// 输出排序后的结果
printf("Sorted array: ");
for (int i = 0; i < N; ++i) {
printf("%d ", *pInt[i]); // 通过指针数组访问并输出排序后的数字
}
return 0; // 程序正常结束
}
1.
int arr[N];
作用:声明了一个名为
arr
的整数数组。细节:
N
是一个宏定义的常量,表示数组的大小(例如#define N 5
)。数组
arr
用于存储N
个整数,可以通过下标访问和修改数组中的元素,例如arr[0]
表示数组的第一个元素。数组的大小在编译时确定,因此
N
必须是一个常量。2.
int* point[N];
作用:声明了一个指针数组
point
。细节:
指针数组是一个数组,其每个元素都是一个指向整数的指针(
int*
)。例如,
point[0]
是一个指针,可以指向一个整数变量。
N
表示指针数组的大小,即指针数组中有N
个指针。通常用于通过指针间接操作数组的元素,或者动态地管理内存
3.
int** pInt;
作用:声明了一个指向指针的指针
pInt
。细节:
pInt
是一个指针,但它指向的不是一个普通的整数,而是指向一个指向整数的指针(即int*
)。简单来说,
pInt
可以理解为一个“指针的指针”。通常用于指针数组的间接访问,或者动态二维数组的操作。