7-1 出圈游戏
用指针实现以下功能:有n个人围成一个圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号。
编程提示
每三个人离开,置为0;当数到最后一个人时,将指针重新指向第一个人;m表示离开的人数,当m=n-1时,说明只剩下一个人,循环结束。
输入样例:
10
输出样例:
4
参考代码:
#include<stdio.h>
#include<stdlib.h>
int main(){
int n;
while(scanf("%d",&n)!=1);
int *circle=(int *)malloc(n*sizeof(int));
//注释1
for(int i=0;i<n;i++){
circle[i]=1;
}
int m=0;
int index=0;
int count=0;
while(m<n-1){
if(circle[index]!=0){
count++;
if(count==3){
circle[index]=0;//标记为0
m++;
count=0;
}
}
index++;
if(index==n){
index=0;
}
}
for(int i=0;i<n;i++){
if(circle[i]!=0){
printf("%d\n",i+1);
break;
}
}
free(circle);//释放内存
return 0;
}
注释1:
malloc()
是 C 语言中的一个函数,它用于在运行时动态地分配内存空间。这个函数在 <stdlib.h>
库中定义。malloc()
函数允许程序在运行时根据需要请求特定大小的内存块。
函数的原型如下:
void* malloc(size_t size);
其中,size
参数表示要分配的内存块的大小(以字节为单位)。
malloc()
函数返回一个指向新分配内存的指针。如果内存分配成功,则指针指向新分配的内存块的开始位置。如果内存分配失败(例如,没有足够的内存可供分配),则 malloc()
返回一个 NULL
指针。
这是一个使用 malloc()
的简单示例:
#include <stdio.h>
#include <stdlib.h>
int main() {
int *ptr;
int n = 5;
// 使用 malloc 分配内存
ptr = (int*)malloc(n * sizeof(int));
// 检查内存是否成功分配
if (ptr == NULL) {
printf("Memory not allocated.\n");
exit(0); //exit():终止程序。
}
else {
printf("Memory successfully allocated using malloc.\n");
// 使用分配的内存
for (int i = 0; i < n; ++i)
ptr[i] = i + 1;
// 输出数组元素
printf("The elements of the array are: ");
for (int i = 0; i < n; ++i)
printf("%d, ", ptr[i]);
// 释放内存
free(ptr);
}
return 0;
}
在上面的示例中,我们首先使用 malloc()
分配了一个包含 5 个整数的内存块。然后,我们检查 malloc()
是否成功分配了内存。如果分配成功,我们就使用这块内存存储一些值,并在最后使用 free()
函数释放这块内存。
注意,当你使用 malloc()
分配内存时,你有责任在不再需要这块内存时使用 free()
函数释放它。否则,你的程序可能会耗尽可用内存,导致崩溃或其他不可预测的行为。
7-2 矩阵转置
编写函数,求一个3×3矩阵的转置矩阵。
编程提示
转置矩阵,将原矩阵的行变为列,列变为行。注意,通过指针访问二维数组时的方法。本题采用的是指向数组元素的指针变量。
输入样例:
1 2 3
4 5 6
7 8 9
输出样例:
1 4 7
2 5 8
3 6 9
参考代码:
#include<stdio.h>
#define N 3
int main(){
int arr[N][N];
int i,j;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
while(scanf("%d",&arr[i][j])!=1);
}
}
for(j=0;j<N;j++){
for(i=0;i<N;i++){
if(i==N-1){
printf("%d",arr[i][j]);
}
else{
printf("%d ",arr[i][j]);
}
}
printf("\n");
}
return 0;
}
7-3 用指针知识连接字符串
任意输入两个字符串,然后连接这两个字符串,并输出连接后的新字符串。要求不能使用字符串处理函数strcat()。
编程提示
连接成新的字符串,要求定义新的字符数组时数组长度要足够长;当形成一个新的字符串时,注意加字符串结束标志。
输入样例:
武汉
加油!
输出样例:
武汉加油!
参考代码:
#include<stdio.h>
#include<stdlib.h>
int main(){
char str1[100];
char str2[100];
char *result;
int i=0,j=0;
//注释1
fgets(str1,sizeof(str1),stdin);
str1[strcspn(str1,"\n")]=0;
fgets(str2,sizeof(str2),stdin);
str2[strcspn(str2,"\n")]=0;
int total_length=strlen(str1)+strlen(str2)+1;
//加1是为了字符串结束符'\0'
result=(char *)malloc(total_length*sizeof(char));
while(str1[i]!='\0'){
result[i]=str1[i];
i++;
}
while(str2[j]!='\0'){
result[i+j]=str2[j];
j++;
}
result[i+j]='\0';
printf("%s\n",result);
free(result);
return 0;
}
注释1:
fgets
函数用于从指定的输入流(在这个例子中是标准输入流 stdin
)读取一行数据,并保存到提供的字符数组中。让我们详细解释一下 fgets(str1, sizeof(str1), stdin);
这行代码。
str1
:这是一个字符数组(通常是一个字符数组变量),用于存储从输入流读取的数据。sizeof(str1)
:sizeof
是一个运算符,它返回括号内类型或对象的大小(以字节为单位)。在这里,它返回str1
数组的大小。这个值将作为fgets
的第二个参数,表示最多可以读取多少个字符并保存到str1
中。注意,这个值应该包括一个额外的字符用于存储字符串的终止符\0
。stdin
:这是一个文件指针,代表标准输入流。在大多数情况下,这通常是键盘输入。
fgets
函数会从 stdin
读取数据,直到遇到换行符(\n
)、文件结束符(EOF)或读取了 sizeof(str1) - 1
个字符为止。然后,它会在目标数组的最后添加一个空字符(\0
)以标记字符串的结束。
例如,如果 str1
是一个大小为 10 的字符数组(包括一个额外的位置用于存储 \0
),那么 fgets
将最多读取 9 个字符,并在第 10 个位置添加 \0
。
这里有一个简单的例子,展示了如何使用 fgets
:
#include <stdio.h>
int main() {
char str1[10]; // 定义一个大小为 10 的字符数组
printf("请输入一行文本: ");
fgets(str1, sizeof(str1), stdin); // 从标准输入读取一行文本,并保存到 str1 中
printf("你输入的是: %s", str1); // 输出读取到的文本
return 0;
}
在这个例子中,程序会提示用户输入一行文本,然后使用 fgets
读取这行文本,并输出到屏幕上。注意,如果用户输入的文本超过了 str1
数组的大小(不包括终止符的位置),那么 fgets
只会读取到数组大小减一的位置,并截断多余的字符。
7-4 输入数字月份输出对应的英文月份
从键盘输入一个月份值,用指针数组编程输出该月份的英文月名。
编程提示
定义指针数组并初始化。注意,指针数组中的元素为各字符串的起始地址。
输入样例1:
4
输出样例1:
April
输入样例2:
15
输出样例2:
Illegal month
参考代码:
#include<stdio.h>
int main(){
int month,*p;
scanf("%d",&month);
p=&month;
switch(*p){
case 1:printf("January");break;
case 2:printf("February");break;
case 3:printf("March");break;
case 4:printf("April");break;
case 5:printf("May");break;
case 6:printf("June");break;
case 7:printf("July");break;
case 8:printf("August");break;
case 9:printf("September");break;
case 10:printf("October");break;
case 11:printf("November");break;
case 12:printf("December");break;
default:printf("Illegal month");break;
}
return 0;
}
7-5 用指针实现整数求和
给出十个整数,输出这十个数的和,用指针来实现。
输入样例:
1 2 3 4 5 6 7 8 9 10
输出样例:
55
参考代码:
#include<stdio.h>
int main(){
int num,i=10,sum=0,*p;
for(i=10;i>0;i--){
scanf("%d",&num);
p=#
sum+=*p;
}
printf("%d",sum);
return 0;
}
7-6 字符串排序
输入10个等长的字符串,进行从小到大排序,然后输出排序后的10个字符串,使用指针来实现。
输入格式:
输入十行,每行为一个字符串,字符串中不包含空格。
输出格式:
输出排序后的字符串。
输入样例:
在这里给出一组输入。例如:
pklnsr
olzxni
rigyqo
pgirjr
jbwgvs
mswgrx
jvrfuo
plmppk
leowfm
jdnuog
输出样例:
在这里给出相应的输出。例如:
jbwgvs
jdnuog
jvrfuo
leowfm
mswgrx
olzxni
pgirjr
pklnsr
plmppk
rigyqo
参考代码:
#include<stdio.h>
#include <string.h>
#define num 10
#define max 100
//冒泡
void bubbling(char* arr[],int length,int n){
int i,j;
char* temp;
for(i=0;i<n-1;i++){
for(j=0;j<n-i-1;j++){
if(strcmp(arr[j],arr[j+1])>0){
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
}
int main(){
char arr[num][max];
char* p[num];
for(int i=0;i<num;i++){
scanf("%s",arr[i]);
p[i]=arr[i];
}
bubbling(p,max,num);
for(int i=0;i<num;i++){
printf("%s\n",p[i]);
}
return 0;
}
7-7 利用指针返回多个函数值
利用指针返回多个函数值
读入n个整数,调用max_min()函数求这n个数中的最大值和最小值。
输入格式:
输入有两行: 第一行是n值; 第二行是n个数。
输出格式:
输出最大值和最小值。
输入样例:
5
8 9 12 0 3
输出样例:
12 0
参考代码:
#include<stdio.h>
#include<stdlib.h>
int maxnum(int n,int* arr){
int max=-0x3f3f3f3f;
for(int i=0;i<n;i++){
if(arr[i]>max){
max=arr[i];
}
}
return max;
}
int minnum(int n,int* arr){
int min=0x3f3f3f3f;
for(int i=0;i<n;i++){
if(arr[i]<min){
min=arr[i];
}
}
return min;
}
int main(){
int n;
scanf("%d",&n);
int* arr=(int*)malloc(n*sizeof(int));
for(int i=0;i<n;i++){
scanf("%d",&arr[i]);
}
int max=maxnum(n,arr);
int min=minnum(n,arr);
printf("%d %d",max,min);
free(arr);
return 0;
}
7-8 利用指针求矩阵的最大值
利用指针求矩阵的最大值
有一个3×4的矩阵,输出其中最大数。要求使用指针变量访问数组元素。
输入样例:
10 11 12 13
14 88 15 16
22 33 55 44
输出样例:
max=88
row=1
column=1
参考代码:
#include<stdio.h>
#define ROW 3
#define COLUMN 4
void maxinum(int arr[ROW][COLUMN]){
int max=-0x3f3f3f3f;
int x,y;
for(int i=0;i<ROW;i++){
for(int j=0;j<COLUMN;j++){
if(arr[i][j]>max){
max=arr[i][j];
x=i;y=j;
}
}
}
printf("max=%d\n",max);
printf("row=%d\n",x);
printf("column=%d\n",y);
}
int main(){
int arr[ROW][COLUMN];
for(int i=0;i<ROW;i++){
for(int j=0;j<COLUMN;j++){
scanf("%d",&arr[i][j]);
}
}
maxinum(arr);
return 0;
}
7-9 利用动态数组求平均值
利用动态数组求平均值
输入n个学生的成绩,计算并输出平均分数。学生的人数由键盘输入。
输入样例:
5
60 70 80 90 100
输出样例:
80.0
参考代码:
#include<stdio.h>
#include<stdlib.h>
double summation(int n,int* arr){
double sum=0;
for(int i=0;i<n;i++){
sum+=arr[i];
}
return sum/n;
}
int main(){
int n;
scanf("%d",&n);
int* arr=(int*)malloc(n*sizeof(int));
for(int i=0;i<n;i++){
scanf("%d",&arr[i]);
}
double average=summation(n,arr);
printf("%.1lf",average);
return 0;
}
7-10 计算学生平均分及某个学生成绩
有3个学生,每个学生有4门成绩,用指向二维数组的指针求
(1)计算总平均分数
(2)输出第n个学生的成。
输出格式均为:“%6.1f”
输入样例:
85 97 80 100
89 87 90 81
90 99 86 70
2
输出样例:
87.8
89.0 87.0 90.0 81.0
参考代码:
#include<stdio.h>
#define ROW 3
#define COLUMN 4
double summation(double arr[ROW][COLUMN]){
double sum=0;
for(int i=0;i<ROW;i++){
for(int j=0;j<COLUMN;j++){
sum+=arr[i][j];
}
}
return sum;
}
int main(){
double arr[ROW][COLUMN];
for(int i=0;i<ROW;i++){
for(int j=0;j<COLUMN;j++){
while(scanf("%lf",&arr[i][j])!=1);
}
}
double sum=summation(arr);
printf("%6.1f\n",sum/ROW/COLUMN);
int n;
while(scanf("%d",&n)!=1);
for(int i=0;i<ROW;i++){
if(i==n-1){
for(int j=0;j<COLUMN;j++){
printf("%6.1f",arr[i][j]);
}
printf("\n");
break;
}
}
return 0;
}
7-11 三个整数排序
输入三个整数,用指针实现从大到小排序
编程提示
本质上是两个数的比较。三个数比较时,a和b比较,a和c比较,b和c比较。
输入样例:
88 22 55
输出样例:
88 55 22
参考代码:
#include<stdio.h>
int main(){
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
int* p_1=&a;
int* p_2=&b;
int* p_3=&c;
if(*p_1<*p_2){
int temp=*p_1;
*p_1=*p_2;
*p_2=temp;
}
if(*p_1<*p_3){
int temp=*p_1;
*p_1=*p_3;
*p_3=temp;
}
if(*p_2<*p_3){
int temp=*p_2;
*p_2=*p_3;
*p_3=temp;
}
printf("%d %d %d",*p_1,*p_2,*p_3);
return 0;
}
7-12 10个整数排序
将10个整数按由大到小排序输出。
编程提示:利用冒泡法排序。
输入样例:
9 7 1 6 8 4 3 10 2 5
输出样例:
输出格式“%d ”
1 2 3 4 5 6 7 8 9 10
参考代码:
#include<stdio.h>
#include<stdlib.h>
void bubbling(int arr[],int length){
int flag=1;
while(length-- && flag){
flag=0;
for(int i=0;i<length;i++){
if(arr[i]>arr[i+1]){
flag = 1;
int temp=arr[i+1];
arr[i+1]=arr[i];
arr[i]=temp;
}
}
}
}
int main(){
int* arr=(int*)malloc(10*sizeof(int));
for(int i=0;i<10;i++){
scanf("%d",&arr[i]);
}
bubbling(arr,10);
for(int i=0;i<10;i++){
printf("%d ",arr[i]);
}
return 0;
}
7-13 用指针知识统计各种字符的个数
输入一行字符,用指针知识统计其中的大写字母、小写字母、空格、数字和其它字符的个数。
编程提示
利用if的第三种形式,判断各字符并进行计数。
输入样例:
输入一行字符,例如
chi n123CDEH# !Tt @
输出样例:
输出格式数据格式如下,用一个空格分隔
大写字符 小写字母 空格 数字字符 其他字符
5 5 3 3 3
参考代码:
#include<stdio.h>
#include<ctype.h>
void counting(char *p){
int capital=0,lowercase=0,digit=0,blank=0,other=0;
while(*p!='\0'){
if(isupper(*p)){
capital++;
}
else if(islower(*p)){
lowercase++;
}
else if(isspace(*p)){
blank++;
}
else if(isdigit(*p)){
digit++;
}
else{
other++;
}
p++;
}
printf("%d %d %d %d %d\n",capital,lowercase,blank,digit,other);
}
int main(){
char arr[100];
char *p=arr;
fgets(arr,sizeof(arr),stdin);
counting(p);
return 0;
}
7-14 用指针知识按要求输出5×5矩阵
将一个5×5矩阵的最大值放在中心,四角按从左到右,从上到下的顺序存放最小值。
编程提示:利用打擂台法求最大值和最小值。
输入样例:
输入数据,之间用空格分隔,例如
11 12 13 14 15
21 31 66 88 23
10 42 68 31 35
65 68 99 82 29
71 72 73 74 75
输出样例:
输出格式数据格式如下,用一个空格分隔
10 71 75 14 11
21 31 66 88 23
15 42 99 31 35
65 68 68 82 29
12 72 73 74 13
参考代码:
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
void rearrangeMatrix(int arr[5][5]) {
int max1 = arr[0][0], min1 = arr[0][0];
int e[2];
int i, j;
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
if (max1 < arr[i][j]) {
max1 = arr[i][j];
e[0] = i;
e[1] = j;
}
}
}
swap(&arr[2][2], &arr[e[0]][e[1]]);
max1 = -1e6;
min1 = 1e6;
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
if (min1 > arr[i][j] && arr[i][j] != arr[2][2]) {
min1 = arr[i][j];
e[0] = i;
e[1] = j;
}
}
}
swap(&arr[0][0], &arr[e[0]][e[1]]);
min1 = 1e6;
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
if (min1 > arr[i][j] && arr[i][j] != arr[0][0] && arr[i][j] != arr[2][2]) {
min1 = arr[i][j];
e[0] = i;
e[1] = j;
}
}
}
swap(&arr[0][4], &arr[e[0]][e[1]]);
min1 = 1e6;
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
if (min1 > arr[i][j] && arr[i][j] != arr[0][0] && arr[i][j] != arr[0][4] && arr[i][j] != arr[2][2]) {
min1 = arr[i][j];
e[0] = i;
e[1] = j;
}
}
}
swap(&arr[4][0], &arr[e[0]][e[1]]);
min1 = 1e6;
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
if (min1 > arr[i][j] && arr[i][j] != arr[0][0] && arr[i][j] != arr[0][4] && arr[i][j] != arr[4][0] && arr[i][j] != arr[2][2]) {
min1 = arr[i][j];
e[0] = i;
e[1] = j;
}
}
}
swap(&arr[4][4], &arr[e[0]][e[1]]);
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
if (j == 4)
printf("%d", arr[i][j]);
else
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main(){
int arr[5][5];
int i,j;
for (i = 0; i < 5; i++) {
for (j = 0; j < 5; j++) {
scanf("%d",&arr[i][j]);
}
}
rearrangeMatrix(arr);
return 0;
}
7-15 求字符串的长度
求字符串的长度。
编程提示:在遍历字符串时,进行计数,直到遇到’\0’结束。
输入样例:
输入数据,之间用空格分隔,例如
abcdefghi
输出样例:
输出格式数据格式如下,用一个空格分隔
9
参考代码:
#include<stdio.h>
int strlen(char *str){
int length=0;
while(*str!='\0'){
length++;
str++;
}
return length;
}
int main(){
char str[100];
scanf("%s",str);
int length=strlen(str);
printf("%d\n",length);
return 0;
}
7-16 用函数指针实现数组排序
输入10个整数进行排序并输出,其中用函数指针编写一个通用的排序函数,如果输入1,程序实现数据按升序排序;如果输入2,程序实现数据按降序。
(1)编程提示
定义ascend函数,决定按升序排序;定义descend函数,决定按降序排序;定义sort函数,实现排序的算法,根据实参,确定指向函数的指针变量调用ascend函数还是descend函数。
输入样例:
输入数据,之间用空格分隔
输入样例1:
2 3 4 9 10 8 7 6 5 1
1
输入样例2:
2 3 4 9 10 8 7 6 5 1
2
输出样例:
输出格式数据格式如下,用一个空格分隔;最后一个数字后没有空格。
输出样例1:
1 2 3 4 5 6 7 8 9 10
输出样例2
10 9 8 7 6 5 4 3 2 1
参考代码:
#include<stdio.h>
#include<stdlib.h>
void bubbling_1(int arr[],int length){
int flag=1;
while(length--&&flag){
flag=0;
for(int i=0;i<length;i++){
if(arr[i]>arr[i+1]){
flag=1;
int temp=arr[i+1];
arr[i+1]=arr[i];
arr[i]=temp;
}
}
}
}
void bubbling_2(int arr[],int length){
int flag=1;
while(length--&&flag){
flag=0;
for(int i=0;i<length;i++){
if(arr[i]<arr[i+1]){
flag=1;
int temp=arr[i+1];
arr[i+1]=arr[i];
arr[i]=temp;
}
}
}
}
int main(){
int n=10;
int* arr=(int*)malloc(n*sizeof(int));
for(int i=0;i<10;i++){
scanf("%d",&arr[i]);
}
int count;
scanf("%d",&count);
if(count==1){
bubbling_1(arr,n);
}
if(count==2){
bubbling_2(arr,n);
}
for(int i=0;i<n;i++){
if(i==n-1){
printf("%d\n",arr[i]);
}
else{
printf("%d ",arr[i]);
}
}
return 0;
}