概述
©一颗斯特拉
【注】
1.标有❤️的是值得多做的题目
2.II、III代表二刷、三刷题目
题目来源于C语言经典例题(菜鸟教程100例)
4.《学习日记 | C语言经典例题③(实例41-60)》中题目比较偏,暂不更。
——3.1更新——
实例61:【二维数组】❤️II
题目:打印出杨辉三角形(要求打印出10行)。
01程序分析:
杨辉三角形
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("%dn", 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!='