c语言的基本案例猴子,学习日记 | C语言经典例题④(实例61-80)

©一颗斯特拉

【注】

1.标有❤️的是值得多做的题目

2.II、III代表二刷、三刷题目

题目来源于C语言经典例题(菜鸟教程100例)

4.《学习日记 | C语言经典例题③(实例41-60)》中题目比较偏,暂不更。

——3.1更新——

实例61:【二维数组】❤️II

题目:打印出杨辉三角形(要求打印出10行)。

01程序分析:

687419575167

杨辉三角形

02Bad Solution:

暂无

03Correct Solution:

#include

int main()

{

int i,j,a[100][100];

//左边一列,右边一列都是1。先把这些位置赋值

for(i=0;i<10;i++)

{

a[i][0]=1;

a[i][i]=1;

}

for(i=2;i<10;i++)

for(j=1;j

a[i][j]=a[i-1][j-1]+a[i-1][j];

for(i=0;i<10;i++){

for(j=0;j<=i;j++)

printf("%5d", a[i][j]);

printf("\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

04题目总结:

给大家推荐一个李永乐老师在b站上讲解「杨辉三角形」的视频。

实例66:【指针+函数】

题目:输入3个数a,b,c,按大小顺序输出。

01程序分析:

1.假设a、b、c依次变大,如果a>b,则交换a、b。

2.编写一个交换两个变量的函数,传递指针变量(实则为整形变量的存储地址),则在函数中可以改变变量的值。

02Bad Solution:

暂无

03Correct Solution:

#include

void swap(int *s1,int *s2);

int main() {

int a, b, c;

int *p1,*p2,*p3;

printf("请输入a、b、c的值:");

scanf("%d%d%d", &a, &b, &c);

p1=&a;

p2=&b;

p3=&c;

if(a>b)

swap(p1,p2);

if(a>c)

swap(p1,p3);

if(b>c)

swap(p2,p3);

printf("从小到大依次为:%d %d %d", a, b, c);

return 0;

}

void swap(int *s1,int *s2){

int t;

t=*s1;

*s1=*s2;

*s2=t;

}

【运行结果】

请输入a、b、c的值:3 2 1

从小到大依次为:1 2 3

04题目总结:

1.指针的使用

通过指针,可以简化一些 C 编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。所以,想要成为一名优秀的 C 程序员,学习指针是很有必要的。

每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址。

指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址。就像其他变量或常量一样,您必须在使用指针存储其他变量地址之前,对其进行声明。

所有实际数据类型,不管是整型、浮点型、字符型,还是其他的数据类型,对应指针的值的类型都是一样的,都是一个代表内存地址的长的十六进制数。

不同数据类型的指针之间唯一的不同是,指针所指向的变量或常量的数据类型不同。

使用指针时会频繁进行以下几个操作:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。这些是通过使用一元运算符 * 来返回位于操作数所指定地址的变量的值。

2.传递指针给函数。

实例67:【输入数组+函数】❤️II

题目:输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。

01程序分析:

02Bad Solution:

#include

int main(){

int i,a[10]={3,2,7,8,9,33,2,92,39,1},min,max,temp;

max=0;

min=9;

for(i=0;i<10;i++)

if(a[i]>a[max]) max=i;

if(max!=0)

{

temp=a[max];

a[max]=a[0];

a[0]=temp;

}

for(i=0;i<10;i++)

if(a[i]

if(min!=9)

{

temp=a[min];

a[min]=a[9];

a[9]=temp;

}

printf("交换后为:");

for(i=0;i<10;i++)

printf("%d ",a[i]);

}

【运行结果】

交换后为:92 2 7 8 9 33 2 3 39 1

【缺陷】没有解决数组自由输入的问题。

03Correct Solution:

#include

void fun(int *s,int n);

int main(){

int a[100],n,i;

printf("要输入整数的个数:");

scanf("%d",&n);

for(i=0;i

scanf("%d",&a[i]);//注意这里输入的时候用空格隔开

fun(a,n);

for(i=0;i

printf(" %d ",a[i]);

return 0;

}

void fun(int *s,int n) {

int max, min, t, i, a;

max = s[0];

for (i = 0; i < n; i++)

if (s[i] > max) {

max = s[i];

a = i;

}

s[a] = s[0];

s[0] = max;

min = s[n - 1];

for (i = 0; i < n; i++)

if (s[i] < min) {

min = s[i];

a = i;

}

s[a] = s[n-1];

s[n-1] = min;

}

【运行结果】

要输入整数的个数:3

1 5 3

5 3 1

04题目总结:

1.结合选择排序。

实例68:【数组】❤️

题目:有 n个整数,使其前面各数顺序向后移 m 个位置,最后m个数变成最前面的 m 个数。

01程序分析:

02Bad Solution:

暂无

03Correct Solution:

【方法一】

#include

void change_back(int *a,int n,int m){//或者int a[]

int i,j,temp;

for(i=0;i

temp=a[n-1];//先把最后一位数保存

//再整体往后移动一位

for(j=n-2;j>=0;j--)

a[j+1]=a[j];

//最后将保存的数放到第一个位置上

a[0]=temp;

}

}

int main(){

int a[100],n,m,i;

printf("请输入数的个数:");

scanf("%d",&n);

printf("请输入该数组:");

for(i=0;i

scanf("%d",&a[i]);

printf("替换前的数组:");

for(i=0;i

printf("%d ",a[i]);

printf("\n");

printf("请输入要替换的个数:");

scanf("%d",&m);

change_back(a,n,m);

printf("替换后的数组:");

for(i=0;i

printf("%d ",a[i]);

return 0;

}

【运行结果】

请输入数的个数:4

请输入该数组:1 2 3 4

替换前的数组:1 2 3 4

请输入要替换的个数:2

替换后的数组:3 4 1 2

【方法二】

方法一的函数可以变成以下形式,发挥指针的作用。

//滚动数组

void move(int a[],int n,int m)

{

int *p,*a_end;

arr_end=a+n; //数组最后一个元素的下一个位置

int last;

//滚动直到偏移量为0

while(m)

{

last=*(arr_end-1);

for(p=arr_end-1;p!=a;--p) //向右滚动一位

*p=*(p-1);

*a=last;

--m;

}

}

04题目总结:

暂无

实例69:【指针、循环、条件语句的综合运用】❤️✨II

题目:有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。

01程序分析:

需要的变量:一个数组num[](将所有人编号)、记录总人数的n、指针p、循环变量ijk、用于记录退出人数的m(循环终止条件)、报数k。

思路:报数为3的人编号为0,最后输出数组中非零的那一个

02Bad Solution:

暂无

03Correct Solution:

【方法一】

#include

int main()

{

int num[50],n,*p,j,loop,i,m,k;

printf("请输入这一圈人的数量:\n");

scanf("%d",&n);

p=num;

//开始给这些人编号

for (j=0;j

{

*(p+j)=j+1;

}

i=0;//i用于计数,即让指针后移

m=0;//m记录退出圈子的人数

k=0;//k报数1,2,3

while(m

//这句不能写成m

//这时是7<8,剩下的一个人自己喊1,2,3那么他也就退出了,将不会有输出

{

if (*(p+i)!=0)//如果这个人的头上编号不是0就开始报数加1,这里采用的方法是报数为3的人头上编号重置为0

{

k++;

}

if (k==3)

{ k=0; //报数清零,即下一个人从1开始报数

*(p+i)=0;//将报数为3的人编号重置为0

m++; //退出人数加1

}

i++; //指针后移

if (i==n)//这句很关键,如果到了队尾,就要使指针重新指向对头

//并且它只能放在i++后面,因为只有i++了才有可能i==n

{

i=0;

}

}

printf("现在剩下的人是:");

for (loop=0;loop

{

if (num[loop]!=0)

{

printf("%2d号\n",num[loop]);

}

}

return 0;

}

【运行结果】

请输入这一圈人的数量:

8

现在剩下的人是: 7号

【方法二】

其实这道题不用指针,只用数组也可以做,毕竟数组本身就可以表示每个位置上的值。

#include

int main()

{

int num[50],n,loop,i,m,k;

printf("请输入这一圈人的数量:\n");

scanf("%d",&n);

//给这圈人编号

for (loop=0;loop

{

num[loop]=loop+1;

}

//给3个重要变量赋初值

i=0;//i用于计数,即让指针后移

m=0;//m记录退出圈子的人数

k=0;//k报数1,2,3

//开始报数,将报到3的人编号成0,表示退出

while(m

//这句不能写成m

//这时是7<8,剩下的一个人自己喊1,2,3那么他也就退出了,将不会有输出

{

//①报数

if (num[i]!=0)//如果这个人的头上编号不是0就开始报数加1,因为是0表示退出了

{

k++;

}

//②如果报到3就退出

if (k==3)

{ k=0; //易漏:报数清零,即下一个人从1开始报数

num[i]=0;//将报数为3的人编号重置为0

m++; //退出人数加1

}

//③否则下一位报数

i++;

//④特别的:一圈轮完再来一圈

if (i==n)//这句很关键,如果到了队尾,就要使指针重新指向对头

//并且它只能放在i++后面,因为只有i++了才有可能i==n

{

i=0;

}

}

//剩下的是编号不为0的人

printf("现在剩下的人是:");

for (loop=0;loop

{

if (num[loop]!=0)

{

printf("%2d号\n",num[loop]);

}

}

return 0;

}

【运行结果】

请输入这一圈人的数量:

8

现在剩下的人是: 7号

【方法三】

#include

int M = 3;

int main()

{ int n, s = 0;

scanf("%d", &n); for (int i = 2; i <= n; ++i)

s = (s+M)%i;

printf("%d\n", s+1); return 0;

}

暂时没看懂···

04题目总结:

对于这种比较复杂的题,一定要先把思路想清楚再做。

——4.1更新——

✨上海银行春``招原题

实例70:【指针数组】

题目:写一个函数,求一个字符串的长度,在main函数中输入字符串,并输出其长度。

01程序分析:

暂无

02Bad Solution:

暂无

03Correct Solution:

#include

int length(char *s);

int main()

{

char ch[20];

int i,len;

printf("请输入字符串:");

scanf("%s",ch);

len=length(ch);

printf("字符串的长度为: %d ",len);

return 0;

}

int length(char *s){

int n=0;

while(*s!='\0'){

s++;//指针递增

n++;

}

return n;

}

【运行结果】

请输入字符串:www,fdfvd

字符串的长度为: 9

04题目总结:

1.指针的运算

指针的每一次递增,它其实会指向下一个元素的存储单元。

指针的每一次递减,它都会指向前一个元素的存储单元。

指针在递增和递减时跳跃的字节数取决于指针所指向变量数据类型长度,比如 int 就是 4 个字节。

实例75:【while】❤️II

题目:输入一个整数,并将其反转后输出。

01程序分析:

最小位数依次升高,最高位数依次降低,用取余和整除运算实现。

02Bad Solution:

暂无

03Correct Solution:

#include

int main()

{

int num,renum=0;

printf("请输入一个整数:");

scanf("%d",&num);

while(num!=0){

renum=num%10+renum*10;

num=num/10;

}

printf("反转后的整数: %d",renum);

}

【运行结果】

请输入一个整数:1234

反转后的整数: 4321

【更清楚的答案】

#include

int main()

{

int num,renum=0,remain;

printf("请输入一个整数:");

scanf("%d",&num);

while(num!=0){

remain=num%10;//取下最后一位数

renum=remain+renum*10;//升高最后一位数

num=num/10;

}

printf("反转后的整数: %d",renum);

}

04题目总结:

1.记住这种常用的取各个位数的方法。

实例76:【指针函数】❤️II

题目:编写一个函数,输入n为偶数时,调用函数求1/2+1/4+...+1/n,当输入n为奇数时,调用函数1/1+1/3+...+1/n(利用指针函数)。

01程序分析:

02Bad Solution:

#include

double fun1(int n);

double fun2(int n);

int main()

{

int num;

printf("请输入一个整数:");

scanf("%d",&num);

if(num%2==0){

printf("%lf",fun1(num));

}

else

{

printf("%lf",fun2(num));

}

}

double fun1(int n)

{

int i;

double sum=0;

for(i=1;i<=n/2;i++)

sum=(double)(sum+1/(2*i));

return sum;

}

double fun2(int n)

{

int i;

double sum=0;

for(i=0;i<=(n-1)/2;i++)

sum=(double)(sum+1/(2*i+1));

return sum;

}

03Correct Solution:

【运行结果】

04题目总结:

1.指针函数

指针函数是返回指针值的函数。其一般定义形式:

类型名 *函数名(参数表列)

例如:

math?formula=%5Ctext%7Bint%20*a(int%20x%20%2Cint%20y)%7D

2.函数指针

函数指针的声明方法为:

返回值类型 ( * [指针变量]名) ([形参列表]);

注1:“返回值类型”说明函数的返回类型,“(指针变量名 )”中的括号不能省,括号改变了运算符的优先级。若省略整体则成为一个函数说明,说明了一个返回的数据类型是指针的函数,后面的“形参列表”表示指针变量指向的函数所带的参数列表。例如:

math?formula=%5Ctext%7Bint%20func(int%20x)%3B%7D /* 声明一个函数 */

math?formula=%5Ctext%7Bint%20(*f)%20(int%20x)%3B%7D /* 声明一个函数指针 */

math?formula=%5Ctext%7Bf%3Dfunc%3B%7D /* 将func函数的首地址赋给指针f */

或者使用下面的方法将函数地址赋给函数指针:

math?formula=%5Ctext%7Bf%20%3D%20%26func%3B%7D

赋值时函数func不带括号,也不带参数,由于func代表函数的首地址,因此经过赋值以后,指针f就指向函数func(x)的代码的首地址。

注2:函数括号中的形参可有可无,视情况而定。

指针函数不同于函数指针。函数指针声明为指针,它与变量指针不同之处是,它不是指向变量,而是指向函数。所以一定要注意。函数指针有两个用途:调用函数和做函数的参数.

实例80:【猴子吃桃问题】✨❤️

题目:海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子平均分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了 一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的, 问海滩上原来最少有多少个桃子?

01程序分析:

02Bad Solution:

暂无

03Correct Solution:

#include

#include

int main()

{

int x,i=0,j=1;

while(i<5){

x=4*j;//最少都是4个

for(i=0;i<5;i++)

{

if(x%4!=0){break;}

x=(x/4)*5+1;

}//5个猴子的条件都满足了

j++;

}

printf("%d\n",x);

return 0;

}

【运行结果】

3121

04题目总结:

1.【变形】

题目:一只小猴子一天摘了许多桃子,第一天吃了一半,然后忍不住又吃了一个;第二天又吃了一半,再加上一个;后面每天都是这样吃。到第10天的时候,小猴子发现只有一个桃子了。问小猴子第一天共摘了多少个桃子。

#include

int main()

{

int i = 1;//表示每天多吃的那一个

int j = 1;//用来控制循环

for (j = 10;j > 1;j--)

{

i++;

i = 2 * i;//吃了一半加一个

}

printf("第一天摘了 %d 个桃子。", i);

}

【运行结果】

第一天摘了 1534 个桃子。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值