《C语言程序设计实验与习题指导(第3版)》题目集

函数题

实验8-1-4 使用函数的选择法排序

本题要求实现一个用选择法对整数数组进行简单排序的函数。

函数接口定义

void sort( int a[], int n );

其中a是待排序的数组,n是数组a中元素的个数。该函数用选择法将数组a中的元素按升序排列,结果仍然在数组a中。

CODE

**记录这题就是想说,数组的形参a实际上是一个指针,主函数传递的是数组a的基地址。
**在函数中,既可以用a[ i ],也可以用 *(a+i)。

#include <stdio.h>
#define MAXN 10

void sort( int a[], int n );

int main()
{
   
   
    int i, n;
    int a[MAXN];

    scanf("%d", &n);
    for( i=0; i<n; i++ )
        scanf("%d", &a[i]);

    sort(a, n);

    printf("After sorted the array is:");
    for( i = 0; i < n; i++ )
        printf(" %d", a[i]);
    printf("\n");

    return 0;
}

/* 你的代码将被嵌在这里 */
void sort( int a[], int n )
{
   
   
    int index, tmp;
    for ( int i=0; i<n-1; i++ ){
   
   
        index = i;
        for ( int j=i+1; j<n; j++ ){
   
   
            if ( a[j]<a[index] ) index = j;
        }
        tmp = a[i];
        a[i] = a[index];
        a[index] = tmp;
    }
}

实验8-1-7 数组循环右移

本题要求实现一个对数组进行循环右移的简单函数:一个数组a中存有n(>0)个整数,将每个整数循环向右移m(≥0)个位置,即将a中的数据由(a​0​​a​1​​⋯a​n−1​​)变换为(a​n−m​​⋯a​n−1​​a​0​​a​1​​⋯a​n−m−1​​)(最后m个数循环移至最前面的m个位置)。

函数接口定义

int ArrayShift( int a[], int n, int m );

其中a[]是用户传入的数组;n是数组的大小;m是右移的位数。函数ArrayShift须将循环右移后的数组仍然存在a[]中。

**不过,这题有个奇怪的地方,循环右移并不需要返回值耶,题目却设为int,是不是一个bug
**而函数体中没有写return语句,实际上会返回一个不确定的值

CODE 1

**依次循环右移

#include <stdio.h>
#define MAXN 10

int ArrayShift( int a[], int n, int m );

int main()
{
   
   
    int a[MAXN], n, m;
    int i;

    scanf("%d %d", &n, &m);
    for ( i = 0; i < n; i++ ) scanf("%d", &a[i]);

    ArrayShift(a, n, m);

    for ( i = 0; i < n; i++ ) {
   
   
        if (i != 0) printf(" ");
        printf("%d", a[i]);
    }
    printf("\n");

    return 0;
}

/* 你的代码将被嵌在这里 */
int ArrayShift( int a[], int n, int m )
{
   
   
    int tmp;
    m %= n;
    for ( int i=0; i<m; i++ ){
   
    //右移m次
        tmp = a[n-1]; //每次记录下最后一个数
        for ( int j=n-1; j>0; j-- ){
   
    //前面的数全部后移一位
            a[j] = a[j-1];
        }
        a[0] = tmp; //把原来的最后一位赋给右移后的第一位
    }
}

CODE 2

**开辟一个新的数组做副本

int ArrayShift( int a[], int n, int m )
{
   
   
    int tmp[MAXN];
    m %= n;
    for ( int i=0; i<n; i++ ){
   
   
        tmp[i] = a[i];
    }
    for ( int i=0; i<n; i++ ){
   
   
        a[i] = tmp[(i+n-m)%n];
    }
}

实验8-1-8 报数

报数游戏是这样的:有n个人围成一圈,按顺序从1到n编好号。从第一个人开始报数,报到m(<n)的人退出圈子;下一个人从1开始报数,报到m的人退出圈子。如此下去,直到留下最后一个人。
本题要求编写函数,给出每个人的退出顺序编号。

函数接口定义

void CountOff( int n, int m, int out[] );

其中n是初始人数;m是游戏规定的退出位次(保证为小于n的正整数)。函数CountOff将每个人的退出顺序编号存在数组out[]中。因为C语言数组下标是从0开始的,所以第i个位置上的人是第out[i-1]个退出的。

裁判测试程序样例

#include <stdio.h>
#define MAXN 20

void CountOff( int n, int m, int out[] );

