C语言不挂科之我爱谭浩强——编程题拿高分(附例题答案和知识点详解)

期末考试要考C语言,边复习边写博客,总结了一些自己不太明白或者可能出错的知识点。现自己已经弄明白,写的你们肯定也能明白,希望期末备考的同学们不挂科,也适合自学C语言的小白哦
这篇博客主要写指针,由易到难,会了指针,前面的例题也就都会了。

先来个冒泡排序热身吧

在这里插入图片描述

#include<stdio.h>
void swap(int *a,int *b){
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main(){
	int arr[6]={2,5,8,1,6 ,4};
	int i, j, temp,len=6;
    for (i = 0; i < len - 1; i++)
        for (j = 0; j < len - 1 - i; j++)
            if (arr[j] > arr[j + 1]) {
            	swap(&arr[j], &arr[j + 1]);
            }
    for (i = 0; i < len; i++){
    	printf("%d ",arr[i]);
	}
}

在这里插入图片描述在这里插入图片描述
https://blog.csdn.net/weixin_45755332/article/details/106892672

在这里插入图片描述

  1. 对三个数进行大小排序
# include <stdio.h>
int swap(int *p,int *q);
int main(){
int  a=5, b=11, c=9;
int *p1=&a,*p2=&b,*p3=&c;
printf("%d %d %d\n",a,b,c);
printf("%d %d %d\n",p1,p2,p3);
	if (a>b){
		swap(p1,p2);
	}
	if(a>c){
		swap(p1,p3);
	}
	if (b>c){
		swap(p2,p3);
	}
	printf("%d %d %d\n",a,b,c);
	printf("%d %d %d\n",p1,p2,p3);
}

int swap(int *p,int *q){
	int o;
	o = *p;
	*p = *q;
	*q = o;}

5 11 9
6487556 6487552 6487548
5 9 11
6487556 6487552 6487548

这个swap函数必须用指针写,如果这样,两个数在函数内是交换了,但没有返回主函数,所以必须用指针写,由结果可以看出,函数交换了指针上存放的数值,指针本身并没有变。

int swap(int p,int q){
	int o;
	o = p;
	p = q;
	q = o;
}
  1. 对10个整数,将其中最小的数与第一个数对换,把最大的数与最后一个数对换
# include <stdio.h>
int swap(int *p,int *q);
int main( ){
	int a[10]={11,5,8,7,6,9,0,3,4,2} ,*min,*max,*p;
	max=min=a;
	p=a; 
	for (;p<a+10;p++){
		if (*max<*p)
			max=p;
	}
	swap(a+9,max);
	for (p=a;p<a+10;p++){
		if(*min>*p)
			min=p;		
	}
	swap(a,min);
	for (p=a;p<a+10;p++)
		printf("%d ",*p);
}

int swap(int *p,int *q){
	int o;
	o = *p;
	*p = *q;
	*q = o;
}

本题的主要思路就是先让max和min都等于第一个值的地址,让其与后面的每一个值的地址进行比较,(注意这里是指针的大小比较)如果min比后面的某个值x大,就把x的地址赋值给min,若还有个y比x还小,就把y的地址再赋值给min,直到找到最小的值。注意这时并没有进行数值交换,只是min这个指针指向了不同的数值,下面的swap函数才让其交换了地址所存放的数值。max是一样的。
有的同学可能会想到,用一个for循环,直接找出最大和最小的值不就行吗。不行!
因为这里有个bug如果a=>第一个数是最大的,b=>最后一个数为最小的,a||b 之能交换一个最值,a&b直接不交换。要是非得用也行, 看老谭怎么写的吧
在这里插入图片描述

  1. 有n个人围成一圈,顺序排号。从第1个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。
# include <stdio.h>
int main(){
	int i, k, m, n, num[50], *p;
	printf("input number of person: n=" );
	scanf("%d", &n);
	p=num;
	for(i=0;i<n;i++)		//给人数编号
		*(p+i)=i+1;
		
	i=0;				//i为每次循环时计数变量
	k=0;				//k为按1 2 3报数的计数变量
	m=0;				//m 是出局的人数
	
	while(m<n-1){ 		//m 是出局的人数,因有n个人,最后剩一个人,最多出局(n-1)个人
	   if( *(p+i) != 0)	//判断这个序号(原来的序号)是否出局
			k++;		//如果这个号没有出局,就报数,计数器加1,要是出局了就不算这个号了
			
		if(k==3){		//报3的出局
			*(p+i)=0;	//将出局的这个人标记为0
			k=0;		//使计数器置零,重新数1 2 3
			m++;		//出局人数计数器加1
			}		

			i++;		//将指针后移,虽然i不是指针,但p+i就是指针了,i为指针服务
		if(i==n)		//如果指针移到了尾部,则返回到头部
			i=0;		//因为编号是从1开始的,所以i=0,以确保下一个是开头
		}
	int a=0;			
	for(i=0;i<n;i++){	//因为报到3的就设置成0了,所以加起来就是最后那个序号 
		a+=num[i];		
	}
	printf("最后一个是%d ",a);

}

在这里插入图片描述
4. 将一个3x3矩阵进行转置操作

# include<stdio.h>
int main(){
	int a[3][3]={1, 2,3, 4, 5 ,6, 7 ,8 ,9 },t ,*p;
	printf("原矩阵\n");
	for (int i=0;i<3;i++){
		for (int j=0;j<3;j++)
			printf("%d ",a[i][j]);
		printf("\n");
	}
	p=&a[0][0];
	for (int i=0;i<3;i++){
		for (int j=i;j<3;j++){
			t=*(p+3*i+j);
			*(p+3*i+j)=*(p+3*j+i);
			*(p+3*j+i)=t;
		}
	}
	printf("转置矩阵\n");
	for (int i=0;i<3;i++){
		for (int j=0;j<3;j++)
			printf("%d ",a[i][j]);
		printf("\n");
	}

}

原矩阵
1 2 3
4 5 6
7 8 9
转置矩阵
1 4 7
2 5 8
3 6 9

这个指针挺简单的,关键是两两交换为啥那样。
在这个33矩阵a中, a [ i ] [ j ] a[i][j] a[i][j]就是第3i+j个数,如 a [ 2 ] [ 1 ] a[2][1] a[2][1]就是第3*2+1=7个数(注意C语言是从0开始计数的)。*p是数组中第一个数第地址, ( p + 3 ∗ i + j ) (p+3*i+j) (p+3i+j)j就是a[i][j]的地址,转置矩阵的 a [ i ] [ j ] = a [ j ] [ i ] a[i][j]=a[j][i] a[i][j]=a[j][i],两个地址交换一下就ok了

评论 37
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猛男技术控

感谢支持!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值