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 // 定义数组的最大容量为10int 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++; // 报数加1if (count == 3) { // 如果报数到3arr[current] = 0; // 将当前位置的人标记为出局remaining--; // 剩余人数减1count = 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 20int 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}}// 如果不及格课程数量大于等于2if (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-1temp[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; // 初始化比较结果为 0for (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码的差值,并赋值给 resultbreak; // 找到第一个不相等的字符后,跳出循环}}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
可以理解为一个“指针的指针”。通常用于指针数组的间接访问,或者动态二维数组的操作。