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]就是第3i+j個數,如a[2][1]a[2][1]就是第3*2+1=7個數(注意C語言是從0開始計數的)。*p是數組中第一個數第地址,(p+3i+j)(p+3*i+j)j就是a[i][j]的地址,轉置矩陣的a[i][j]=a[j][i]a[i][j]=a[j][i],兩個地址交換一下就ok了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章