文章目录
- 第八章 指针 21
- 8.1 3个整数从小到大排序
- 8.2 3个字符串从大到小排序
- 8.3 最小值和第一位互换,最大值和最后一位互换
- 8.4 n个整数右偏移m位
- 8.5 报数(经典约瑟夫问题)
- 8.6 求字符串长度
- 8.7 从第m个字符开始复制到另一个字符串
- 8.8 统计字符
- 8.9 3阶矩阵矩阵转置
- 8.10 5阶矩阵,最大元素放中间,最小值放4个角(左到右,上到下)
- 8.11 等长字符串排序
- 8.12 不等长字符串排序
- 8.13 用矩阵求定积分的通用函数
- 8.14 n个数顺序输入,逆序排列,函数实现
- 8.15 学生成绩
- 8.16 统计字符串中连续数字构成的整数个数
- 8.17 实现strcmp函数,函数原型int strcmp(char *p1,char *p2)
- 8.18 输入月份号输出英文名月份
- 8.19 动态分配申请空间函数和free释放申请空间函数
- 8.20 指向指针的指针,对5个字符串排序
- 8.21 指向指针的指针,n个整数排序
第八章 指针 21
8.1 3个整数从小到大排序
#include<stdio.h>
void sort(int *p,int *q,int *r);
int main()
{
int a,b,c;
int *p=&a,*q=&b,*r=&c;
scanf("%d %d %d",&a,&b,&c);
sort(p,q,r);
printf("%d %d %d",a,b,c);
return 0;
}
void sort(int *p,int *q,int *r) //抽象为函数形式
{
int temp;
if(*p>*q)
{
temp=*p;
*p=*q;
*q=temp;
}
if(*p>*r)
{
temp=*p;
*p=*r;
*r=temp;
}
if(*q>*r)
{
temp=*q;
*q=*r;
*r=temp;
}
}
8.2 3个字符串从大到小排序
#include<stdio.h>
#include<string.h>
#define N 100
void sort(char *p,char *q,char *r);
int main()
{
char a[N],b[N],c[N];
char *p=a,*q=b,*r=c;
gets(a);
gets(b);
gets(c);
sort(p,q,r);
printf("%s %s %s",p,q,r);
return 0;
}
void sort(char *p,char *q,char *r) //抽象为函数形式
{
char temp[N];
if(strcmp(p,q)<0) //比较字符串大小
{
strcpy(temp,p); //交换
strcpy(p,q);
strcpy(q,temp);
}
if(strcmp(p,r)<0)
{
strcpy(temp,p);
strcpy(p,r);
strcpy(r,temp);
}
if(strcmp(q,r)<0)
{
strcpy(temp,q);
strcpy(q,r);
strcpy(r,temp);
}
}
8.3 最小值和第一位互换,最大值和最后一位互换
写3个函数:
- 输入10个数
- 处理函数
- 输出10个数
#include<stdio.h>
#define N 10
void inputnumber(int a[]);
void exchange(int a[]);
void outputnumber(int a[]);
int main()
{
int a[N];
inputnumber(a);
exchange(a);
outputnumber(a);
return 0;
}
void inputnumber(int a[])
{
int i;
printf("请输入10个数:");
for(i=0;i<N;i++)
scanf("%d",&a[i]);
}
void exchange(int a[]) //抽象为函数形式
{
int i,temp,max=0,min=0;
for(i=0;i<N;i++) //找到最大值和最小值
{
if(a[max]<a[i])
max=i;
if(a[min]>a[i])
min=i;
}
if(max==0&&min==N-1) //最大值在第一个,最小值在最后一个,直接互换首尾
{
temp=a[max]; a[max]=a[min]; a[min]=temp;
}
else if(max==0) //最大值恰好在第一个,先交换最大值位置
{
temp=a[N-1]; a[N-1]=a[max]; a[max]=temp;
temp=a[0]; a[0]=a[min]; a[min]=temp;
}
else //最小值恰好在最后一位,先交换最小值位置(其他情况顺序任意)
{
temp=a[0]; a[0]=a[min]; a[min]=temp;
temp=a[N-1]; a[N-1]=a[max]; a[max]=temp;
}
}
void outputnumber(int a[])
{
int i;
printf("输出处理后的10个数:");
for(i=0;i<N;i++)
printf("%d ",a[i]);
}
8.4 n个整数右偏移m位
#include<stdio.h>
#define N 100
void fact(int a[],int n,int m);
int main()
{
int i,a[N],n,m;
printf("分别输入数字个数和偏移位置:");
scanf("%d %d",&n,&m);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
fact(a,n,m);
for(i=0;i<n;i++)
printf("%d ",a[i]);
return 0;
}
void fact(int a[],int n,int m)
{
int i,j,temp;
int *p=a;
for(i=0;i<m;i++) //外循环为偏移次数
{
temp=*(p+n-1); //记录最后一位
for(j=n-1;j>0;j--) //数组往后偏移一位
*(p+j)=*(p+j-1);
*p=temp; //把最后一位赋值给第一位
}
}
8.5 报数(经典约瑟夫问题)
#include<stdio.h>
#define N 100
void fact(int a[],int n,int m);
int main()
{
int i,a[N],n,m,index;
printf("分别输入人数和报数:");
scanf("%d %d",&n,&m);
for(i=0;i<n;i++)
a[i]=i+1;
fact(a,n,m);
return 0;
}
void fact(int a[],int n,int m)
{
int i=0,count=0,people=n;
int *p=a;
while(people!=0) //当总人数不是最后一个时循环
{
if(*(p+i)!=0) //0表示淘汰 ,未淘汰则报数
count++;
if(count%m==0&&*(p+i)!=0) //若选手未淘汰报数能被m整除,则被淘汰
{
people--; //人数-1
//printf("%d ",*(p+i));
if(people==0) //若人数为0,则输出序号,并结束循环
{
printf("最后一个留下是%d号",*(p+i));
break;
}
*(p+i)=0; //置0淘汰
}
i++;
if(i>=n&&people>0) //当下标移动到末尾且人数大于1人时从头开始。
{
i=0;
p=a; //指针重新回到数组名
}
}
}
/*
分别输入人数和报数:8 3
最后一个留下是7号
*/
8.6 求字符串长度
#include<stdio.h>
#define N 100
int getstrlen(char *p);
int main()
{
int length;
char ch[N];
gets(ch);
length=getstrlen(ch);
printf("length = %d",length);
}
int getstrlen(char *p)
{
int i=0;
while(*(p+i)!='\0') i++;
return i; //虽然i最后停留在'\0'处,但起始位置是字符串的首字符相当于从1开始计数,故不是i-1,而是返回i即可。
}
8.7 从第m个字符开始复制到另一个字符串
#include<stdio.h>
#include<string.h>
#define N 100
char *indexstrcpy(char *a,char *b,int m);
int main()
{
char a[N],b[N];
gets(a);
int length,m;
printf("设置复制起点下标:");
scanf("%d",&m);
printf("new string:%s",indexstrcpy(a,b,m));
}
char *indexstrcpy(char *a,char *b,int m)
{
int i=0,j;
if(m==0) //偏移为0,直接返回a字符串;
return a;
else if(m>strlen(a)) //便宜超过a字符串的长度,则返回空串
return NULL;
else //其他则从m开始拷贝到b中返回
{
while(i<m) i++;
for(j=0;*(a+i)!='\0';j++,i++)
*(b+j)=*(a+i);
b[j]='\0';
return b;
}
}
8.8 统计字符
#include<stdio.h>
#include<string.h>
#define N 100
void statistics(char *p,int *q);
int main()
{
char a[N];
int count[5]={0};
gets(a);
statistics(a,count);
}
void statistics(char *p,int count[]) //抽象为函数形式
{
int i;
//统计字符
for(i=0;*(p+i)!='\0';i++)
{
if((*(p+i)>='A'&&*(p+i)<='Z'))
count[0]++;
else if((*(p+i)>='a'&&*(p+i)<='z'))
count[1]++;
else if(*(p+i)>='0'&&*(p+i)<='9')
count[2]++;
else if(*(p+i)==' ')
count[3]++;
else
count[4]++;
}
//打印统计结果
printf("大写英文\t%d\n",count[0]);
printf("小写英文\t%d\n",count[1]);
printf("空格\t\t%d\n",count[3]);
printf("数字\t\t%d\n",count[2]);
printf("其他字符\t%d\n",count[4]);
}
8.9 3阶矩阵矩阵转置
#include<stdio.h>
#define N 3
void transposition(int *p);
int main()
{
int i,j,a[N][N],b[N][N];
//赋值
for(i=0;i<N;i++)
for(j=0;j<N;j++)
scanf("%d",&a[i][j]);
transposition(*a); //转置
//打印
printf("\ntransposition:\n");
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
printf("%d ",a[i][j]);
printf("\n");
}
return 0;
}
//转置
void transposition(int *p)
{
int i,j;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
*(p+i*N+j)=*(p+j*N+i);
}
8.10 5阶矩阵,最大元素放中间,最小值放4个角(左到右,上到下)
#include<stdio.h>
#define N 5
void transposition(int *p);
int main()
{
int i,j,a[N][N],b[N][N];
//赋值
for(i=0;i<N;i++)
for(j=0;j<N;j++)
scanf("%d",&a[i][j]);
transposition(*a); //转置
//打印
printf("\ntransposition:\n");
for(i=0;i<N;i++)
{
for(j=0;j<N;j++)
printf("%3d",a[i][j]);
printf("\n");
}
return 0;
}
/*
思考:
1.二维数组,*p=&a[0][0],可以看成是一个特殊的一维数组。
2.目的是找到最大值和最小值,先把最小最大值找到,最小值放在第一位,最大值放在中间,之后遍历除第一位外的所有元素找第二个最小值放在第一位,重复3次
3.把第2.3,4位上的最小值按要求赋值给其他3个角;
*/
void transposition(int *p)
{
int i,j;
int*max=p,*min=p,temp;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
if(*max<*(p+i*N+j))
max=p+i*N+j;
if(*min>*(p+i*N+j))
min=p+i*N+j;
}
if(max==p&&min==p+12) //最大值在第一个,最小值在中间,直接互换首尾
{
temp=*max; *max=*min; *min=temp;
}
else if(max==p) //最大值恰好在第一个,先交换最大值位置
{
temp=*(p+12); *(p+12)=*max; *max=temp;
temp=*p; *p=*min; *min=temp;
}
else //最小值恰好在中间先交换最小值位置(其他情况顺序任意)
{
temp=*p; *p=*min; *min=temp;
temp=*(p+12); *(p+12)=*max; *max=temp;
}
//找第二个最小值,交换到第二位上
min=p+1;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
if(i==0&&j<1)
continue;
else if(*min>*(p+i*N+j))
min=p+i*N+j;
}
temp=*(p+1); *(p+1)=*min; *min=temp;
//找第三个最小值,交换到第三位上
min=p+2;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
if(i==0&&j<2)
continue;
else if(*min>*(p+i*N+j))
min=p+i*N+j;
}
temp=*(p+2); *(p+2)=*min; *min=temp;
//找第四个最小值,交换到第四位上
min=p+3;
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
if(i==0&&j<3)
continue;
else if(*min>*(p+i*N+j))
min=p+i*N+j;
}
temp=*(p+3); *(p+3)=*min; *min=temp;
//处理最小数的位置
temp=*(p+1); *(p+1)=*(p+4); *(p+4)=temp;
temp=*(p+2); *(p+2)=*(p+20); *(p+20)=temp;
temp=*(p+3); *(p+3)=*(p+24); *(p+24)=temp;
}
/*
情况一:最大值在首位,最小值在中间
25 24 23 22 21
20 19 18 17 16
15 14 01 13 12
10 09 08 07 06
05 04 03 02 11
transposition:
1 21 5 11 2
20 19 18 17 16
15 14 25 13 12
10 9 8 7 6
3 22 23 24 4
情况二:最大值在首位,最小值不再中间
25 24 23 22 21
20 19 18 17 16
15 14 11 13 12
10 09 08 07 06
05 04 03 02 01
transposition:
1 21 5 11 2
20 19 18 17 16
15 14 25 13 12
10 9 8 7 6
3 22 23 24 4
情况三:最小值在中间,最大值不再首位
11 24 23 22 21
20 19 18 17 16
15 14 01 13 12
10 09 08 07 06
05 04 03 02 25
transposition:
1 21 5 11 2
20 19 18 17 16
15 14 25 13 12
10 9 8 7 6
3 22 23 24 4
情况四:非特殊情况
21 24 23 25 21
20 19 18 17 16
15 14 11 13 12
10 09 08 07 06
05 04 03 02 01
transposition:
1 21 5 21 2
20 19 18 17 16
15 14 25 13 12
10 9 8 7 6
3 11 23 24 4
*/
8.11 等长字符串排序
#include<stdio.h>
#include<string.h>
#define N 80
#define M 100
void sort(char (*p)[N],int m);
int main()
{
int i,m;
char a[M][N];
printf("请输入要排序的字符串个数:");
scanf("%d",&m);
getchar();
for(i=0;i<m;i++) //赋值
gets(a[i]);
sort(a,m); //排序
printf("sort after:\n");
for(i=0;i<m;i++) //赋值
puts(a[i]);
}
void sort(char (*p)[N],int m) //形参为指向一维数组的指针变量
{
int i,j;
char s[N]; //用于交换申请一个一维数组临时存储
for(i=0;i<m;i++)
{
for(j=i+1;j<m;j++)
{
if(strcmp(p[i],p[j])>0) //比较字符串
{
strcpy(s,p[i]); //赋值交换
strcpy(p[i],p[j]);
strcpy(p[j],s);
}
}
}
}
/*
请输入要排序的字符串个数:6
123
321
132
213
231
312
sort after:
123
132
213
231
321
312
*/
8.12 不等长字符串排序
#include<stdio.h>
#include<string.h>
#define N 80
#define M 100
void sort(char (*p)[N],int m);
int main()
{
int i,m;
char a[M][N];
printf("请输入要排序的字符串个数:");
scanf("%d",&m);
getchar();
for(i=0;i<m;i++) //赋值
gets(a[i]);
sort(a,m); //排序
printf("sort after:\n");
for(i=0;i<m;i++) //赋值
puts(a[i]);
}
void sort(char (*p)[N],int m) //形参为指向一维数组的指针变量
{
int i,j;
char s[N]; //用于交换申请一个一维数组临时存储
for(i=0;i<m;i++)
{
for(j=i+1;j<m;j++)
{
if(strcmp(p[i],p[j])>0) //比较字符串
{
strcpy(s,p[i]); //赋值交换
strcpy(p[i],p[j]);
strcpy(p[j],s);
}
}
}
}
/*
请输入要排序的字符串个数:5
1234564
alkshdlak
*/-*/9+/*
@827GAJD3
ASD6-*=-
sort after:
*/-*/9+/*
1234564
@827GAJD3
ASD6-*=-
alkshdlak
*/
8.13 用矩阵求定积分的通用函数
#include<stdio.h>
#include<math.h>
#define N 20
/****************主函数**************************************/
int main()
{
float integral(float(*)(float), float, float, int);
float fsin(float);
float fcos(float);
float fexp(float);
float a1, b1, a2, b2, a3, b3, c, (*p)(float);//定义一个float类型的指针
//输入积分上下限
printf("enter a1,b1:\n");
scanf("%f%f", &a1, &b1);
printf("enter a2,b2:\n");
scanf("%f%f", &a2, &b2);
printf("enter a3,b3:\n");
scanf("%f%f", &a3, &b3);
p = fsin;//用float型指针指向fsin函数
c = integral(p, a1, b1, N);
printf("sin(x)=%f\n", c);
p = fcos;//用float型指针指向fcos函数
c = integral(p, a2, b2, N);
printf("cos(x)=%f\n", c);
p = fexp;//用float型指针指向exp函数
c = integral(p, a3, b3, N);
printf("exp(x)=%f\n", c);
return 0;
}
float integral(float(*p)(float), float a, float b, int n)
{
//矩形法求定积分,把x轴细分为 n 等份,每1等份都视作矩形的高
//从下限x开始代入被积函数得到函数值为矩形底,定积分的值为这n个矩形累积之和
int i;
float x, h, s;
h = (b - a) / n;//牛顿莱布尼茨公式运用
x = a;
s = 0;
for (i = 0; i < n; i++)
{
x = x + h;
s = s + (*p)(x)*h;
}
return (s);
}
float fsin(float x)
{
return sin(x);
}
float fcos(float x)
{
return cos(x);
}
float fexp(float x)
{
return exp(x);
}
8.14 n个数顺序输入,逆序排列,函数实现
#include<stdio.h>
#include<math.h>
#define N 200
void fact(int *a,int n);
int main()
{
int i,n,a[N];
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&a[i]);
fact(a,n);
for(i=0;i<n;i++)
printf("%d ",a[i]);
}
void fact(int *a,int n)
{
int i,*p=a,temp;
for(i=0;i<n/2;i++)
{
temp=*p;
*p=*(p+n-1-i);
*(p+n-1-i)=temp;
}
}
8.15 学生成绩
#include<stdio.h>
#define N 4
#define M 5
/****************主函数**************************************/
void TheFirstave(int *p);
void Findpasstwo(int *p);
void Searchgreat(int *p);
int main()
{
int i,j,student[N][M];
//赋值
for(i=0;i<N;i++)
for(j=0;j<M;j++)
scanf("%d",&student[i][j]);
TheFirstave(*student);
Findpasstwo(*student);
Searchgreat(*student);
return 0;
}
void TheFirstave(int *p)
{
int i,sum=0;
double ave;
for(i=0;i<N;i++)
sum=sum+*(p+i*M);
ave=sum/N;
printf("%f\n",ave);
}
void Findpasstwo(int *p)
{
int i,j,sum=0,count=0;
for(i=0;i<N;i++)
{
for(count=0,j=0;j<M;j++)
{
if(*(p+i*M+j)<60)
count++;
}
if(count>=2)
{
printf("[%d]同学两门及以上不及格:各科成绩为",i+1);
for(j=0;j<M;j++)
printf("%d ",*(p+i*M+j));
printf("\n");
}
}
}
void Searchgreat(int *p)
{
int i,j,sum,count;
double ave;
for(i=0;i<N;i++)
{
for(count=0,sum=0,j=0;j<M;j++)
{
if(*(p+i*M+j)>=85)
count++;
sum=sum+*(p+i*M+j);
}
ave=sum/M;
if(count==5&&ave>=90)
printf("[%d]同学平均成绩在90,且各科均分在85以上",i+1);
}
}
8.16 统计字符串中连续数字构成的整数个数
#include<stdio.h>
#include<math.h>
#define N 80
int statisticsnumber(char *p);
int main()
{
char str[N];
gets(str);
printf("statistics number = %d",statisticsnumber(str));
}
int statisticsnumber(char *p)
{
int i,count=0;
int flag[N]={0};
for(i=0;*(p+i)!='\0';i++)
{
if(*(p+i)>='0'&&*(p+i)<='9')
flag[i]=1;
if(flag[i-1]==0&&flag[i]!=0)
count++;
}
return count;
}
8.17 实现strcmp函数,函数原型int strcmp(char *p1,char *p2)
#include<stdio.h>
#include<math.h>
#define N 80
int stringcmp(char *p1,char *p2);
int main()
{
char str1[N],str2[N],str3[N];
gets(str1);
gets(str2);
gets(str3);
printf("%s VS %s :",str1,str2);
printf("%d\n",stringcmp(str1,str2));
printf("%s VS %s :",str2,str3);
printf("%d\n",stringcmp(str2,str3));
printf("%s VS %s :",str3,str2);
printf("%d\n",stringcmp(str3,str2));
return 0;
}
int stringcmp(char *p1,char *p2)
{
int i,j;
for(i=0,j=0;*(p1+i)!='\0'||*(p2+j)!='\0';i++,j++)
{
if(*(p1+i)>*(p2+j))
return 1;
if(*(p1+i)<*(p2+j))
return -1;
}
if(*(p1+i)!='\0')
return -1;
else if(*(p2+j)!='\0')
return 1;
else if(*(p1+i)!='\0'&&*(p2+j)!='\0')
return 0;
}
8.18 输入月份号输出英文名月份
#include<stdio.h>
#include<math.h>
#define N 13
void monthexchange(int n);
int main()
{
int i,n;
scanf("%d",&n);
monthexchange(n);
}
void monthexchange(int n)
{
int i,a[N];
for(i=0;i<N;i++)
a[i]=i;
char *month[]={"0","January","February","March","April",
"May","June","July","August","September","October",
"November","December"};
for(i=1;i<N;i++)
{
if(a[i]==n)
printf("%s",month[i]);
}
if(i<1||i>12)
printf("非法输入");
}
8.19 动态分配申请空间函数和free释放申请空间函数
1.编写一个函数new,对n个字节开辟连续的存储空间,此函数应返回一个指针,指向字符串开始空间
2.写一个函数free,将前面new函数占用的空间释放,free§表示将p指向的单元以后的内存段释放。
#include<stdio.h>
#define NEWSIZE 1000 //开辟的最大空间
char newbuf[NEWSIZE]; //定义字符数组
char *newp=newbuf; //定义指针变量newp,指向存储区域的起始处
char *new(int n) //new函数
{
if(newp+n<newbuf+NEWSIZE) //不越界
{
newp+=n;
return newp-n; //够则返回起始位置
}
else
return NULL; //不够则返回空指针
}
void free(char *p)
{
if(p>=newbuf&&p<newbuf+NEWSIZE)
newp=p;
}
8.20 指向指针的指针,对5个字符串排序
//指针的指针需要严格区分出地址和值,字符数组的数组名也是地址
#include<stdio.h>
#include<string.h>
#define N 5
#define M 80
void Sort(char **p);
int main()
{
int i,j;
char str[N][M],*strp[N],**p;
//指针地址初始化
for(i=0;i<N;i++)
strp[i]=str[i];
//赋值
for(i=0;i<N;i++)
scanf("%s",str[i]);
p=strp;
Sort(p);
for(i=0;i<N;i++)
printf("%s\n",str[i]);
return 0;
}
void Sort(char **p)
{
int i,j;
char *temp;
for(i=0;i<N;i++)
{
for(j=i+1;j<N;j++)
{
if(strcmp(*(p+i),*(p+j))>0)
{
temp=*(p+i);
*(p+i)=*(p+j);
*(p+j)=temp;
}
}
}
}
8.21 指向指针的指针,n个整数排序
//指针的指针需要严格区分出地址和值
#include<stdio.h>
#define N 80
void Sort(int **p,int n);
int main()
{
int i,j,n;
int a[N],*ap[N],**p;
scanf("%d",&n);
//指针地址初始化
for(i=0;i<n;i++)
ap[i]=&a[i];
//赋值
for(i=0;i<n;i++)
scanf("%d",ap[i]);
p=ap;
Sort(p,n);
for(i=0;i<n;i++)
printf("%d ",*ap[i]);
return 0;
}
void Sort(int **p,int n)
{
int i,j;
int *temp;
for(i=0;i<n;i++)
{
for(j=i+1;j<n;j++)
{
if(**(p+i)>**(p+j))
{
temp=*(p+i);
*(p+i)=*(p+j);
*(p+j)=temp;
}
}
}
}