int main()
{
   
   
    int out[MAXN], n, m;
    int i;

    scanf("%d %d", &n, &m);
    CountOff( n, m, out );   
    for ( i = 0; i < n; i++ )
        printf("%d ", out[i]);
    printf("\n");

    return 0;
}

/* 你的代码将被嵌在这里 */

输入样例

11 3

输出样例

4 10 1 7 5 2 11 9 3 6 8 

CODE

**这题主要是要理解题意,out[i]记录的是第i+1个人是第几个退出的( ̄▽ ̄)"

void CountOff( int n, int m, int out[] )
{
   
   
    int i, a[MAXN];
    int j=1; //记录退出顺序
    int cnt = 0; //报数次数
    //记录这n个人顺序编号
    for ( i=0; i<n; i++ ){
   
   
        a[i] = i+1;
    }
    for ( i=0; j<=n; i++ ){
   
    //很坑的是,说是留下一个人,但out[]却算了最后一个人
        if ( a[i]!=-1 ) //如果不是被剔除的人的位置,则参与报数
            cnt++; //报数+1
        if ( cnt==m ){
   
   
            out[i] = j; //记录下退出者的编号
            j++;
            a[i] = -1; //从编号中剔除
            //n--; //从报数人数中剔除
            cnt = 0; //重置报数次数
        }
        if ( i==n-1 ) //报数报完一轮,则重新开始
            i = -1; //注意,下一轮报数前会进行i++
    }
}

实验8-2-7 字符串的连接

函数接口定义

char *str_cat( char *s, char *t );

函数str_cat应将字符串t复制到字符串s的末端,并且返回字符串s的首地址。

CODE

**这题有个地方:for循环条件判断那里,如果不用n代换,而是直接二者相加,就会出现测试点1——超长字符串相接,发生运行时错误(如数组越界访问等)。
**因为s[ ] 一直在变长。

#include <stdio.h>
#include <string.h>

#define MAXS 10

char *str_cat( char *s, char *t );

int main()
{
   
   
    char *p;
    char str1[MAXS+MAXS] = {
   
   '\0'}, str2[MAXS] = {
   
   '\0'};

    scanf("%s%s", str1, str2);
    p = str_cat(str1, str2);
    printf("%s\n%s\n", p, str1);

    return 0;
}

/* 你的代码将被嵌在这里 */
char *str_cat( char *s, char *t )
{
   
   
    int i, j=0;
    int n = strlen(s) + strlen(t);
    for ( i=strlen(s); i<n; i++, j++ ){
   
     //---(*)
        s[i] = t[j];
    }
    s[i] = '\0';
    return s;
}

实验8-2-9 长整数转化成16进制字符串(*)

函数接口定义

void f( long int x, char *p );

其中x是待转化的十进制长整数,p指向某个字符数组的首元素。函数f的功能是把转换所得的16进制字符串写入p所指向的数组。16进制的A~F为大写字母。

CODE

**这题需要注意:

  1. 指针是字符型的,所以要赋给它字符型常量或变量的值
  2. 十进制数是long int型的,所以副本也应定义为long int
#include <stdio.h>
#define MAXN 10

void f( long int x, char *p );

int main()
{
   
   
    long int x;
    char s[MAXN] = "";

    scanf("%ld", &x);
    f(x, s);
    printf("%s\n", s);

    return 0;
}

/* 你的代码将被嵌在这里 */
void f( long int x, char *p )
{
   
   
    int len = 0; //十六进制数的长度
    long int tmp; //复制十进制数x
    int m; //转进制时取余
    //零单独拎出来
    if ( x==0 )
        *p = '0';
    //负数加负号
    if ( x<0 ){
   
   
        *p = '-';
        x = -x;
        len++;
    }
    //正数或者本来是负数
    tmp = x; //副本
    if ( x>0 ){
   
   
        //计算长度
        do{
   
   
            x /= 16;
            len++;
        }while( x!=0 );
        x = tmp;
        //转进制
        for ( int i=0; i<MAXN; i++ ){
   
   
            m = x % 16;
            x /= 16;
            //将转换后的“余数”倒着放入数组中
            if ( m<=9 ) *(p+len-1-i) = m + '0';
            else *(p+len-1-i) = m -10 + 'A';
            if ( x==0 ) break;
        }
    }
}

实验10-5 递归求简单交错幂级数的部分和

