程序设计题(49-56)
第四十九题
题目
请编写函数void fun(int *dp, int n, int upordown), 其功能是,找出dp所指数组中的
最小或最大值,并与其第1个元素交换。形参n为元素的个数,
形参upordown为查找标志:值为0时找最小值;值为1时找最大值。
#include <stdio.h>
#include <stdlib.h>
#define N 10
#pragma warning (disable:4996)
void NONO(FILE *fp, int pd[], int n);
void fun (int *dp,int n,int upordown)
{
}
void display(int pd[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%4d",pd[i]);
printf("\n");
}
void main()
{
int data[N],i,n=N;
FILE *out ;
out = fopen("out.dat","w") ;
for(i=0;i<N;i++)
data[i]=rand()%90+10;
for(i=0;i<N-1;i++)
fun(data+i,n-i,0);
display(data,n);
NONO(out, data, n);
for(i=0;i<N;i++)
data[i]=rand()%90+10;
for(i=0;i<N-1;i++)
fun(data+i,n-i,1);
display(data,n);
NONO(out, data, n);
fclose(out);
}
void NONO(FILE *fp, int pd[], int n)
{
int i;
for(i=0;i<n;i++)
fprintf(fp, "%4d", pd[i]);
fprintf(fp, "\n");
}
解析
void fun (int *dp,int n,int upordown)
{
int i,j,max=dp[0],min=dp[0],a=0,s=0,temp;
if(upordown==0){
for(i=1;i<n;i++)
if(min>dp[i]){
min=dp[i];
a=i;
}
temp=dp[a];
dp[a]=dp[0];
dp[0]=temp;
}
if(upordown==1){
for(j=1;j<n;j++)
if(max<dp[j]){
max=dp[j];
s=j;
}
temp=dp[s];
dp[s]=dp[0];
dp[0]=temp;
}
}
分析
max=dp[0],min=dp[0],这里的赋值很关键,如果赋值为零的话,找最小值的时候就会出现一些问题,导致min的值不会更新
第五十题
题目
请编写函数fun,其功能是:验证参数n是否可以分解成2个素数相乘,是则返回1,否则
返回0,并通过指针变更x、y返回分解后的2个素数值,要求*x < *y。
主程序中将打印出分解结果。
例如:111=3*37, 当函数fun的参数n为111时,
可以分解为2个素数(3和37) 的乘积函数返回值为1。
另外,prime函 数验证参数m是否为素数,是则返回1,否则返回0。
#include<stdio.h>
#include<math.h>
int prime(int m)
{
int k,flag=1;
for(k=2;k<(int)sqrt((double)m);k++)
if(m%k==0)
flag=0;
return flag;
}
int fun(int n,int *x,int *y)
{
int k,flag=0;
return flag;
}
main()
{
int a,b;FILE *out ;
out = fopen("out.dat","w") ;
if(fun(111,&a,&b)) {
printf("111=%d*%d\n",a,b);
fprintf(out, "111=%d*%d\n",a,b);
}
if(fun(11111,&a,&b)) {
printf("11111=%d*%d\n",a,b);
fprintf(out, "11111=%d*%d\n",a,b);
}
if(fun(1111111,&a,&b)) {
printf("1111111=%d*%d\n",a,b);
fprintf(out,"1111111=%d*%d\n",a,b);
}
fclose(out);
getchar();
}
解析
int fun(int n,int *x,int *y)
{
int k,flag=0;
for(k=1;k<n/2;k++)
if(prime(k)&&n%k==0)
if(prime(n/k)){
*x=k;
*y=n/k;
flag=1;
break;
}
return flag;
}
分析
不明白为啥还要加 break;
第五十一题
题目
程序中定义了NXN的二维数组,并已在主函数中赋初值。
请编写函数fun,其功能是:将a所指数组主对角线上的元素分别乘以2;次对角线上的元素
分别乘以3,依次放入指针p所指的数组中。计算过程中不得修改a所指数组中的数据。
#include <stdio.h>
#define N 3
#pragma warning(disable:4996)
void NONO( );
void fun( int a[N][N],int *p)
{
}
main()
{ int a[N][N]={ 1,5,7,2,6,8,3,4,9};
int b[2*N],i;
fun(a,b);
for(i=0;i<2*N;i++)
printf("%d,",b[i]);
NONO();
}
void NONO( )
{ int a[N][N];
int b[2*N],i,j,k;
FILE *rf, *wf;
rf = fopen("in.dat","r") ;
wf = fopen("out.dat","w") ;
for(k=0; k<9;k++) {
for(i=0;i<N;i++)
for(j=0;j<N;j++)
fscanf(rf,"%d,",&a[i][j]);
fun(a,b);
for(i=0;i<2*N;i++)
fprintf(wf, "%d,",b[i]);
fprintf(wf, "\n");
}
fclose(rf);
fclose(wf);
}
解析
void fun( int a[N][N],int *p)
{
int i,j,n,k=0;
for(i=0;i<N;i++)
p[k++]=a[i][i]*2;
for(j=N-1,n=0;j>=0,n<N;j--,n++)
p[k++]=a[n][j]*3;
}
分析
次对角线的表达要好好记住
第五十二题
题目
函数fun的功能是:将a、b中的两个两位正整数合并形成一个新的整数放在c中。合并的方式是:将a中的十位和个位数依次放在变量c的十位和千位上,b中的十位和个位数依次放在变量c的个位和百位上。
例如,当a=45, b=12。调用该函数后,c=5241。
#include <stdio.h>
void fun(int a, int b, long *c)
{
}
main()
{ int a,b; long c;void NONO ();
printf("Input a b:");
scanf("%d%d", &a, &b);
fun(a, b, &c);
printf("The result is: %ld\n", c);
NONO();
getchar();
}
void NONO ()
{/* 本函数用于打开文件,输入数据,调用函数,输出数据,关闭文件。 */
FILE *rf, *wf ;
int i, a,b ; long c ;
rf = fopen("in.dat","r") ;
wf = fopen("out.dat","w") ;
for(i = 0 ; i < 10 ; i++) {
fscanf(rf, "%d,%d", &a, &b) ;
fun(a, b, &c) ;
fprintf(wf, "a=%d,b=%d,c=%ld\n", a, b, c) ;
}
fclose(rf) ;
fclose(wf) ;
}
解析
void fun(int a, int b, long *c)
{
*c=(a%10)*1000+(b%10)*100;
*c=*c+(a/10)*10+(b/10);
}
分析
第五十三题
题目
假定输入的字符串中只包含字母和*号。请编写函数fun,它的功能是:将字符串尾部的*号全部删除,前面和中间的*号不删除。
例如,字符串中的内容为:****A*BC*DEF*G*******,删除后,字符串中的内容应当是:****A*BC*DEF*G。在编写函数时,不得使用C语言提供的字符串函数。
#include <stdio.h>
void fun( char *a )
{
}
main()
{ char s[81];void NONO ();
printf("Enter a string:\n");gets(s);
fun( s );
printf("The string after deleted:\n");puts(s);
NONO();
getchar();
}
void NONO ()
{/* 本函数用于打开文件,输入数据,调用函数,输出数据,关闭文件。 */
FILE *in, *out ;
int i ; char s[81] ;
in = fopen("in.dat","r") ;
out = fopen("out.dat","w") ;
for(i = 0 ; i < 10 ; i++) {
fscanf(in, "%s", s) ;
fun(s) ;
fprintf(out, "%s\n", s) ;
}
fclose(in) ;
fclose(out) ;
}
解析
void fun( char *a )
{
int i,n=0;
char* p;
p=a;
while(*p!='\0'){
n++;
p++;
}
for(i=n-1;i>=0;i--)
if(a[i]!='*'){
a[i+1]='\0';
break;
}
}
分析
void fun( char *a )
{
int i,n=0;
while(*a!='\0'){
n++;
a++;
}
for(i=n-1;i>=0;i--)
if(a[i]!='*'){
a[i]='\0';
break;
}
}
很奇怪,观察这两个代码的不同,就知道这再进行for循环的时候a的指针已经不再a[0]了,已经跑到a末尾了。
第五十四题
题目
请编写一个函数,用来删除字符串中的所有空格。
例如,输入"asd af aa z67",则输出为"asdafaaz67"。注意:部分源程序存在文件prog1.c中。
#include <stdio.h>
#include <string.h>
void fun(char *str)
{
}
main()
{
char str[81];void NONO ();
printf("Input a string:") ;
gets(str);
puts(str);
fun(str);
printf("*** str: %s\n",str);
NONO();
getchar();
}
void NONO ()
{
/* 请在此函数内打开文件,输入调试数据,调用 fun 函数,
输出数据,关闭文件。 */
char str[81];
int n = 0;
FILE *rf, *wf ;
rf = fopen("in.dat","r") ;
wf = fopen("out.dat","w") ;
while(n < 10) {
fgets(str, 80, rf);
fun(str);
fprintf(wf, "%s", str) ;
n++ ;
}
fclose(rf) ;
fclose(wf) ;
}
解析
void fun(char *str)
{
char *readPtr = str; // 用于读取字符的指针
char *writePtr = str; // 用于写入字符的指针
// 遍历字符串直到遇到空字符
while (*readPtr != '\0') {
// 如果当前字符不是空格,则将其复制到 writePtr 指向的位置
if (*readPtr != ' ') {
*writePtr = *readPtr;
writePtr++;
}
readPtr++;
}
// 在新字符串的末尾添加空字符
*writePtr = '\0';
}
void fun(char *str)
{
int i, j = 0;
for (i = 0; str[i] != '\0'; i++) {
if (str[i] != ' ') {
str[j++] = str[i]; // 只有当字符不是空格时,才将其复制到新位置
}
}
str[j] = '\0'; // 在新字符串的末尾添加空字符
}
分析
我很懵逼,这是为啥
void fun(char *str)
{
int i,n=0;
while(str[n]!=' ')
n++;
for(i=n;*str!='\0';i++)
if(str[i]!=' ')
str[n++]=str[i];
str[n]='\0';
}
好的,让我们更详细地逐行解释这段代码:
```c
void fun(char *str)
{
```
这行定义了一个名为 `fun` 的函数,它接受一个参数 `str`,这是一个指向字符数组(字符串)的指针。
```c
int i, n = 0;
```
在函数内部,声明了两个整型变量 `i` 和 `n`。`i` 将用于后续的循环,而 `n` 用于记录字符串中第一个空格字符的位置。初始时,`n` 被设置为 0,即字符串的起始位置。
```c
while (str[n] != ' ')
n++;
```
这是一个 `while` 循环,它遍历字符串 `str`,直到找到第一个空格字符(`' '`)。在每次循环中,`n` 的值递增,直到找到空格字符。如果字符串中没有空格,`n` 将递增到字符串的长度,即直到遇到字符串的结束符 `\0`。
```c
for (i = n; *str != '\0'; i++)
```
这是一个 `for` 循环,它从找到的第一个空格的位置 `n` 开始,继续遍历字符串直到字符串的末尾(即直到遇到 null 字符,表示字符串结束)。`i` 是循环变量,用于跟踪当前遍历到的位置。
```c
if (str[i] != ' ')
str[n++] = str[i];
```
在 `for` 循环内部,有一个 `if` 语句检查当前字符(`str[i]`)是否不是空格。如果不是空格,则将该字符复制到 `str` 的 `n` 位置,并将 `n` 递增。这样,所有非空格字符都会被复制到字符串的前部分,覆盖掉第一个空格之前的所有字符。如果当前字符是空格,则不执行复制操作,`n` 也不会递增。
```c
str[n] = '\0';
```
最后,这行代码将 `str` 的 `n` 位置设置为 null 字符,从而结束字符串。这确保了字符串在删除了第一个空格之前的所有字符后正确终止。
### 总结
这个函数的作用是删除字符串中从开头到第一个空格之间的所有字符。如果字符串中没有空格,它将删除整个字符串,留下一个空字符串。这个函数不处理字符串中第一个空格之后可能出现的空格字符。
### 注意
这段代码有一个潜在的问题:如果字符串中没有空格,那么 `n` 将等于字符串的长度,这将导致 `for` 循环不执行,而 `str[n] = '\0';` 这行代码会在字符串的末尾之外的位置写入 null 字符,这可能会导致未定义行为。正确的做法应该是在 `for` 循环之后,而不是在 `while` 循环之后立即设置 null 字符。
第五十五题
题目
请编写函数fun,其功能是:编写函数char *fun(char * s0, char *s1, char *s2,char*s3),
要求实现:
将s0所指字符串分解成三个字符串,分别存入s1、s2、 s3所指内存中。分解的方法是,s1、 s2、s3从s0中依次顺序每隔3个字符取1个。
例如:s0为"abcdefghij"时,分解完成后,s1、s2、s3分别为: "adgj”、 "beh”、 "cfi”。
#include <stdio.h>
#include <string.h>
void fun(char * s0,char *s1,char *s2, char *s3)
{
}
void main()
{
void NONO();
char s0[100],s1[40],s2[40],s3[40];
printf("请输入一行字符串\n");
gets(s0);
fun(s0,s1,s2,s3);
puts(s1);
puts(s2);
puts(s3);
NONO();
}
void NONO()
{
FILE *fp = fopen("out.dat", "w");
char s0[10][100]={"1234567890qazwsx","abcdefghij","0987654321plmokn","fsdjfsdlrj564342dsf",
"gfdklgjdsfl4754398","zxcvbnmasdfg","asdfghjkl123","qwertyuiop456","qweasdzxc789",
"poiuytrewqwsxqaz"};
char s1[40],s2[40],s3[40];
int i;
for(i=0;i<10;i++)
{
fun(s0[i],s1,s2,s3);
fprintf(fp,"s1=%s,s2=%s,s3=%s\n", s1,s2,s3);
}
fclose(fp);
}
解析
void fun(char * s0,char *s1,char *s2, char *s3)
{
int i,a=0,s=0,d=0;
for(i=0;s0[i]!='\0';i++)
switch (i%3){
case 0:
s1[a++]=s0[i];
break;
case 1:
s2[s++]=s0[i];
break;
case 2:
s3[d++]=s0[i];
break;
}
s1[a]='\0';
s2[s]='\0';
s3[d]='\0';
}
分析
第五十六题
题目
根据哥德巴赫猜想,任意一个大偶数都可以分解为两个素数之和。但许多偶数分解为两个素数之和并不是唯一的。
请编写函数fun,其功能是:求1000(不包括1000)以内的所有恰好能分解成10组两个素数之和(5+109和109+5被认为是同一组) 的偶数,并依次存入数组a中并在屏幕上打印出来,打印时每个数单独一行,符合条件的个数通过函数值返回。
例如:114=5+109=7+107=11+103=13+101=17+97=31+83=41+73=43+71=47+67=53+61
114恰好可以分解为10组素数之和,因此114是我们要找的偶数。
而116=3+113=7+109=13+103=19+97=37+79=43+73
120=7+113=11+109=13+107=17+103=19+101=23+97=31+89=37+83=41+79=47+73=53+67=59+61
116可以分解为6组素数之和,120可以分解为12组素数之和,因此116和120都不是我们要找的偶数。函数prime用来判断一个数n是否为素数,是则返回1,否则返回0。
#include<stdio.h>
#include<math.h>
#pragma warning(disable:4996)
int prime(int n)
{ int k,flag=1;
for (k=2; k<=(int)sqrt((double)n); k++)
if (n%k == 0)
flag=0;
return flag;
}
int fun(int m, int a[])
{
int k, s, count, i=0;
for(k=6; k<=m; k+=2)
{ count = 0;
/* 请在此处填写代码 */
if (count == 10) {
printf("%d\n", k);
a[i++] = k;
}
}
return i;
}
main( )
{ int count, a[100];
void NONO(int count, int a[]);
count = fun(999, a);
NONO(count, a);
}
void NONO(int count, int a[])
{
FILE *fp;
int i;
fp = fopen("out.dat","w") ;
for(i=0; i<count; i++)
fprintf(fp, "%d\n", a[i]);
fclose(fp);
}
解析
int fun(int m, int a[])
{
int k, s, count, i=0;
for(k=6; k<=m; k+=2)
{ count = 0;
/* 请在此处填写代码 */
for (s = 2; s <= k / 2; s++)
if (prime(s) && prime(k - s))
count++;
if (count == 10) {
printf("%d\n", k);
a[i++] = k;
}
}
return i;
}
分析
int fun(int m, int a[])
{
int k, s, count, i = 0;
for (k = 6; k <= m; k += 2)
{
count = 0;
for (s = 0; s <= k / 2; s++)
if (prime(s) && prime(k - s))
count++;
if (count == 10) {
printf("%d\n", k);
a[i++] = k;
}
}
return i;
}
s=0就不对,的原因是在他那个判断素数的函数有毛病,他0,1也是素数,但事实上不是。真是无语。