C 程序设计(第五版) 书后题解(仅供参考)

Posted on 2022-11-24 21:20  梦中千秋  阅读(155)  评论(0编辑  收藏  举报

文章目录

第一章 程序设计和C语言

1 概念

**程序:**一组计算机能够识别和执行的指令。

**程序设计:**从确定任务到得到结果,写出文档的全过程。

2 特点

**为什么:**为了方便人与计算机之间的交流。

**有哪些特点:**结构丰富、可读性好、可维护性强、可靠性高、易学易掌握、可移植性高,重用率高,与机器依赖性低。

3 理解含义

(1)、

**源程序:**用C语言编写的程序(后缀.c)。

**目标程序:**对源程序进行编译,编译系统会自动将源程序转换为二进制形式的目标程序(后缀.obj)。

**可执行程序:**将经过编译后的所有目标程序和系统的函数库连接成一个整体,生成一个可供计算机执行的目标程序,称为可执行程序(后缀.exe)。

(2)、

**程序编辑:**对源程序进行输入和编辑。

**程序编译:**由C编译系统提供的“预处理器”对程序中的预处理命令进行预编译处理,然后对源程序进行编译。

**程序连接:**将所有编译后得到的目标模块装配起来,再与库函数相连接成一个整体。

(3)、

**程序:**一组计算机能够识别和执行的指令。

**程序模块:**一个源文件程序就是一个程序模块。

**程序文件:**输入和编辑源程序后,将源程序以文件形式存放。

(4)、

**函数:**函数是C程序的基本单位

**主函数:**即main函数,一个C程序必须包含一个main函数,且有且只能有一个。

**被调用函数:**可以是系统提供的库函数,也可以是用户根据需要自己编制设计的函数。

**库函数:**系统所提供的函数。

(5)、

**程序调式:**通过上机发现和排除程序中故障的过程。

**程序测试:**设计多组测试数据,检查测序对不同数据的运行情况,从中尽量发现程序中存在的漏洞,并修改程序,使之能够适用于各种情况。

4 Hello 程序

#include <stdio.h>
int main(){
    printf("Hello world!");
    return 0;
}

5 特殊图案

# include<stdio.h>
int main(){
    for(int i = 0;i < 4;i++){
        for(int j = 0; j < i; j++) printf("  ");
        printf("*****\n");
    }
    return 0;
}
*****
*****    
 *****  
   *****

6 三者最大值

#include <stdio.h>
int main(){
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    printf("%d", a > b ? (a > c ? a : c) : (b > c ? b : c));
    return 0;
}
	int a,b,c,temp;
    scanf("%d%d%d",&a,&b,&c);
	temp = a > b?a:b;
	printf("%d", temp > c ? temp : c);

7 省

第二章 算法——程序的灵魂

1 算法

**算法:**广义地说,为解决一个问题而采取的方法和步骤,就称为“算法”。

2 结构化的算法

**结构化的算法:**由基本结构所构成的算法。

**为什么:**便于编写、阅读、修改和维护,减少了程序出错的机会,提高了程序的可靠性,保证了程序的质量。

3 三种基本结构

**顺序结构:**按顺序执行,不可跳转。

**选择结构:**根据条件判断选择是否执行。

**循环结构:**反复执行某一部分操作。

特点:(1)只有一个入口。(2)只有一个出口。(3)结构内的每一部分都有机会被执行到。(4)不存在“死循环”。

4 传统流程图

(1)

开始
A=醋,B=酱油
C=空
C=A醋,A=空
A=B酱油,B=空
B=C醋
A=酱油,B=醋
Created with Raphaël 2.3.0 开始 输入x x>0? 输出x 结束 是否重新输入 yes/no yes no yes no

5 N-S图

6 伪代码

7 结构化程序设计

用计算机语言表示的结构化算法

**基本思路:**把一个复杂的问题的求解过程分阶段进行,每个阶段处理的问题都控制在人们容易理解和处理的范围内。

8 自顶向下

(1)

统计1900-2000之间的闰年
能被4整除
不能被100整除
能被400整除

(2)

ax^2+bx+c=0
d=b^2-4ac > 0
方程有两个不同的解
d=b^2-4ac = 0
方程有且仅有一个解
d=b^2-4ac < 0
方程无解

(3)

第三章 顺序程序设计

1 简单公式计算年利率

#include <stdio.h>
#include <math.h>
int main(){
    double p, r = 0.07;
    int n = 10;
    p = pow(1+r, n);
    printf("%f", p);
    return 0;
}

1.967151

2 不同存款方式的利息

(1)

#include <stdio.h>
int main(){
    double r = 0.03, P, m = 1000.0;  //利息,本息和,本金
    int n = 5; //存款年数
    P = m * (1 + n * r);
    printf("%.2f", P);
    return 0;
}

1150.00

(2)

#include <stdio.h>
int main(){
    //先存两年
    double r = 0.021, P, m = 1000.0;  //利息,本息和,本金
    int n = 2; //存款年数
    P = m * (1 + n * r);
    //再存三年
    r = 0.0275;
    n = 3;
    P *= 1 + n * r;
    printf("%.2f", P);
    return 0;
}

1127.96

(3)

#include <stdio.h>
int main(){
    //先存三年
    double r = 0.0275, P, m = 1000.0;  //利息,本息和,本金
    int n = 3; //存款年数
    P = m * (1 + n * r);
    //再存两年
    r = 0.021;
    n = 2;
    P *= 1 + n * r;
    printf("%.2f", P);
    return 0;
}

1127.96

(4)

#include <stdio.h>
int main(){
    double r = 0.015, P = 1000.0;  //利息,本息和,本金
    int n = 1; //存款年数
    for(int i = 0; i < 5; i++) P *= 1 + n * r;
    printf("%.2f", P);
    return 0;
}

1077.28

(5)

#include <stdio.h>
#include <math.h>
int main(){
    double r = 0.0035, P, m = 1000.0;  //利息,本息和,本金
    int n = 5; //存款年数
    P = m * pow((1 + r/4), 4*n);
    printf("%.2f", P);
    return 0;
}

1017.65

3 贷款买房

#include <stdio.h>
#include <math.h>
int main(){
	double d = 300 000,p=6 000,r=0.01, m;
    m = log10(p/(p-d*r))/log10(1+r);
    printf("%.1f",m);
    return 0;
}

69.7

4 超存储界限,发生阶段

char 只有 8位, 如果强行存入了超过8位的, 只对后8位生效

(1)

c1=a,c2=b c1=97,c2=98

(2)

如系统不支持128~255的字符输出,将会输出:

c1=E,c2=F c1=69,c2=70

(3)

c1=E,c2=F c1=69,c2=70

5 输入问题

a=3b=7

8.5 71.82

Aa

6 简单加密输出

#include <stdio.h>
int main(){
    char c1='C',c2='h',c3='i',c4='n',c5='a';
    putchar(c1+=4);
    putchar(c2+=4);
    putchar(c3+=4);
    putchar(c4+=4);
    putchar(c5+=4);
    putchar('\n');
    printf("%c",c1);
    printf("%c",c2);
    printf("%c",c3);
    printf("%c",c4);
    printf("%c",c5);
    return 0;
}

7 圆 球相关计算

#include <stdio.h>
int main(){
    double r = 1.5,h = 3; //圆半径,圆柱高
    const double pi = 3.1415926;
    //scanf("%lf%lf",&r,&h);
    printf("圆周长: %.2f\n",2*pi*r);
    printf("圆面积: %.2f\n",pi*r*r);
    printf("圆球表面积: %.2f\n",4*pi*r*r);
    printf("圆球体积: %.2f\n",4.0/3*pi*r*r*r);
    printf("圆柱体积: %.2f\n",pi*r*r*h);
    return 0;
}

圆周长: 9.42
圆面积: 7.07
圆球表面积: 28.27
圆球体积: 14.14
圆柱体积: 21.21

8 字符

(1)皆可

(2)以十进制输出字符,可得到其字符的ASCLL码值:printf("%d",c1);

(3)不是,char只占用1字节,而int占用4字节,大于255的数存入char会失真。

第四章 选择结构

1 运算概念

算术运算:对数值进行加减乘除取余等操作。

关系运算:将两个数值进行比较,判断其比较的结果。

逻辑运算:将关系表达式或其他逻辑两连接起来。

2 真假表示

表示:用表达式表示“真”“假”,包括算术表达式,逻辑表达式,关系表达式,赋值表达式,其中关系表达式最直观。

判断:表达式的值,如为数值0表示“假”,非0表示“真”。

3 逻辑表达式的值

(1)0

(2)0

(3)1

(4)0

(5)1

4 三者最大

#include <stdio.h>
int main(){
    int a,b,c;
    scanf("%d%d%d",&a,&b,&c);
    int temp = a>b? a:b;
    printf("%d",temp>c? temp:c);
    return 0;
}

5 按整求平方根

#include <stdio.h>
int main(){
    int num,res=31; //1000以内的数,最大平方根为31(向下取整) 31的平方为961
    do
        scanf("%d",&num);
    while(num>=1000||num<0);
    while(res*res>num) res--;  //按整可以用此法
    printf("%d",res);
    return 0;
}

6 分段函数

#include <stdio.h>
int main(){
    int x, y;
    scanf("%d",&x);
    if(x<1) y=x;
    else if(x>=10) y=3*x-11;
    else y=2*x-1;
    printf("%d",y);
    return 0;
}

7 分析程序

不能,if……else 配对有问题。

8 成绩等级

#include <stdio.h>
int main(){
    int score,level; //虽然分数限制在0~100以内,在char的范围,但是输入某些数(比如288,会输出E)会"截取"后再判断,逃过判断条件.
    do
        scanf("%d",&score);
    while(score>100||score<0);
    switch(score/10){
        case 10: 
        case 9: level = 'A'; break;
        case 8: level = 'B'; break;
        case 7: level = 'c'; break;
        case 6: level = 'D'; break;
        default: level = 'E';
    }
    printf("你的成绩等级是: %c",level);
    return 0;
}

9 统计位数,输出各位值

#include <stdio.h>
int main(){
    int count=1, num;
    do
        scanf("%d",&num);
    while(num>99999||num<0);
    int temp = num;  //临时变量,不改变num值
    while(temp/=10) count++;  //统计位数
    printf("位数: %d\n",count);
    
    int div = 1;
    while(--count) div*=10;  //根据不同位数,得到除数
    do
        printf("%d\t",num/div%10);  //以正序方式输出各位值
    while(div/=10);
    putchar(10);  //换行
    do
        printf("%d\t",num%10);  //倒序输出各位值
    while(num/=10);
    return 0;
}

10 ***分阶段计利润累加

(1)

#include <stdio.h>
int main(){
    double P=0,I;
    scanf("%lf",&I);
    while(I)
        if(I<=100000) {P+=I*0.1; I = 0;}  
    	else if(I>100000&&I<=200000) {P+=(I-100000)*0.075; I = 100000;}  
    	else if(I>200000&&I<=400000) {P+=(I-200000)*0.05; I = 200000;}  
    	else if(I>400000&&I<=600000) {P+=(I-400000)*0.03; I = 400000;}  
    	else if(I>600000&&I<=1000000) {P+=(I-600000)*0.015; I=600000;}
    	else {P+=(I-1000000)*0.01; I=1000000;}
    printf("%.2f",P);
    return 0;
}
#include <stdio.h>
int main(){
    double P=0,I;
    scanf("%lf",&I);
    //为毛要减一? I<=100 000 => I-1<100 000 => (I-1)/100 000 == 0
    // 利润为 0,怎么办?
    switch((int)(I-1)/100000){
        default: P+=(I-1000000)*0.001; I = 1000000;
        case 10:
        case 9:
        case 8:
        case 7:
        case 6: P+=(I-600000)*0.015; I = 600000;
        case 5: 
        case 4: P+=(I-400000)*0.03; I = 400000;   
        case 3:
        case 2: P+=(I-200000)*0.05; I = 200000;    
        case 1: P+=(I-100000)*0.075; I = 100000;   
        case 0: P+=I*0.1;        
    }
    printf("%.2f",P);   
    return 0;
}

11 排序

#include <stdio.h>
int main(){
    int arr[4],i,j,k=0;
    for( i=0; i<4; i++) scanf("%d",arr+i);
    for( i=0; i<4; i++)
    	for( j=i+1; j<4; j++)
            if(arr[i]>arr[j]){
                int temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
    while(4-k) printf("%d\t",arr[k++]);
	return 0;   
}

12 范围确定

#include <stdio.h>
#include <math.h>
int main(){
    double x,y,l; //l 距离圆心的距离
    int h=0,r=1; 
    scanf("%lf%lf",&x,&y); //坐标
    x = fabs(x);
    y = fabs(y);
    l = sqrt(pow(2-x,2)+pow(2-y,2));
    if(l<r) h = 10;
    printf("%d",h);
    return 0;
}

第五章 循环结构

1 流程图

2 pi近似值与精度

#include <stdio.h>
int main(){
    int sign = 1,count=0;
    double pi = 0.0,n=1.0,term=1.0;
    while(fabs(term)>=1e-8){
        pi+=term;
        n+=2;
        sign=-sign;
        term=sign/n;
        count++; //统计循环次数
    }
    pi*=4;
    printf("%.8f\n",pi);
    printf("循环了%d次",count);
    return 0;
}

1e-8:

3.14159263
循环了50000000次

1e-6:

3.14159065
循环了500000次

3 最大公约数与最大公倍数

int gcd (int x, int y)
     {
         if (y==0)
            return x;
         else 
             return gcd (y,x%y); 
  }
 /* 辗转相除法基于如下原理:
    两个整数的最大公约数等于其中较小的数和两数的相除的余数的最大公约数
 那y和x%y如果余数为0,那y不就是最大公约数
    补充:两个数的最小公倍数等于  x*y/gcb(x,y);
*/
#include <stdio.h>
int main(){
    int m,n;
    scanf("%d%d",&m,&n);
    int i = m < n ? m:n;
    for(;i>1;i--)
        if(m%i==0&&n%i==0) break;
	printf("最大公约数为:%d\n",i);
    i = m > n ? m:n;
    for(;i<m*n;i++)
        if(i%m==0&&i%n==0) break;
    printf("最大公倍数为:%d",i);
    return 0;
}

4 分类统计字符

#include <stdio.h>
int main(){
    char str[100],*p;
    int z=0,k=0,s=0,q=0;
    p = str;
    gets(str);
    do
        if((*p<=122&&*p>=97)||(*p>=65&&*p<=90)) z++;
        else if(*p>=48&&*p<=57) s++;
        else if(*p==' ') k++;
        else q++;
    while(*p++);
    printf("字母有%d个",z);
    printf("空格有%d个",k);    
    printf("数字有%d个",s);
    printf("其他字符有%d个",q);
    return 0;
}

5 2+22+222…

#include <stdio.h>
#include <math.h>
int main(){
    int a = 2,n,S=0,no=0;  // no 第n项的值
    scanf("%d",&n);
    for(int i = 0; i < n; i++){
        no += a * pow(10,i);  //第i+1项
    	S+=no;  //累加
    }        
	printf("%d",S);
    return 0;
}

6 阶乘的前N项和

#include <stdio.h>
//递归求得第N项的阶乘
int func(int n){
    if(n==1) return 1;
    return func(n-1)*n;
}

int main(){
    int sum,i=20;
    while(i) sum+=func(i--); 
    printf("%d",sum);
    return 0;
}

268040729

7 求和

#include <stdio.h>
int main(){
    double sum,sum1=0,sum2=0,sum3=0;
    int i;
    sum1 = (1 + 100)*100/2;
    i = 51;
    while(--i) sum2+=i*i;
    i = 11;
    while(--i) sum3+=1.0/i;
    sum=sum1+sum2+sum3;
    printf("%.6f",sum);
    return 0;
}

47977.928968

8 水仙花数

#include <stdio.h>
#include <math.h>
int main(){
    double g,s,b;  //pow返回double类型!!!确保精度
    for(int i = 100;i<1000;i++){
        g = pow(i%10,3);
        s = pow(i/10%10,3);
        b = pow(i/100%10,3);
        if(g+s+b == i) printf("%d\t",i);
    }
    return 0;
}

153 370 371 407

9 完数

#include <stdio.h>

int main(){
    int sum;
    for (int i = 6; i < 1000; i++){
        sum = 0;  //!!!循环内赋值初始值,每次循环清零重新统计
        for (int j = 1; j <= i / 2; j++)
            if (i % j == 0) sum += j;
        if (sum == i){
            printf("\n%d its factors are ", i);
            for (int j = 1; j <= i / 2; j++){
                if(i%j==0&&j!=1) printf(",");
                if (i % j == 0) printf("%d,", j);
            }                
        }
    }
    return 0;
}

6 its factors are 1,2,3,
28 its factors are 1,2,4,7,14,
496 its factors are 1,2,4,8,16,31,62,124,248,

完美主义

#include <stdio.h>

int main(){
    int sum;
    for (int i = 6; i < 1000; i++){
        sum = 0;  //!!!循环内赋值初始值,每次循环清零重新统计
        for (int j = 1; j <= i / 2; j++)
            if (i % j == 0) sum += j;
        if (sum == i){
            printf("\n%d its factors are ", i);
            for (int j = 1; j <= i / 2; j++){
                if(i%j==0&&j!=1) printf(",");  //第一个因子必然是1
                if (i % j == 0) printf("%d", j);
            }                
        }
    }
    return 0;
}

6 its factors are 1,2,3
28 its factors are 1,2,4,7,14
496 its factors are 1,2,4,8,16,31,62,124,248

10 Fibinacci 前N项和

#include <stdio.h>
//求第N项
double fun(int n){
    if(n==1 || n==0) return 1.0;
    return fun(n-1)+fun(n-2);
}

int main(){
    double m,n,sum=0;
    for(int i = 1;i<=20;i++)
        sum+=fun(i+1)/fun(i);
    printf("%f",sum);
    return 0;
}

32.660261

11 球球反弹

#include <stdio.h>
//第N次反弹的距离
double func(int n){
    if(n==1) return 50.0;  //第一次反弹100的一半
    return func(n-1)/2;  //每一次落下反弹的距离是前一次的一半
}

int main(){
    double h,sum = 0.0;
    for(int i = 1;i<10;i++)
        sum+=func(i);
    sum = sum*2+100;  //反弹50米,落下50米,乘以2,加最初落下的100米.
    printf("总共经历了%f米,第10次反弹了%f米",sum,func(10));    
    return 0;
}

总共经历了299.609375米,第10次反弹了0.097656米

12 吃桃子

#include <stdio.h>
//求第N天所剩下的桃子
int fun(int n){
    if(n==10) return 1;  //第10天剩下一个
    return (fun(n+1)+1)*2;  // 当天 - 当天的1/2 - 1 = 第二天 =>(化简得) 当天 = 2 * (第二天+ 1)
}

int main(){
    printf("%d",fun(1));
    return 0;
}

1534

13 迭代法求平方根

#include <stdio.h>
#include <math.h>
int main(){
    double x = 0.0,x1=1.0,a;
    scanf("%lf",&a);
    while(fabs(x1-x)>=1e-5){
        x = x1;
        x1 = (x + a / x) / 2;
    }
    printf("%f\n",x1);
    return 0;
}

999
31.606961

14 牛顿迭代法

image-20220406133021240

#include<stdio.h>
#include<math.h>
double func(double x){ //举例函数
    return 2*x*x*x-4*x*x+3*x-6.0;
}
double func1(double x){ //导函数
    return 6*x*x-8*x+3;
}
int Newton(double *x,double precision,int maxcyc){      //maxcyc 迭代次数
    double x1,x0;
    int k;
    x0=*x;
    for(k=0;k<maxcyc;k++){
        if(func1(x0)==0.0){//若通过初值,函数返回值为0
            printf("迭代过程中导数为0!\n");
            return 0;
        }
        x1=x0-func(x0)/func1(x0);//进行牛顿迭代计算
        if(fabs(x1-x0)<precision || fabs(func(x1))<precision){//达到结束条件
            *x=x1; //返回结果
            printf("该值附近的根为:%lf\n",*x);
            return 1;
        }
        else //未达到结束条件
            x0=x1; //准备下一次迭代
    }
    printf("迭代次数超过预期!\n"); //迭代次数达到,仍没有达到精度
    return 0;
}
 
int main(){
    double x,precision;
    int maxcyc;
    printf("输入初始迭代值x0:");
    scanf("%lf",&x);
    printf("输入最大迭代次数:");
    scanf("%d",&maxcyc);
    printf("迭代要求的精度:");
    scanf("%lf",&precision);
    if(Newton(&x,precision,maxcyc)==1) //若函数返回值为1
    ;
    else //若函数返回值为0
        printf("迭代失败!\n");
    return 0;
}

输入初始迭代值x0:1.5
输入最大迭代次数:1000
迭代要求的精度:1e-5
该值附近的根为:2.000000

15 二分法求近似解

递归

#include <stdio.h>
#include <math.h>

double fun(double low, double high){
    double mid, fm;
    mid = (low + high) / 2;
    fm = 2 * pow(mid, 3) - 4 * pow(mid, 2) + 3 * mid - 6;    //待求函数
    //printf("%f--%f   -->  %f\n", low, high, mid);   //二分过程
    if (fm == 0 || (high - low) < 1e-5)//两种情况停止,一是fm刚好等于0(应该不可能),二是精度小于1e-5时,直接返回mid为近似解
        return mid;
    else if (fm < 0)
        return fun(mid, high);
    else if (fm > 0)
        return fun(low, mid);
}
int main(){
    printf("%.2f", fun(-10, 10));
    return 0;
}

循环

#include <stdio.h>
#include <math.h>
double f(double x){
    return  2*x*x*x-4*x*x+3*x-6.0; //函数
}

int main(){
    double a = 1000, b = -1000, e = 1e-5;  //a,b二分范围,e精度
    // printf("input a b e: ");
    // scanf("%lf%lf%lf", &a, &b, &e);
    e = fabs(e);
    if (fabs(f(a)) <= e)
        printf("solution: %lg\n", a);
    else if (fabs(f(b)) <= e)
        printf("solution: %lg\n", b);
    else if (f(a)*f(b) > 0)
        printf("f(%lg)*f(%lg) > 0 ! need <= 0 !\n", a, b);
    else{
        while (fabs(b-a) > e) {
            double c = (a+b)/2.0;
            if (f(a)* f ( c ) < 0) b = c;
            else a = c;
        }
        printf("solution: %lg\n", (a+b)/2.0);
    }
    return 0;
}

solution: 2

16 菱形图案

#include <stdio.h>

int main(){
    int m = 3,n = 1;  //控制内循环次数变量
    for(int i = 0; i<7; i++){
        for(int j = 0; j< m;j++)
            printf(" ");
        i<3?m--:m++;
        for(int j = 0; j < n;j++)
            printf("*");
        n = i<3?n+2:n-2; 
        putchar('\n');
    }
    return 0;
}

17 比赛组合

#include <stdio.h>
//判断有问题
int main(){
    char a[3] = {'A','B','C'};
    char b[3] = {'X','Y','Z'};
    for(int i = 0;i<3;i++)
        for(int j = 0; j<3; j++)
            if((a[i]!='A'&&b[j]!='X')||(a[i]!='C'&&(b[j]!='X'||b[j]!='Z'))) printf("%c--%c\n",a[i],b[j]);
    return 0;
}
#include <stdio.h>
//推荐,清晰明了
int judge(char a,char b){
    if(a=='A'&&b=='X') return 0;
    if(a=='C'&&(b=='X'||b=='Z')) return 0;
    return 1;
}

int main(){
    char a[3] = {'A','B','C'};
    char b[3] = {'X','Y','Z'};
    for(int i = 0;i<3;i++)
        for(int j = 0; j<3; j++)
            if( judge(a[i],b[j]) ) printf("%c--%c\n",a[i],b[j]);
    return 0;
}

A–Y
A–Z
B–X
B–Y
B–Z
C–Y

第六章 数组

1 筛选法求素数

//直接判断n是否为素数,排除法
int judge(int n){
    for(int i = 2; i<= sqrt(n); i++)
        if(n%i==0) return 0;
    return 1;
}
#include <stdio.h>
#include <math.h>
#define M 100
//筛选法
int main(){
    int arr[M],i,count=0;
    for(i=0;i<M;i++) arr[i] = i+1; //[1,100] 范围内存入数组,等待筛选
    arr[0] = 0;  //1 不是素数
    for(i=0; i<sqrt(M); i++){    //到根号下M就可以,极大提高效率
        if(arr[i]==0) continue;  //若是标记的0直接跳过本次循环,提高效率
        count++;
        for(int j = i+1; j<M; j++){
            if(arr[j]==0) continue;  
            if(arr[j]%arr[i]==0) arr[j] = 0;  //其后若是其倍数,筛选标记为0.
        }
    }
    printf("%d\n",count);  //测试循环执行次数
    //数据展示,可判断为如是0,不输出
    for(i = 0;i<M;i++){
        if(i%10==0) putchar('\n');
        printf("%d\t",arr[i]);
    }
    return 0;
    
}

25

2 3 0 5 0 7 0 0 0 11
0 13 0 0 0 17 0 19 0 0
0 23 0 0 0 0 0 29 0 31
0 0 0 0 0 37 0 0 0 41
0 43 0 0 0 47 0 0 0 0
0 53 0 0 0 0 0 59 0 61
0 0 0 0 0 67 0 0 0 71
0 73 0 0 0 0 0 79 0 0
0 83 0 0 0 0 0 89 0 0
0 0 0 0 0 97 0 0

W h a t d o y o u w a n t m e t o d o What do you want me to do Whatdoyouwantmetodo

4 //换为根号下的N,只执行4次

0 2 3 0 5 0 7 0 0 0
11 0 13 0 0 0 17 0 19 0
0 0 23 0 0 0 0 0 29 0
31 0 0 0 0 0 37 0 0 0
41 0 43 0 0 0 47 0 0 0
0 0 53 0 0 0 0 0 59 0
61 0 0 0 0 0 67 0 0 0
71 0 73 0 0 0 0 0 79 0
0 0 83 0 0 0 0 0 89 0
0 0 0 0 0 0 97 0 0 0

2 **选择排序

#include <stdio.h>
//将数组p中的下标分别为a,b的两个数交换
void swap(int a,int b,int p[]){
    int temp = p[a];
    p[a] = p[b];
    p[b] = temp;
}

int main(){
    int a[10] = {67,43,7,97,59,73,37,61,11,31},min,i;  //min 最小值所在下标,而不是最小值
    for(i = 0; i<10; i++){
        min = i;  //假设当前为最小值,将下标赋予
        for(int j = i+1; j < 10; j++)
            if(a[j]<a[min]) min = j;  
        if(min!=i) swap(min,i,a);
    }
    for(i = 0; i<10; i++) printf("%d\t",a[i]);
    return 0;
    
}

7 11 31 37 43 59 61 67 73 97

3 矩阵对角线之和

#include <stdio.h>
int main(){
    int arr[3][3] = {1,2,3,4,5,6,7,8,9},i,j,sum=0;
    for(i = 0; i<3; i++)
        for(j = 0;j<3; j++)
            if(i==j||i+j==2) sum+=arr[i][j];  
    printf("%d",sum);
    return 0;
}

25

4 按序插入

???为什么第二个b值改变了?

编译系统不同

Thread model: win32 gcc version 9.2.0 (MinGW.org GCC Build-2) 出现问题,

编译器名: TDM-GCC 4.9.2 64-bit Release 运行正常

#include <stdio.h>
int main(){
    int a[11] = {7, 11, 31, 37, 43, 59, 61, 67, 73, 97}, b = 17, i, j;
    for (i = 0; i < 11; i++)
        if (a[i] > 17) break;
    printf("%d\n", b);
    for (j = 10; j >= i; j--)
        a[j + 1] = a[j]; //后移
    printf("%d\n", b);
    return 0;
}

逻辑应该没问题

#include <stdio.h>
int main(){
    int a[11] = {7   ,   11   ,   31   ,   37   ,   43    ,  59   ,   61   ,   67   ,   73   ,  97},b=17,i,j;
    for(i = 0; i<11;i++)
        if(a[i]>b) break;  //获取所应插入的位置下标i
    for(j = 10;j>=i;j--) a[j+1] = a[j];  //后移
    a[i] = b;  //插入
    for(i = 0; i<11; i++) printf("%d\t",a[i]);  
    return 0;
}

7 11 17 31 37 43 59 61 67 73 97

5 逆序数组

#include <stdio.h>
#define L 10
//将数组p中的下标分别为a,b的两个数交换
void swap(int a,int b,int p[]){
    int temp = p[a];
    p[a] = p[b];
    p[b] = temp;
}

int main(){
    int a[L] = {7   ,   11   ,   31   ,   37   ,   43    ,  59   ,   61   ,   67   ,   73   ,  97},i;
    for(i=0; i<L/2; i++)
        swap(i,L-i-1,a);
    for(i = 0; i<L; i++) printf("%d\t",a[i]);  
    return 0;
}

6 杨辉三角

递归

#include <stdio.h>
//返回i行j列的值
int fun(int i,int j){
    if(j==1||i==j) return 1;  //如果在第一列或者行列相同,返回1
    return fun(i-1,j)+fun(i-1,j-1);   //本列上一行 + 上一行前一列
}
//输出前n行
void Triangle(int n){
    if(n) {
        Triangle(n-1);   //在其之前,输出前一行
        for(int i=1;i<=n;i++)
            printf("%-5d",fun(n,i));
        putchar(10);
    }
}
int main(){
    Triangle(10);
    return 0;
}

循环

#include <stdio.h>
#define M 10  //输出前10行
int main(){
    int a[M]={1},b[M],i,j;
    printf("%d\n",a[0]);
    for(i = 2;i<=M;i++){  //第 i 行,根据行数控制内循环次数
        if(i%2)   //a,b循环交替
            for(j = 0; j<i;j++) 
            	printf("%d\t",j==0?(a[j]=1):(a[j]=b[j]+b[j-1]));  //首位必然为1,赋值打印同时进行
        else
        	for(j = 0; j<i;j++) 
            	printf("%d\t",j==0?(b[j]=1):(b[j]=a[j]+a[j-1])); 
        a[j] = 0; b[j] = 0;  //最后位补0,避免无法预料的随机值.  或者最后位的单独补充
        putchar('\n');
    }
    return 0;
}

1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1

7 “魔方矩阵”

https://baike.baidu.com/item/%E9%AD%94%E6%96%B9%E7%9F%A9%E9%98%B5/6532651?fr=aladdin

#include <stdio.h>
// 交换
void Exchange(int **pj, int tr, int tc, int n) {
    n++;
    if (1 <= tr && tr <= n / 2 && 1 <= tc && tc <= n) {
        pj[tr][tc] += pj[n - tr][n - tc];
        pj[n - tr][n - tc] = pj[tr][tc] - pj[n - tr][n - tc];
        pj[tr][tc] -= pj[n - tr][n - tc];
    }
}
 
int main(){
    int n, i = 0, j = 0, **pj;
    int tr, tc;
    printf("输入魔方矩阵的阶层:");
        scanf("%d",&n);
    // 初始化二维数组
    pj = (int**)malloc(sizeof(int **) * (n + 1));
    for (i = 0; i < (n + 1); i++)
        pj[i] = (int*)malloc(sizeof(int *) *  (n + 1));
    // n为奇数时
    if (n % 2 == 1) {
        // 1.将1放至第一行中间
        i = 1; j = n / 2 + 1;
        pj[1][n / 2 + 1] = 1;
        // 2.沿右上45°,依次放置剩下的数
        for (int k = 2; k <= n * n; k++) {
            // 行数上移,列数右移,即右上45°移动
            tr = i - 1; tc = j + 1; 
            // 条件一:若超出,则回绕
            if (tr < 1) tr = n;
            if (tc > n) tc = 1;
            // 条件二:若有数据,则放在上一个数字之下
            if (0 < pj[tr][tc] && pj[tr][tc] <= n * n) {
                tr = i + 1; tc = j;
                if (tr < 0) tr = n;
            }
            pj[tr][tc] = k;
            i = tr; j = tc;
        }
    }
    // n为4的倍数时
    else if (n % 4 == 0) {
        i = 1; j = 1; 
        // 1.先将数据从上到下,从左到右填入
        for (int k = 1; k <= n * n; k++) {
            pj[i][j++] = k;
            if (j > n) { j = 1; i++; }
        }
        // 2.将方阵的所有4*4子方阵中的两对角线上的数
        // 关于大方阵中心作中心对称交换
        i = 1; j = 1;
        for (size_t r = 0; r < n / 4 + 1; r++) {
            for (size_t c = 0; c < n / 4 + !(r % 2); c++) {
                tr = 2 * r + i;
                tc = 4 * c + r % 2 * 2 + j;
                Exchange(pj, tr, tc, n);
                Exchange(pj, tr - 1, tc, n);
                Exchange(pj, tr, tc - 1, n);
                Exchange(pj, tr - 1, tc - 1, n);
            }
        }
    }
    for (i = 1; i <= n; i++) {
        for (j = 1; j <= n; j++)
            printf("%d\t", pj[i][j]);
        printf("\n");
    }
}

8 鞍点判断

#include <stdio.h>
#define N 3  
int main(){
    int a[N][N],i,j,k,exist=0;  //exist 判别是否存在鞍点
    //创建二维数组
    for(i = 0;i<N; i++)
        for(j = 0; j < N; j++)
            a[i][j] = i*3+j+1;
    for(i = 0;i<N; i++){
        //找到此行最大值在第几列 max
        int max = 0,flag = 1;  //flag 判断是否为鞍点
        for(j = 1; j < N; j++)
            if(a[i][j]>a[i][max]) max = j;
        //验证i行最大值 是否在该列最小
        for(k=0; k<N; k++)
            if(a[k][max]<a[i][max]) {flag = 0;break;}  //如有比其小的,判断标记0,跳出
        if(flag) {printf("此二维数组的第%d行第%d列的%d为其中一个鞍点\n",i+1,max+1,a[i][max]);exist=1;}
        if(i==N-1&&!exist) printf("此二维数组没有鞍点!");
    }
}

9 **折半查找法

#include <stdio.h>
#include <time.h>
#define M 15
//将数组p中的下标分别为a,b的两个数交换
void swap(int a,int b,int p[]){
    int temp = p[a];
    p[a] = p[b];
    p[b] = temp;
}
//对数组a排序升序
void sortArr(int *a,int l){
    int i,j;
    for(i=0; i<l-1;i++)
        for(j=0;j<l-i-1;j++)
            if(a[j]>a[j+1]) swap(j,j+1,a);
}
//随机数组
void getArr(int *a,int l){
    int i;
    srand(time(NULL));  //以当前系统时间作为种子
    while (i < l) a[i++] = rand()%(2*l+1);  //限制范围[0,2*M]
    sortArr(a,l);
    for(i=0;i<M;i++) printf("%d ",a[i]);  //输出数组
}

int main(){	
    int low=0,high = M-1,mid,s,flag=1,a[M];  //s 待查找的数,flag 判断是否找寻到
    getArr(a,M);
    printf("\n请输入要查找的数:"); 
    scanf("%d",&s);
    while(low<=high){
        mid = (low + high)/2;
        if(a[mid]<s)
            low = mid+1;
        else if(a[mid]>s) high = mid - 1;
        else {flag = 0;printf("在第%d个位置查到",mid+1);break;}
    }
    if(flag) printf("查无此数!");
    return 0;
}

10 统计字符

#include <stdio.h>
int main(){
    char str[100],*p;
    int z=0,Z=0,k=0,s=0,q=0;
    p = str;
    gets(str);
    do
        if((*p<=122&&*p>=97)) z++;
    	else if((*p>=65&&*p<=90)) Z++;
        else if(*p>=48&&*p<=57) s++;
        else if(*p==' ') k++;
        else q++;
    while(*p++);
    printf("小写字母有%d个",z);
    printf("大写字母有%d个",Z);
    printf("空格有%d个",k);    
    printf("数字有%d个",s);
    printf("其他字符有%d个",q);
    return 0;
}

11 平行四边形图案

#include <stdio.h>
int main(){
    int i,j;
    for(i = 0; i<5; i++){
        for(j = 0;j<i;j++) printf("  ");
        for(j = 0;j<5;j++) printf("* ");
        putchar('\n');
    }
    return 0;
}

12 密码译文

#include <stdio.h>
int main(){
    char a[100],b[100];
    int i,j;
    gets(a);
    for(i = 0; a[i]; i++)
        if(a[i]>='A'&&a[i]<='Z') b[i] = 'Z'-a[i]+'A';
        else if(a[i]>='a'&&a[i]<='z') b[i] = 'z'-a[i]+'a';
    b[i] = '\0';   //结束!!!超级重要!!!超级容易忘!!!
    puts(a);  //原文
    puts(b);  //译文
    return 0;
}

13 字符串连接

#include <stdio.h>
//将s2连接到s1后面, s2不改变
void strconcat(char *s1,char *s2){
    int i,j;
    for(i = 0;s1[i];i++);  //定位到 s1字符串 中的'\0' 位置
    for(j = 0;s2[j];i++,j++)
        s1[i] = s2[j];
    s1[i] = '\0';       //结束!!!超级重要!!!超级容易忘!!!
}
int main(){
    char a[100],b[100];
    gets(a);
    gets(b);
    strconcat(a,b);
    puts(a);
    return 0;
}

14 比较字符串

#include <stdio.h>
//比较字符串s1,s2 , 相等返回0, 正数s1大,反之.
int strcomp(char *s1,char *s2){
    for(int i=0;s1[i] || s2[i];i++)
        if(s1[i]!=s2[i]) return s1[i]-s2[i];
    return 0;
}

int main(){
    char a[100],b[100];
    gets(a);
    gets(b);
    printf("%d",strcomp(a,b));
    return 0;
}

15 复制字符串函数

#include <stdio.h>
//s2字符串 复制 到s1中
void strcopy(char *s1,char *s2){
    int i,j;
    for(i=0;s2[i];i++)
        s1[i] = s2[i];
    s1[i] = '\0';        //结束!!!超级重要!!!超级容易忘!!!
}

int main(){
    char s1[100],s2[100];
    gets(s2);
    strcopy(s1,s2);
    puts(s1);
}

第七章 函数

1 **最大公约数与最小公倍数

#include <stdio.h>
//最大公约数 m>n
int gcd(int m,int n){ 
    if (n==0)   //若 m%n 能被整除, m则为最大公约.  两个整数的最大公约数等于其中较小的数和两数的相除的余数的最大公约数
         return m;
    return gcd(n,m%n); 
}
//最小公倍数 m>n
int lcm(int m,int n){
    return m*n/gcd(m,n);
}
int main(){
    int x,y;
    scanf("%d%d",&x,&y);
    if(x<y) {  //交换值
        x+=y;
        y=x-y;
        x-=y;
    }
    printf("最大公约数:%d\n",gcd(x,y));
    printf("最小公倍数:%d\n",lcm(x,y));
    return 0;
}

2 一元二次方程的根

#include <stdio.h>
#include <math.h>


//求 a*x*x + b*x + x == 0  的根
int main(){
    
    return 0;
}

3 判断素数

#include <stdio.h>
int judge(int n){
    for(int i = 2;i<n/2;i++)
        if(n%i==0) return 0;
    return 1;
}
int main(){
    int a;
    scanf("%d",&a);
    if(judge(a)) printf("是素数!");
    else printf("不是素数!");
    return 0;
}

4 二维数组行列互换

#include <stdio.h>
#include <time.h>
#define M 4
#define N 2
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);

//随机数组 a数组首地址,m一维长度,n二维长度
void getArr(int (*a)[N],int m, int n){
    int i,j;
    srand(time(NULL));  //以当前系统时间作为种子
    for(i = 0; i < m;i++){
        for(j=0; j<n; j++)
            printf("%d ",a[i][j] = rand()%(2*m*n+1));  //限制范围[0,2*m*n]
    	putchar('\n');
    }
}

void exchange(int (*a)[N],int (*b)[M],int m,int n){
    int i,j;
    for(i = 0; i < n;i++){
        for(j=0; j<m; j++) 
            printf("%d ",b[i][j]=a[j][i]);  
    	putchar('\n');
    }
}

int main(){
    int a[M][N],b[N][M];
    getArr(a,M,N);
    exchange(a,b,M,N);
    return 0;
}

5 反序字符数组

#include <stdio.h>
//将数组p中的下标分别为a,b的两个数交换
void swap(int a,int b,char p[]){
    char temp = p[a];
    p[a] = p[b];
    p[b] = temp;
}
//反序字符串str
void reverse(char *str){
    int i,j=0;
    while(str[j+1]) j++; //定位下标到最后一个字符
    for(i=0;i<j;i++,j--)
        swap(i,j,str);
}
int main(){
    char s[100];
    gets(s);
    reverse(s);
    puts(s);
    return 0;
}

6 字符串连接

#include <stdio.h>
//将s2连接到s1后面, s2不改变
void strconcat(char *s1,char *s2){
    int i,j;
    for(i = 0;s1[i];i++);  //定位到 s1字符串 中的'\0' 位置
    for(j = 0;s2[j];i++,j++)
        s1[i] = s2[j];
    s1[i] = '\0';       //结束!!!超级重要!!!超级容易忘!!!
}
int main(){
    char a[100],b[100];
    gets(a);
    gets(b);
    strconcat(a,b);
    puts(a);
    return 0;
}

7 元音字母复制

#include <stdio.h>
//判断是否元音
int judge(char a){
    switch(a){
        case 'a':
        case 'A':
        case 'e':
        case 'E':
        case 'i':
        case 'I':    
        case 'o':    
        case 'O':    
        case 'u':    
        case 'U': return 1;   
        default: return 0;      
    }
}
void str_vowel_copy(char *s1,char *s2){
    int i,j=0;
    for(i = 0;s2[i];i++)
        if(judge(s2[i])) s1[j++] = s2[i];
}

int main(){
    char s1[100],s2[100];
    gets(s1);
    str_vowel_copy(s2,s1);
    puts(s2);
    return 0;
}

8 **间隔数字

#include <stdio.h>
//递归打印
void interval_print(int n){
    if (n){
        interval_print(n / 10);  //与下一行 交换位置则反序打印
        printf("%d ", n % 10);
    }
}

int main(){
    int num;
    scanf("%d",&num);
    interval_print(num);
    return 0;
}

9 统计字符

想返回多个元素? 直接传入一个数组, 存入数组不返回.

#include <stdio.h>
void statistic(char *a,int *b){
    do
        if((*a<=122&&*a>=97)||(*a>=65&&*a<=90)) b[0]++;
        else if(*a>=48&&*a<=57) b[1]++;
        else if(*a==' ') b[2]++;
        else b[3]++;
    while(*a++);   
}

int main(){
    char str[100];
    int b[4]={0};
    gets(str);
    statistic(str,b);
    printf("字母有%d个\n",b[0]);
    printf("数字有%d个\n",b[1]);    
    printf("空格有%d个\n",b[2]);
    printf("其他字符有%d个\n",b[3]);
    return 0;
}

10 **找最长单词

#include <stdio.h>
//自左向右 输出第一个最长的单词
void findlongest(char *str){
    char longest_word[100];
    int long_,longest=0,i=0,j,k;
    while(str[i]){   
    	if(str[i]==' ') {i++;continue;}  //跳过所有空格,防止单词间不止一个空格
        long_ = 0;  //每次循环重置长度 
        for(j = i;str[j]!=' '&&str[j]; j++) long_++;  //两种情况:末位为空格或者'\0',表示本单词结束
        //printf("%d\t",long_);  //每个单词的长度
        if(longest<long_) {
            longest = long_;
            for(j = i,k=0;str[j]!=' ';j++) longest_word[k++] = str[j];  //存入目前最长的单词
            longest_word[k] = '\0';  //截止结束!!!
        }
        i+=long_; //跳到下一个单词
    }
    puts(longest_word);
}
int main(){
    char str[100];
    gets(str);
    findlongest(str);
    return 0;
}

11 **冒泡排序----排序总结

#include <stdio.h>
#include <time.h>
#define M 10  //数组长度
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//打印数组
void print_arr(int *arr,int l){
    putchar('\n');
    for(int i = 0;i<l; i++) printf("%4d",arr[i]);
    putchar('\n');
}
//将数组p中的下标分别为a,b的两个数交换
void swap(int a,int b,int p[]){
    int temp = p[a];
    p[a] = p[b];
    p[b] = temp;
}
//随机数组 a数组首地址,l数组长度
void getArr(int *a,int l){
    int i=0;
    srand(time(NULL));  //以当前系统时间作为种子
    printf("你生成的数组为:");
    while (i < l) printf("%4d",a[i++] = rand()%(2*l+1));  //限制范围[0,2*l]
}
//冒泡排序法升序
void bubbling(int *arr,int l){
    for(int i=0;i<l-1;i++){
        int var = 1; 
        for(int j=0;j<l-i-1;j++)
            if(arr[j]>arr[j+1]) {swap(j,j+1,arr); var = 0;}
        //print_arr(arr,l);  查看排序过程
        if(var) break;  //本回合未产生排序,即已排序完成,跳出循环,提高效率(非必须)
    }
}
//选择排序法升序,最多产生 l(数组长度) 次交换
void elect_sort(int *arr,int l){
    int i,j,k;
    for(i=0;i<l;i++){
        k=i;  //假设当前下标为最小值
        for(j=i+1;j<l;j++)  //找最小值下标
            if(arr[j]<arr[k]) k = j;
        if(k!=i) swap(i,k,arr);  //将最小值交换到i的位置
    }
}
//选择排序法1,交换次数较多,但更简洁
void elect_sort_1(int *arr,int l){
    for(int i=0; i<l; i++)
    	for(int j=i+1; j<l; j++)
            if(arr[i]>arr[j]) swap(i,j,arr);
}
//插入排序法升序
void insertt_sort(int *r, int l){
    int i, j, k;
    for (i = 1; i < l; i++){
        if (r[i] < r[i - 1]){
            k = r[i];  //存入当前待插入的值,否则定位后移 会覆盖
            for (j = i - 1; r[j] > k && j>=0; j--) //后移,寻找合适的插入位置
                r[j + 1] = r[j];  
            r[j + 1] = k;  //插入
        }
    }
}

int main(){
    int a[M];
    getArr(a,M);
    // elect_sort_1(a,M);
    // bubbling(a,M);
    insertt_sort(a,M);
    print_arr(a,M);
    return 0;
}

冒泡排序过程例举 :

29 22 15 27 26 18 31 11 24 3 40 14 23 22 31 9 5 26 25 17
22 15 27 26 18 29 11 24 3 31 14 23 22 31 9 5 26 25 17 40
15 22 26 18 27 11 24 3 29 14 23 22 31 9 5 26 25 17 31 40
15 22 18 26 11 24 3 27 14 23 22 29 9 5 26 25 17 31 31 40
15 18 22 11 24 3 26 14 23 22 27 9 5 26 25 17 29 31 31 40
15 18 11 22 3 24 14 23 22 26 9 5 26 25 17 27 29 31 31 40
15 11 18 3 22 14 23 22 24 9 5 26 25 17 26 27 29 31 31 40
11 15 3 18 14 22 22 23 9 5 24 25 17 26 26 27 29 31 31 40
11 3 15 14 18 22 22 9 5 23 24 17 25 26 26 27 29 31 31 40
3 11 14 15 18 22 9 5 22 23 17 24 25 26 26 27 29 31 31 40
3 11 14 15 18 9 5 22 22 17 23 24 25 26 26 27 29 31 31 40
3 11 14 15 9 5 18 22 17 22 23 24 25 26 26 27 29 31 31 40
3 11 14 9 5 15 18 17 22 22 23 24 25 26 26 27 29 31 31 40
3 11 9 5 14 15 17 18 22 22 23 24 25 26 26 27 29 31 31 40
3 9 5 11 14 15 17 18 22 22 23 24 25 26 26 27 29 31 31 40
3 5 9 11 14 15 17 18 22 22 23 24 25 26 26 27 29 31 31 40
3 5 9 11 14 15 17 18 22 22 23 24 25 26 26 27 29 31 31 40
3 5 9 11 14 15 17 18 22 22 23 24 25 26 26 27 29 31 31 40
3 5 9 11 14 15 17 18 22 22 23 24 25 26 26 27 29 31 31 40
3 5 9 11 14 15 17 18 22 22 23 24 25 26 26 27 29 31 31 40

3 5 9 11 14 15 17 18 22 22 23 24 25 26 26 27 29 31 31 40

12 牛顿迭代法求根

13 递归求N阶勒让德多项式

#include <stdio.h>
int Legendre(int n,int x){
    if(n==0) return 1;
    if(n==1) return x;
    if(n>=1) 
        return (2*n-1)*x-Legendre(n-1,x)-(n-1)*Legendre(n-2,x)/n;
}

int main(){
    int n,x;
    scanf("%d%d",&n,&x);
    printf("%d",Legendre(n,x));
    return 0;
}

3 3
7

14 学生成绩–二维数组计算

#include <stdio.h>
#include <time.h>
#define M 10  //10个学生
#define N 5  // 5门功课
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//1.随机数组 a数组首地址,m一维长度,n二维长度
void getArr(int (*a)[N],int m, int n){
    int i,j;  //
    srand(time(NULL));  //以当前系统时间作为种子
    for(i = 0; i < m;i++){
        double sum=0;
        printf("%d号学生成绩分别为: ",i+1);
        for(j=0; j<n; j++){
            printf("%4d",a[i][j] = rand()%(100+1));  //限制范围[0,100]
            sum+=a[i][j];
        }
        printf("   平均分为:%6.2f\n",sum/n);  
    }
}
//2.课程(列)平均分
void course_average(int (*a)[N],int m,int n){
    for(int i = 0;i<n; i++) {
        double sum =0 ;
        for(int j=0;j<m;j++)
            sum+=a[j][i];
        printf("第%d门功课平均分为:%6.2f\n",i+1,sum/m);
    }   
}
//3.寻找二维数组最大值(最高分)
void find_max_score(int (*a)[N],int m,int n){
    int i,j,max = 0,q,p;
    for(i = 0; i < m;i++)
        for(j=0; j<n; j++)
            if(a[i][j]>max) {max = a[i][j];q=i;p=j;}
    printf("%d号学生的第%d号课分数最高--%d分\n",q+1,p+1,max);
}
//4.平均分方差
double variance(int (*a)[N],int m,int n){
 	int i,j;
    double m1=0,m2=0;
    for(i = 0; i < m;i++){
        double ave = 0;
        for(j=0; j<n; j++) ave+= a[i][j];
    	ave/=n;  //平均分
        m1+=ave*ave;
        m2+=ave;
    }
    return 1/n*m1-(m2/n)*(m2/n);
}

int main(){
    int achi[M][N];
    getArr(achi,M,N);
    course_average(achi,M,N);
    find_max_score(achi,M,N);
    printf("平均分方差: %f",variance(achi,M,N));
    return 0;
}

1号学生成绩分别为: 89 53 10 21 11 平均分为: 36.80
2号学生成绩分别为: 31 57 97 57 100 平均分为: 68.40
3号学生成绩分别为: 76 83 28 7 45 平均分为: 47.80
4号学生成绩分别为: 26 38 12 50 38 平均分为: 32.80
5号学生成绩分别为: 64 52 19 27 88 平均分为: 50.00
6号学生成绩分别为: 36 30 52 8 81 平均分为: 41.40
7号学生成绩分别为: 97 34 78 49 88 平均分为: 69.20
8号学生成绩分别为: 38 77 27 70 18 平均分为: 46.00
9号学生成绩分别为: 80 18 71 52 53 平均分为: 54.80
10号学生成绩分别为: 71 32 24 61 7 平均分为: 39.00
第1门功课平均分为: 60.80
第2门功课平均分为: 47.40
第3门功课平均分为: 41.80
第4门功课平均分为: 40.20
第5门功课平均分为: 52.90
2号学生的第5号课分数最高–100分
平均分方差: -9455.617600

15 职工–issue:输入问题 had found

#include <stdio.h>
#define L 3

void input(int *num,char *name[],int len){ 
	int i; 
    for(i=0;i<len;i++){
        printf("请输入第%d员工的姓名和职工号:",i+1);
        scanf("%s%d",name[i],num+i);
        printf("%s---%d\n",name[i],num[i]); 
    }  
}
//打印
void print(int *num,char **name,int len){
	int i; 
    for (i = 0; i < len; i++)
        printf("%s---%d\n",name[i],num[i]); 
}

//交换
void swap(int a,int b,int p[],char **pp){
    int temp = p[a];
    p[a] = p[b];
    p[b] = temp;
    char *name = pp[a];
    pp[a] = pp[b];
    pp[b] = name;
}

void sort(int *num,char *name[],int len){
	int i,j; 
    for(i=0; i<len; i++)
    	for(j=i+1; j<len; j++)
            if(num[i]>num[j]) 
                swap(i,j,num,name);   
}

//查询下标
int findname(int *number,int num,int len){
    int mid,low,high;
    low = 0;
    high = len-1;
    while(low<high){
        mid = (low+high)/2; 
        if(number[mid]>num) high = mid-1;
        else if(number[mid]<num) low = mid+1;
        else return mid;
    }
    return -1;
}

int main(){
    int number[L],num,where;
    char *name[L];
    input(number,name,L);
    
    //sort(number,name,L);
    //print(number,name,L);

    // printf("请输入你想查询的标号:");
    // scanf("%d",&num);
    // where = findname(number,num,L);
    // if(where==-1) printf("查无此人!");
    // else puts(name[where]);
    return 0;
}
#include <stdio.h>
#include <time.h>
#define L 10
#define N 4  //定义二维数组的第二维
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//随机数组 a数组首地址,m一维长度,n二维长度
void getArr(char (*a)[N],int m, int n){
    int i,j;
    srand(time(NULL));  //以当前系统时间作为种子
    for(i = 0; i < m;i++){
        for(j=0; j<n; j++)
            printf("%c",a[i][j] = rand()%26+97);  //限制范围[97,122]
    	putchar('\n');
    }
}
void getNum(int *a,int l){
    int i=0;
    srand(time(NULL));  //以当前系统时间作为种子
    printf("你生成的数组为:");
    while (i < l) printf("%4d",a[i++] = rand()%900+100);  //限制范围 三位数
}
void input(int *num,char (*name)[N],int len){ 
	int i; 
    for(i=0;i<len;i++){
        printf("请输入第%d员工的姓名和职工号:",i+1);
        scanf("%s%d",name[i],num+i);
        printf("%s---%d\n",name[i],num[i]); 
    }  
}
//打印
void print(int *num,char (*name)[N],int len){
	int i; 
    for (i = 0; i < len; i++)
        printf("%s---%d\n",name[i],num[i]); 
}

//交换
void swap(int a,int b,int p[],char (*pp)[N]){
    int temp = p[a];
    p[a] = p[b];
    p[b] = temp;
    char (*name)[N] = pp[a];
    pp[a] = pp[b];
    pp[b] = name;
}

void sort(int *num,char (*name)[N],int len){
	int i,j; 
    for(i=0; i<len; i++)
    	for(j=i+1; j<len; j++)
            if(num[i]>num[j]) 
                swap(i,j,num,name);   
}

//查询下标
int findname(int *number,int num,int len){
    int mid,low,high;
    low = 0;
    high = len-1;
    while(low<high){
        mid = (low+high)/2; 
        if(number[mid]>num) high = mid-1;
        else if(number[mid]<num) low = mid+1;
        else return mid;
    }
    return -1;
}

int main(){
    int number[L],num,where;
    // char *name[L];
    char name[L][4];
    getArr(name,L,4);
    getNum(number,L);
    // input(number,name,L);   //输入
    sort(number,name,L);
    print(number,name,L);

    // printf("请输入你想查询的标号:");
    // scanf("%d",&num);
    // where = findname(number,num,L);
    // if(where==-1) printf("查无此人!");
    // else puts(name[where]);
    return 0;
}

16 十六进制转十进制

#include <stdio.h>

//十六进制转10进制
int sixToten(char *six){
    int i,ten=0,k=1;
    for(i=0; six[i+1];i++);  //下标指向末位
    for(;i>=0;i--,k*=16)
        ten+= k*(six[i]- (six[i]>'9'?87:'0'));
    return ten;
}
int main(){
    char six[20];
    gets(six);   //请输入小写字符的十六进制数
    printf("%d",sixToten(six));
    return 0;
}
#include <stdio.h>
//将16进制的字符转为所表示的数值
int charToint(char c){
    if(c>='a') return c-87;
    else if(c>='A') return c-55;
    else return c-'0';
}
//十六进制转10进制
int sixToten(char *six){
    int i,ten=0,k=1;
    for(i=0; six[i+1];i++);  //下标指向末位
    for(;i>=0;i--,k*=16)
        ten+= k*charToint(six[i]);
    return ten;
}
//检验是否为十六进制中的字符
int isHex(char c){
    if(c>='0'&&c<='9') return 1;
    else if(c>='A'&&c<='F') return 1;
    else if(c>='a'&&c<='f') return 1;
    else return 0;
}

int main(){
    char six[20];
    while(1){
        gets(six);   //检验是否合法十六进制数
        int flag = 1;
        for(int i=0;six[i];i++) 
            if(!isHex(six[i])) {flag = 0;break;}
        if(flag) break;
        else printf("请输入十六进制数!请重新输入:");
    }
    printf("%d",sixToten(six));
    return 0;
}

17 整形数值转字符串

递归:

#include <stdio.h>
#include <stdlib.h>
//递归存入
void intTostr(int num,char *str){
    if(num){      
        intTostr(num/10,str-1);  //此时与下一句前后交换不影响结果.
        *str = num%10+'0';  //转字符加上'0' !!!!
    }
}

int main(){
    int num,n,len=1;  //len 确定位数
    scanf("%d",&num);
    n=num;
    while(n/=10) len++;
    char *str;
    str = (char *)malloc(len*sizeof(char)+1);  //根据位数开辟存储空间,+1 结束标识
    intTostr(num,str+len-1);  //传入最后一个地址
    str[len] = '\0';  // 结束标记
    puts(str);  
    return 0;
}

循环:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void intTostr(int num,int len,char *str){
    //div 最高位除数
    int i,div = pow(10,len-1)+0.5;  //+0.5 pow函数精度问题,double转int 失真
    for(i=0;i<len;i++,div/=10)
        str[i] = num/div%10+'0';        
    str[i] ='\0';
}

int main(){
    int num,n,len=1;  //len 确定位数
    scanf("%d",&num);
    n=num;
    while(n/=10) len++;
    char *str;
    str = (char *)malloc(len*sizeof(char)+1);  //根据位数开辟存储空间,+1 结束标记'\0'
    intTostr(num,len,str);
    puts(str);
    return 0;
}

18 求某天是该年的第几天

#include <stdio.h>
//判断闰年
int isleap(int year){
    if(year%400==0) return 1;
    else if(year%4==0&&year%100) return 1;
    else return 0;
}
//求某天是该年的第几天
int no_day(int year,int month,int day){
    int sum=0;
    switch(month-1){
        case 11:sum+=30;
        case 10:sum+=31;    
        case 9:sum+=30;    
        case 8:sum+=31;    
        case 7:sum+=31;    
        case 6:sum+=30;    
        case 5:sum+=31;    
        case 4:sum+=30;    
        case 3:sum+=31;
        case 2:sum+=28; if(isleap(year)) sum+=1;   
        case 1:sum+=31;
        case 0:sum+=day; break;
        default: printf("数据有误!");
    }  
    return sum;
}

int main(){
    int year,month,day;
    scanf("%d%d%d",&year,&month,&day);   //检验数据合法性(省)
    printf("这是%d年的第%d天,Time flies!",year,no_day(year,month,day));
    return 0;
}

第八章 指针

1 3个数排序

#include <stdio.h>
void max(int *p,int *q){
    
}

int main(){
    int a,b,c;
    int *max=&a,*mid=&b,*min=&c;
    if(*max<*mid) {}
    
    return 0;
}

2 排序字符串

#include <stdio.h>
#include <stdlib.h>
// #include <string.h>
#define M 3
//比较字符串s1,s2 , 相等返回0, 正数s1大,反之.
int strcomp(char *s1,char *s2){
    for(int i=0;s1[i] || s2[i];i++)
        if(s1[i]!=s2[i]) return s1[i]-s2[i];
    return 0;
}
//可直接赋值,或使用strcpy
void swap(int i,int j,char **str){
    char *temp = str[j];   
    str[j] = str[i];
    str[i] = temp;
}
//冒泡排序
void str_sort(char **str,int len){
    int i,j;
    for(i=0;i<len-1; i++)
        for(j=0;j<len-i-1;j++)
	        if(strcomp(str[j],str[j+1])>0) 
                swap(j,j+1,str);            
}

int main(){
    char *string[M];
    int i;
    for(i=0;i<M; i++)
        gets(string[i]=(char*)malloc(100*sizeof(char)));  //一定要先开辟空间,否则无法输入
    str_sort(string,M);
    printf("排序后:");
    for(i=0;i<M; i++)
        printf("%s  ",string[i]);
    return 0;
}

3 10个整数

#include <stdio.h>
#define M 10
void input(int *p,int len){
    while(len--)
        scanf("%d",p++);
}
//将数组p中的下标分别为a,b的两个数交换
void swap(int a,int b,int p[]){
    int temp = p[a];
    p[a] = p[b];
    p[b] = temp;
}
void exchange(int *p,int len){
 	int i,min,max;
    max=min=0;
    for(i=1;i<len;i++)
        if(p[i]>p[max]) max = i;
        else if(p[i]<p[min]) min=i;
    swap(0,min,p);
    swap(len-1,max,p);
}
void print(int *p,int len){
    while(len--)
        printf("%d ",*p++);
}
int main(){
    int a[M];
    input(a,M);
    exchange(a,M);
    print(a,M);
    return 0;
}

动态版

#include <stdio.h>
#include <stdlib.h>

void input(int *p,int len){
    printf("please input number:");
    while(len--)
        scanf("%d",p++);
}
//将数组p中的下标分别为a,b的两个数交换
void swap(int a,int b,int p[]){
    int temp = p[a];
    p[a] = p[b];
    p[b] = temp;
}
void exchange(int *p,int len){
 	int i,min,max;
    max=min=0;
    for(i=1;i<len;i++)
        if(p[i]>p[max]) max = i;
        else if(p[i]<p[min]) min=i;
    swap(0,min,p);
    swap(len-1,max,p);
}
void print(int *p,int len){
    while(len--)
        printf("%d ",*p++);
}
int main(){
    int *a,m;
    printf("please tell me that how many you want to input number? you say:");
    scanf("%d",&m);
    a = (int*)malloc(m*sizeof(int));
    input(a,m);
    exchange(a,m);
    print(a,m);
    return 0;
}

4 循环数组

#include <stdio.h>
#include <time.h>
#define M 10
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//随机数组 a数组首地址,l数组长度
void getArr(int *a,int l){
    int i=0;
    srand(time(NULL));  //以当前系统时间作为种子
    printf("你生成的数组为:");
    while (i < l) printf("%4d",a[i++] = rand()%(2*l+1));  //限制范围[0,2*l]
}
void loop(int *a,int len,int offset){
    int i,j,temp;
    for(i=0;i<offset;i++){
        temp = a[len-1];  //最后一位暂存
        for(j=len-1;j>0;j--)  //后移
            a[j] = a[j-1];
        a[0] = temp;  //将最后一个存在首位
    }
}
void print(int *a,int len){
    printf("偏移后的数组为:");
    while(len--)
        printf("%4d",*a++);
}
int main(){
    int a[M],m;
    getArr(a,M);
    printf("\n请输入偏移量:");
    scanf("%d",&m);
    loop(a,M,m);
    print(a,M);
    return 0;
}

5 报数游戏

#include <stdio.h>
int main()
{
	int i,j,a[100], n ,k=0,m=0,last; //所有人按号存入数组,总人数 ,报数 ,记录退出圈子的个数 , 最后一个人编号
    printf("宝儿 你们有多少人一起玩儿?:");
	scanf("%d",&n);
	for (i = 0; i < n; i++)  //顺序排号
	    printf("%d ",a[i]=i+1);
    i=0;
	while (1){
		if (a[i]) k++;   //除去为0的 报数
		if (k==3){   //报到3退出,
			a[i]=0;  //赋值为0,代表退出圈子;
			m++;      //记录退出人数
			k=0;      //重新将k赋值,下次重新报数到3
		}
		if (n-m==1){  //当剩最后一人的时候
			for (j = 0; j < n; j++)   //找到未退出的
				if (a[j]) last=a[j];				
			break;
		}
        //围成一圈,无限循环		
		if (i==n-1) i=0; 
         else i++;	
	}
	printf("\n恭喜!最后剩下了%d号玩家",last);
	return 0;
}

6 字符串长度

#include <stdio.h>
int length(char *str){
    int len=0;
    while(*str++) len++;
    return len;
}
int main(){
    char str[100];
    gets(str);
    printf("%d",length(str));
    return 0;
}

7 按需复制字符串

#include <stdio.h>
void strcopy(char *a,char *b,int m){
     b+=m-1;
     while(*b)
         *a++ = *b++;
}
int main(){
    char a[100],b[100];
    int m;
    printf("请输入字符串:");
    gets(b);
    printf("想从第几位开始复制呢 宝儿:");
    scanf("%d",&m);
    strcopy(a,b,m);
    puts(a);
    return 0;
}

8 统计字符

#include <stdio.h>
void statistic(char *a){
    int b[4] ={0};
    do
        if((*a<=122&&*a>=97)||(*a>=65&&*a<=90)) b[0]++;
        else if(*a>=48&&*a<=57) b[1]++;
        else if(*a==' ') b[2]++;
        else b[3]++;
    while(*a++);
    printf("字母有%d个\n",b[0]);
    printf("数字有%d个\n",b[1]);    
    printf("空格有%d个\n",b[2]);
    printf("其他字符有%d个\n",b[3]);
}
int main(){
    char str[100];
    int b[4]={0};
    gets(str);
    statistic(str);
    return 0;
}

9 3乘3矩阵 转置–未完

#include <stdio.h>
int main(){
    
    return 0;
}

10 5乘5矩阵存放–未完

#include <stdio.h>
#include <time.h>
#define N 5  //定义二维数组的第二维
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//随机数组 a数组首地址,m一维长度,n二维长度
void getArr(int (*a)[N],int m, int n){
    int i,j;
    srand(time(NULL));  //以当前系统时间作为种子
    for(i = 0; i < m;i++){
        for(j=0; j<n; j++)
            printf("%d ",a[i][j] = rand()%(2*m*n+1));  //限制范围[0,2*m*n]
    	putchar('\n');
    }
}
//二维数组交换
void swap(int i,int j,int m,int n,int (*arr)[N]){
    int temp = arr[i][j];   
    arr[i][j] = arr[m][n];
    arr[m][n] = temp;
}
//找到二维数组中最大值的下标,存入数组max中
void findmax(int (*a)[N],int len,int *max){
    for(i = 0; i < len;i++)
        for(j=0; j<len; j++)
            if(a[max[0]][max[1]]<a[i][j]) {
                max[0] = i;
                max[1] = j;
            }
}
//找最小的4个值的坐标
void findmin(int (*a)[N],int len,int (*min)[2]){
    for(i = 0; i < len;i++)
        for(j=0; j<len; j++)
            
}
void dosth(int (*a)[N],int m, int n){
    int max[2]={0},min[4][2]={0};  
    findmax(a,int m,max);
    swap(2,2,max[0],max[1],a);  //交换到中间
    findmin(a,int m,min);

}

int main(){
    int arr[N][N];
    getArr(arr,N,N);
    dosth(arr,N,N);
    return 0;
}

11 字符串排序–未完

#include <stdio.h>
#include <string.h>
#include <time.h>
#define N 4  //定义二维数组的第二维
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//随机数组 a数组首地址,m一维长度,n二维长度
void getArr(char (*a)[N],int m, int n){
    int i,j;
    srand(time(NULL));  //以当前系统时间作为种子
    for(i = 0; i < m;i++){
        for(j=0; j<n; j++)
            printf("%c",a[i][j] = rand()%26+97);  //限制范围[97,122]
    	putchar('\t');
    }
}

//使用strcpy
void swap(int i,int j,char (*str)[N]){
    char temp[N];
    strcpy(temp,str[i]);
    strcpy(str[i],str[j]);
    strcpy(str[j],temp);
}
//冒泡排序
void str_sort(char (*str)[N],int m){
    int i,j;
    for(i=0;i<m-1; i++)
        for(j=0;j<m-i-1;j++)
	        if(strcmp(str[j],str[j+1])>0) 
                swap(j,j+1,str);            
}

int main(){
    char string[10][N];
    getArr(string,10,N);
    str_sort(string,10);
    printf("排序后:");
    for(i=0;i<10; i++)
        printf("%s  ",string[i]);
    return 0;
}
#include <stdio.h>
#include <math.h>
int fun(double low, double high);

int main()
{
  printf("%.2f", fun(-10, 10));
  return 0;
}

int fun(double low, double high)
{
  double mid, fl, fh, fm;
  mid = (low + high) / 2;
  fm = 2 * pow(mid, 3) + 4 * (mid, 2) + 3 * mid - 6;
  if ((high-low)>1e-5)
  {   
    fl = 2 * pow(low, 3) + 4 * (low, 2) + 3 * low - 6;
    fh = 2 * pow(high, 3) + 4 * (high, 2) + 3 * high - 6;
    if (fm < 0)
      low = mid;
    else if (fm > 0)
      high = mid;
    else
      return fm;
    fun(low, high);
  }
  return fm;
}

17 比较字符串

#include <stdio.h>
//比较字符串s1,s2 , 相等返回0, 正数s1大,反之.
int strcomp(char *s1,char *s2){
    while(*s1||*s2) 
        if(*s1++=*s2++) 
            return *s1-*s2;
    return 0;
}

int main(){
    char a[100],b[100];
    gets(a);
    gets(b);
    printf("%d",strcomp(a,b));
    return 0;
}

18 对应月份英语

#include <stdio.h>
int main(){
    char *monthy[12] = {"January","Fabruary","March","April","May","june","july","August","September","October","November","December"};
    int mon;
    scanf("%d",&mon);
    puts(monthy[mon]);
    return 0;
}

19 开辟空间

#include <stdio.h>
#include <stdlib.h>
void* new(int n){
    return malloc(n*sizeof(char));
}
//have trouble
void free_(void *p){
    free(p);
}

int main(){
    char *str;
    str = new(10);
    // free_(str);
    printf("%c",str[3]='A');
    return 0;
}

第九章 复合数据类型

1 结构体变量定义

#include <stdio.h>
//两种方式都可以
// typedef struct date{
//     int year;
//     int month;
//     int day;
// }Date;
typedef struct{
    int year;
    int month;
    int day;
}Date;
//判断闰年
int isleap(int year){
    if(year%400==0) return 1;
    else if(year%4==0&&year%100) return 1;
    else return 0;
}
//求某天是该年的第几天
int no_day(int year,int month,int day){
    int sum=0;
    switch(month-1){
        case 11:sum+=30;
        case 10:sum+=31;    
        case 9:sum+=30;    
        case 8:sum+=31;    
        case 7:sum+=31;    
        case 6:sum+=30;    
        case 5:sum+=31;    
        case 4:sum+=30;    
        case 3:sum+=31;
        case 2:sum+=28; if(isleap(year)) sum+=1;   
        case 1:sum+=31;
        case 0:sum+=day; break;
        default: printf("数据有误!");
    }  
    return sum;
}

int main(){
    Date date_;
    scanf("%d%d%d",&date_.year,&date_.month,&date_.day);
    printf("这是%d年的第%d天,Time flies!",date_.year,no_day(date_.year,date_.month,date_.day));
    return 0;
}

2 days同上

3 结构体打印—

#include <stdio.h>
#define M 2
typedef struct achievement{
    int num;
    char name[10];
    int score[3];
}Achieve;
void input(Achieve one){
    scanf("%d",&one.num);
    gets(one.name);
    scanf("%d%d%d",one.score,one.score+1,one.score+2);
}
void print(Achieve one){
    printf("No.%d -- %s: 语文:%d 数学:%d 英语:%d\n",one.num,one.name,one.score[0],one.score[1],one.score[2]);
}
int main(){
    Achieve result[M];
    int i;
    for(i = 0; i<M; i++){
        input(result[i]);
        print(result[i]);
    }
        
    // for(i = 0; i<M; i++)
        
    return 0;
}

4 结构体输入

5 学生成绩

6 报数游戏-链表

#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(Player)
//类型声明
typedef struct Node{
    int num;
    struct Node *next;
} Player;
//动态链表创建
Player *creat(){
    int temp;  //暂存量--判断是否继续输入
    Player *head, *p1, *p2;
    head = p1 = p2 = (Player *)malloc(LEN);
    printf("请输入你的编号 宝儿:");
    scanf("%d", &temp);
    if (!temp) return NULL;  //第一次输入0,返回空表
    p2->num = temp;  //存入
    do
    {
        scanf("%d", &temp);  // 下一个节点的数据!!!
        if (!temp) break;    //输入0结束输入,不想继续输入=>不用再创建新节点     
        p1 = (Player *)malloc(LEN);  //创建新节点
        p1->num = temp;
        p2->next = p1;    //上个节点next指向新的节点
        p2 = p1;          //p2 也指向新节点
    } while (1);
    p2->next = head;     //循环链表
    return head;
}
//链表打印
void printLinked(Player *head){
    if (!head)
        printf("空表无法打印的哦 亲");
    else {
        Player *p = head;
    	while (p){
        	printf("%d ", p->num);
        	p = p->next;
            if(p==head) break;  //如果是循环链表
    	}
    }
}
//返回链表长度
int linklegth(Player *head){
    int len=0;
    Player *p = head;
    while (p){
        len++;
        p = p->next;
        if(p==head) break;
    }
    return len;
}
//循环链表 删除节点
void del_linked(Player *del){
    Player *p = del;
    while(p->next!=del)   //找到待删除节点的上一个节点
        p = p->next;
    p->next = del->next;  //将其指向下一个节点
}
//一起玩游戏呀,看看最后剩下谁
int playgame(Player *head){
    Player *p = head;
    int number=0;  //报号
    while (1){
        if(linklegth(p)==1) break;  //剩下一个,不玩了
        if(++number%3==0)  //报到3的, 即是3的倍数
            del_linked(p);  //退出-即删除
        p = p->next;   
    }
    return p->num;
}
int main(){
    Player *head;
    head = creat();
    printLinked(head);
    printf("\n这个链表有%d个节点\n",linklegth(head));
    printf("最后剩下了%d号玩家!!congratulation!",playgame(head));
    return 0;
}

7 链表删除节点

//链式链表 删除节点,无法删除头结点(head 为形参,无法改变实参的指向)
void del_linked(Player *head,Player *del){
    Player *p = head;
    while(p->next!=del){   //找到待删除节点的上一个节点
        p = p->next;
        if(!p){
            printf("\n找不到你要删除的节点呢 亲");
            return;
        }
    }
    p->next = del->next;  //将其指向下一个节点
}
//删除头结点可在主函数中使用以下语句
head = head -> next;

8 链表插入

//将add插入到head链表的第n个位置之后, n>=1     链式链表
void insert(Player* head,Player *add,int n){
    if(n<1) {printf("非法操作!");return;}  
    if(n>linklegth(head)) n = linklegth(head);  //大于最大长度,插入在最后
    Player * p = head;
	while(--n)
        p=p->next;
    add->next = p->next;
    p->next = add;    
}

9 链表的建立,输出,输出,插入

见上

10 合并链表

同插入

11 删除相同节点

12 哦哦哦

拜拜

第十章 文件(略)

附: 常用功能函数

0 基本结构

#include <stdio.h>
int main(){
    
    return 0;
}

1 数组值交换

//将数组p中的下标分别为a,b的两个数交换
void swap(int a,int b,int p[]){
    int temp = p[a];
    p[a] = p[b];
    p[b] = temp;
}
//二维数组交换
void swap(int i,int j,int m,int n,int (*arr)[N]){
    int temp = arr[i][j];   
    arr[i][j] = arr[m][n];
    arr[m][n] = temp;
}

2 对数组排序(升序)

//冒泡排序法升序
void bubbling(int *arr,int l){
    for(int i=0;i<l-1;i++){
        int var = 1; 
        for(int j=0;j<l-i-1;j++)
            if(arr[j]>arr[j+1]) {swap(j,j+1,arr); var = 0;}
        //print_arr(arr,l);  查看排序过程
        if(var) break;  //本回合未产生排序,即已排序完成,跳出循环,提高效率(非必须)
    }
}
//冒泡排序2,更简洁
void sortArr(int *a,int l){
    int i,j;
    for(i=0; i<l-1;i++)
        for(j=0;j<l-i-1;j++)
            if(a[j]>a[j+1]) swap(j,j+1,a);   //判断改为 < ,降序
}
//选择排序法升序,最多产生 l(数组长度) 次交换
void elect_sort(int *arr,int l){
    int i,j,k;
    for(i=0;i<l;i++){
        k=i;  //假设当前下标为最小值
        for(j=i+1;j<l;j++)  //找最小值下标
            if(arr[j]<arr[k]) k = j;
        if(k!=i) swap(i,k,arr);  //将最小值交换到i的位置
    }
}
//选择排序法2,交换次数较多,但更简洁
void elect_sort_1(int *arr,int l){
    for(int i=0; i<l; i++)
    	for(int j=i+1; j<l; j++)
            if(arr[i]>arr[j]) swap(i,j,arr);
}
//插入排序法升序
void insertt_sort(int *r, int l){
    int i, j, k;
    for (i = 1; i < l; i++){  //从第2个(即下标为1)个元素开始判断
        if (r[i] < r[i - 1]){  //比前一个元素小就执行寻找插入
            k = r[i];  //存入当前待插入的值,否则定位后移 会覆盖
            for (j = i - 1; r[j] > k && j>=0; j--) //后移,寻找合适的插入位置
                r[j + 1] = r[j];  
            r[j + 1] = k;  //插入
        }
    }
}

3 生成随机一维数组

#include <time.h>
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//随机数组 a数组首地址,l数组长度
void getArr(int *a,int l){
    int i=0;
    srand(time(NULL));  //以当前系统时间作为种子
    printf("你生成的数组为:");
    while (i < l) printf("%4d",a[i++] = rand()%(2*l+1));  //限制范围[0,2*l]
}

4 生成随机二维数组

#include <time.h>
#define N 4  //定义二维数组的第二维
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//随机数组 a数组首地址,m一维长度,n二维长度
void getArr(int (*a)[N],int m, int n){
    int i,j;
    srand(time(NULL));  //以当前系统时间作为种子
    for(i = 0; i < m;i++){
        for(j=0; j<n; j++)
            printf("%d ",a[i][j] = rand()%(2*m*n+1));  //限制范围[0,2*m*n]
    	putchar('\n');
    }
}

5 打印输出一维数组

//打印数组
void print_arr(int *arr,int l){
    putchar('\n');
    for(int i = 0;i<l; i++) printf("%4d",arr[i]);
    putchar('\n');
}
void print(int *a,int len){
    printf("数组为:");
    while(len--)  printf("%4d",*a++);
}

6 打印输出二维数组

//打印数组
void print_biarr(int (*a)[N],int m,int n){
    for(int i = 0;i<m; i++) {
        for(int j=0;j<n;j++)
            printf("%4d",a[i][j]);
        putchar('\n');
    }   
}

7 随机验证码-字符串数组

#include <time.h>
#define N 4  //定义二维数组的第二维
//函数声明: 防止编译系统警告
void srand(unsigned seed);
int rand(void);
//随机数组 a数组首地址,m一维长度,n二维长度
void getArr(char (*a)[N],int m, int n){
    int i,j;
    srand(time(NULL));  //以当前系统时间作为种子
    for(i = 0; i < m;i++){
        for(j=0; j<n; j++)
            printf("%c",a[i][j] = rand()%26+97);  //限制范围[97,122]
    	putchar('\n');
    }
}

8 int型数组长度

无解;

9 动态链表创建-输入

#define LEN sizeof(Player)
//类型声明
typedef struct Node{
    int num;
    struct Node *next;
} Player;
//动态链表创建
Player *creat(){
    int temp;  //暂存量--判断是否继续输入
    Player *head, *p1, *p2;
    head = p1 = p2 = (Player *)malloc(LEN);
    printf("请输入你的编号 宝儿:");
    scanf("%d", &temp);
    if (!temp) return NULL;  //第一次输入0,返回空表
    p2->num = temp;  //存入
    do
    {
        scanf("%d", &temp);  // 下一个节点的数据!!!
        if (!temp) break;    //输入0结束输入,不想继续输入=>不用再创建新节点     
        p1 = (Player *)malloc(LEN);  //创建新节点
        p1->num = temp;
        p2->next = p1;    //上个节点next指向新的节点
        p2 = p1;          //p2 也指向新节点
    } while (1);
    p2->next = NULL;    //将本节点的next指向NULL,如改为指向head,形成一个圈,循环链表
    return head;
}

10 链表打印+返回长度

//链表打印+长度
int printLinked(Player *head){
    int len = 0;
    if (!head)
        printf("这个是空表哦 亲");
    else {
        Player *p = head;
    	while (p){
        	printf("%d ", p->num);
        	p = p->next;
            len++;
            if(p==head) break;  //如果是首尾相连的链表
    	}
     }
    return len;
}

11 链表删除节点

//链式链表 删除节点
void del_linked(Player *head,Player *del){
    Player *p = head;
    while(p->next!=del){   //找到待删除节点的上一个节点
        p = p->next;
    	if(!p){
            printf("\n找不到你要删除的节点呢 亲");
            return;
        }
    }
    p->next = del->next;  //将其指向下一个节点
}
//循环链表 删除节点
void del_linked(Player *del){
    Player *p = del;
    while(p->next!=del)   //找到待删除节点的上一个节点
        p = p->next;
    p->next = del->next;  //将其指向下一个节点
}
//删除头结点可在主函数中使用以下语句
head = head -> next;

12 链表插入

//将add插入到head链表的第n个位置之后, n>=1     链式链表
void insert(Player* head,Player *add,int n){
    if(n<1) {printf("非法操作!");return;}  
    if(n>linklegth(head)) n = linklegth(head);  //大于最大长度,插入在最后
    Player * p = head;
	while(--n)
        p=p->next;
    add->next = p->next;
    p->next = add;    
}

13 素数判断

//直接判断n是否为素数
int Prime(int n){
    for(int i = 2; i<= sqrt(n); i++)
        if(n%i==0) return 0;
    return 1;
}

12 快速顺序查找法

#include <stdio.h>

int main()
{
    int a[9] = {25, 57, 48, 37, 12, 92, 86, 33}, i, x;
    scanf("%d", &x);
    a[8] = x;
    i = 0;
    while (a[i] != x)
       printf("%d\n",i++);
    i < 8 ? printf("find in %d", i) : printf("Not find");
    return 0;
}