本题要求实现一个函数,计算下列简单交错幂级数的部分和:
f(x,n)=x−x​2​​+x3​​−x​4​​+⋯+(−1)​n−1​​x​n​​

函数接口定义

double fn( double x, int n );

其中题目保证传入的n是正整数,并且输入输出都在双精度范围内。函数fn应返回上述级数的部分和。建议尝试用递归实现。

CODE

**注意,fn()函数中不要在递归前区分加减,应该在幂函数项前控制加减

#include <stdio.h>

double fn( double x, int n );

int main()
{
   
   
    double x;
    int n;

    scanf("%lf %d", &x, &n);
    printf("%.2f\n", fn(x,n));

    return 0;
}

/* 你的代码将被嵌在这里 */
double ppow( double x, int n )
{
   
   
    if ( n==1 ) return x;
    else return x*ppow(x,n-1);
}
double fn( double x, int n )
{
   
   
    if ( n==1 ) return x;
    else if ( n%2 ) return ppow(x,n)+fn(x,n-1);
    else return -ppow(x,n)+fn(x,n-1);
}

实验10-9 递归将十进制转换二进制

本题要求实现一个函数,将正整数n转换为二进制后输出。

函数接口定义

void dectobin( int n );

函数dectobin应在一行中打印出二进制的n。建议用递归实现。

CODE

**这里需要理解,十进制转二进制时,除以2,最终十进制数都会变成0或1;而后依次向上取余

#include <stdio.h>

void dectobin( int n );

int main()
{
   
   
    int n;

    scanf("%d", &n);
    dectobin(n);

    return 0;
}

/* 你的代码将被嵌在这里 */
void dectobin( int n )
{
   
   
    if ( n==0 ) printf("0");
    else if ( n==1 ) printf("1");
    else{
   
   
        dectobin(n/2); //最先打印最底层(最高位)
        printf("%d", n%2); //再打印上面一层
    }
}

实验10-10 递归实现顺序输出整数

本题要求实现一个函数,对一个整数进行按位顺序输出。

函数接口定义

void printdigits( int n );

函数printdigits应将n的每一位数字从高位到低位顺序打印出来,每位数字占一行。

CODE

**深入理解上一实验

void printdigits( int n )
{
   
   
    if ( n/10==0 ) printf("%d\n", n);
    else{
   
   
        printdigits(n/10);
        printf("%d\n", n%10);
    }
}

实验11-1-6 指定位置输出字符串

本题要求实现一个函数,对给定的一个字符串和两个字符,打印出给定字符串中从与第一个字符匹配的位置开始到与第二个字符匹配的位置之间的所有字符。

函数接口定义

char *match( char *s, char ch1, char ch2 );

函数match应打印s中从ch1到ch2之间的所有字符,并且返回ch1的地址。

裁判测试程序样例

#include <stdio.h>

#define MAXS 10

char *match( char *s, char ch1, char ch2 );

int main()
{
   
   
    char str[MAXS], ch_start, ch_end, *p;

    scanf("%s\n", str);
    scanf("%c %c", &ch_start, &ch_end);
    p = match(str, ch_start, ch_end);
    printf("%s\n", p);

    return 0;
}

/* 你的代码将被嵌在这里 */

CODE 1

**出错:测试点1——ch1找不到,ch2找到
**改成一个return即可;返回NULL即有两个回车,返回s+i就有两个回车加一个空行

char *match( char *s, char ch1, char ch2 )
{
   
   
    int i, j;
    for ( i=0; s[i]!='\0'; i++ ){
   
   
        if ( s[i]==ch1 ){
   
   
            for ( j=i; s[j]!='\0'; j++ ){
   
   
                printf("%c", s[j]);
                if ( s[j]==ch2 ) break;
            }
            break;
        }
    }
    printf("\n");
    //if ( s[i]=='\0' ) return NULL;
    //else return s+i;
    return s+i;  
}

CODE 2

char *match( char *s, char ch1, char ch2 )
{
   
   
    char *t = "";
    int i = 0, mark = -1;
    while ( s[i] && s[i]!=ch1 ) i++;
    if ( s[i]==ch1 ){
   
   
        t = s + i;
        mark = i;
    }
    while ( s[i] && s[i]!=ch2 ) i++;
    if ( s[i]!=ch2 ) i--;
    if ( mark!=-1 ){
   
   
        while( mark<=i ){
   
   
            putchar(s[mark
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值