前言
博主在幾年前的C語言後中,結合自身學習情況和學習感悟在當時的一個寒假做了兩份C語言學習的經驗總結,分別爲 《C語言學習基本框架》 和 《C語言學習基礎程序》,
現在把它們分享出來,供大家交流學習,如果能給初學C語言的小夥伴們提供一些幫助也是不錯的,想當初我也是從C語言的折磨中走出來的,吼吼吼!
一、常見練習題
1. 計算1!+2!+n!
思路:運用兩層for循環,一層進行階乘計算,一層進行加法運算.
#include
int main()
{
int n,i,j,k=1,s=0;
printf("請輸入項數:\n");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
k=1;
for(j=1;j<=i;j++)
{
k=k*j;
}
s=s+k;
}
printf("結果=%d\n",s);
return 0; }
2. 計算斐波那列數列第n項
思路:先對項數進行判斷,分爲兩部分計算,第二部分運用遞歸的思想.
#include
int main()
{
int n,i,f,f1=1,f2=1;
printf("請輸入項數:\n");
scanf("%d",&n);
if(n<=2)
f=1;
else
for(i=3;i<=n;i++)
{
f=f1+f2;
f1=f2;
f2=f;
}
printf("結果=%d\n",f);
return 0;
}
3. 愛因斯坦階梯問題
思路:通過while循環判斷,不斷增加倍數,直至循環結束.
#include
int main()
{
int x=7,i=1;
while(!((x%2==1)&&(x%3==2)&&(x%5==4)&&(x%6==5)))
{
i++;
x=7*i;
}
printf("%d\t",x);
return 0;
}
4. 求勾股數
思路:通過三層for循環依次遞增,再運用if語句進行判斷.
#include
int main()
{
int x,y,z,k=0;
for(x=1;x<100;x++)
{
for(y=1;y<100;y++)
{
for(z=1;z<100;z++)
{
if(x*x+y*y==z*z&&x<y&&y<z)< p=""></y&&y<z)<>
printf("x=%dy=%dz=%d\n",x,y,z),k++;
}
}
}
printf("%d\n",k);
return 0;
}
5. 百錢百雞問題
思路:通過三層for循環將雞翁,雞母,雞雛依次遞增,在運用if語句進行兩個條件合併判斷.
#include
int main()
{
int x,y,z;
for(x=1;x<=20;x++)
{
for(y=1;y<=33;y++)
{
for(z=1;z<=100;z++)
{
if(15*x+9*y+z==300&&x+y+z==100)
printf("公雞:%d母雞:%d雞雛:%d\n",x,y,z);
}
}
}
return 0;
}
6. 編寫函數,一趟循環,找出數組的最大元素和最小元素
思路:以a[0]爲比較元素,與數組其他元素依次判斷,如果大於則記錄max,如果小於則記錄min.
#include<stdio.h>
void max_min(int p[]);
int main()
{
int a[10],i;
printf("input 10 integers:\n");
for(i=0;i<10;++i)
scanf("%d",&a[i]);
max_min(a);
return 0;
}
void max_min(int p[])
{
int i,max=0,min=0;
for (i=0;i<10;i++)
{
if(p[max]<p[i])
max=i;
if(p[min]>p[i])
min=i;
}
printf("最大值=%d\t最小值=%d\n",p[max],p[min]);
}
7. 編寫函數,倒排數組元素
思路:將數組元素分爲前後兩個部分,然後兩個部分頭尾對應函數依次交換. 解法:
#include <stdio.h>
void RevertToSelf(int p[],int n);
int main()
{
int a[6],i;
printf("input 6 integers:\n");
for (i=0;i<6;i++)
{
scanf("%d",&a[i]);
}
printf("倒排後:\n");
RevertToSelf(a,6);
return 0;
}
void RevertToSelf(int p[],int n)
{
int temp,i;
for(i=0;i<n/2;i++)
{
temp=p[i];
p[i]=p[n-1-i];
p[n-1-i]=temp;
}
for(i=0;i<n;i++)
printf("%d\t",p[i]);
printf("\n"); }
8. 編寫函數,從數組元素中挑選出百位數比十位數和個位數之和還大的元素
思路:將數組元素個位數,十位數,百位數分別賦值,後運用if語句比較判斷. 解法
#include<stdio.h>
void compare(int p[]);
int main()
{
int a[5],i;
printf("input 5 integers:\n");
for(i=0;i<5;i++)
{
scanf("%d",&a[i]);
}
compare(a);
return 0;
}
void compare(int p[])
{
int i,k,x,y,z;
for (i=0;i<5;i++)
{
k=p[i];
x=k%10;
k=k/10;
y=k%10;
k=k/10;
z=k%10;
if(x+y<z)
printf("元素:%d\n",p[i]); } }
9. 編寫檢驗密碼函數,密碼輸入錯誤時,允許重新輸入,最多3次
思路:首先運行for語句設置3次循環,進入for循環後首先進行strcmp判斷,若爲是則通過,不是則記錄次數,達到3次則退出.
#include<stdio.h>
#include<string.h>
int main()
{
char a[10];
char b[10]="123456";//初始化密碼
int i;
printf("請輸入密碼:\n");
for(i=0;i<3;i++)//輸入三次密碼
{
scanf("%s",&a);
if(strcmp(a,b)==0)//比較字符串
{
printf("歡迎使用!\n");
return 0;
}
else
if(i<2)
printf("輸入錯誤,請重新輸入:\n");
if(i==2)
printf("非法用戶!\n");
}
return 0;
}
二、常見問題
1. Josephus問題
問題描述:假設有n個人圍坐一圈,現在要求從第k個人開始報數,報到第m個數的人退出。然後從下一個人開始繼續報數並按照同樣的規則退出,直至所有人都退出。按照順序輸出各出列人的編號
#include<stdio.h>
#include<stdlib.h>
int josephus(int n,int m);
int main()
{
int num,counter;
printf("請輸出總人數和循環數:\n");
scanf("%d%d",&num,&counter);
printf("獲勝者=%d\n",josephus(num,counter));
return 0;
}
int josephus(int n,int m)
{
int i,j,winner,*p;
p=(int*)malloc(n*sizeof(int));
for(i=0;i<n;i++)
p[i]=i+1;
i=0;
while(n>1)
{
i=(i+m-1)%n;
printf("淘汰者:%d\n",p[i]);
for(j=i+1;j<n;j++)
p[j-1]=p[j];
n--;
if(i==n)
i=0;
}
winner=p[0];
free(p);
return winner;
}
2. 模擬洗牌
問題模擬:編程用C語言模擬人工洗牌過程
#include<stdio.h>
#include<stdlib.h>
#include <time.h>
typedef struct
{
char suit;
int pips;
}Card;
void shuffle(Card pa[],int n);
void display(const Card pa[],int n);
int main()
{
int i;
Card deck[52];
for (i=0;i<52;i++)
{
deck[i].suit=i/13+3;
deck[i].pips=i%13+1;
}
printf("before suffling:\n");
display(deck,52);
shuffle(deck,52);
printf("after shuffling:\n");
display(deck,52);
return 0;
}
void shuffle(Card pa[],int n)
{
int i,j;
Card temp;
srand(time(0));
for (i=0;i<n;i++)
{
j=rand()%n;
temp=pa[i];
pa[i]=pa[j];
pa[j]=temp;
}
}
void display(const Card pa[],int n)
{
int i;
for (i=0;i<n;i++)
{
printf("(%c-",pa[i].suit);
printf("%d)",pa[i].pips);
if((i+1)%13==0)
printf("\n");
}
}
3. 起泡排序
問題描述:編程用起泡排序給一組數組從小到大進行排序
#include <stdlib.h>
#include<stdio.h>
void bubble(int p[],int n);
int main()
{
int i,a[5];
printf("input 5 integers:\n");
for(i=0;i<5;i++)
scanf("%d",&a[i]);
bubble(a,5);
return 0;
}
void bubble(int p[],int n)
{
int i,j,last,temp;
i=0;
while(i<n-1)
{
last=n-1;
for (j=n-1;j>i;j--)
{
if(p[j]<p[j-1])
{
temp=p[j-1];
p[j-1]=p[j];
p[j]=temp;
last=j;
}
}
i=last;
}
for(i=0;i<5;i++)
printf("%d\t",p[i]);
printf("\n");
}
4. 順序表練習
問題描述:編程使用順序表對數組進行一些基本操作
//Test.c(主函數)
typedef int Type;
#include "seqlist.h"
#include <stdlib.h>
int main()
{
int i,n;
Seqlist L;
IniList(&L,10);//建立空表
InsertRear(&L,5);//尾插入5
InsertRear(&L,15);//尾插入15
InsertRear(&L,20);//尾插入20
Insert(&L,1,10);//在下標爲1的位置插入10
Erase(&L,0);//刪除下標爲1的數據元素
n=Size(&L);//取數據個數
for (i=0;i<n;i++)
{
printf("%d\t",Getdate(&L,i));//打印出現存數據元素
}
printf("\n");
Clear(&L);//清表
FreeList(&L);//撤銷動態空間
return 0;
}
//Seqlist.h(順序表聲明)
typedef int Type;
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
Type * date;
int size;
int max;
}Seqlist;
void IniList(Seqlist *l,int n);
void FreeList(Seqlist *l);
void InsertRear(Seqlist *l,Type item);
void Insert(Seqlist *l,int id,Type item);
void Erase(Seqlist *l,int id);
void Clear(Seqlist *l);
Type Getdate(const Seqlist *l,int id);
int Size(const Seqlist *l);
//Seqlist.c(順序表實現)
#include <stdio.h>
#include <stdlib.h>
#include "seqlist.h"
void IniList(Seqlist *l,int n)
{
l->date=(Type*)malloc(n*sizeof(Type));
l->size=0;
l->max=n;
}
void FreeList(Seqlist *l)
{
free(l->date);
}
void InsertRear(Seqlist *l,Type item)
{
if (l->size==l->max)
{
printf("list is full!\n");
exit(1);
}
l->date[l->size]=item;
l->size++;
}
void Insert(Seqlist *l,int id,Type item)
{
int i;
if(l->size==l->max||id<0||id>l->size)
{
printf("list is full or id is illegal!\n");
exit(1);
}
for (i=l->size-1;i>=id;--i)
{
l->date[i+1]=l->date[i];
}
l->date[id]=item;
l->size++;
}
void Erase(Seqlist *l,int id)
{
int i;
if (id<0||id>l->size-1)
{
printf("list is empty or id is illegal!\n");
exit(1);
}
for (i=id+1;i<l->size;++i)
{
l->date[i-1]-l->date[i];
}
l->size--;
}
void Clear(Seqlist *l)
{
l->size=0;
}
Type Getdate(const Seqlist *l,int id)
{
if (id<0||id>l->size-1)
{
printf("list is empty or id is illegal!\n");
exit(1);
}
return l->date[id];
}
int Size(const Seqlist *l)
{
return l->size;
}
5. 鏈表練習
問題描述:編程使用鏈表對數組進行一些基本操作
//Test.c(主函數)
typedef int Type;
#include<stdio.h>
#include"List.h"
void display_list(Node *first,Node *last);
int main()
{
int i,item;
Node *current;
List L;
Init(&L);
printf("input 10 integers:\n");
for(i=0;i<10;++i)
{
scanf("%d",&item);
Push_back(&L,item);
}
current=Begin(&L);
current=Get_next(current);
printf("the second:\n");
printf("%d\n",Get_date(current));
current=Get_prev(current);
printf("the first :\n");
printf("%d\n",Get_date(current));
Erase(&L,current);
printf("after erasing the first:\n");
display_list(Begin(&L),End(&L));
Pop_back(&L);
printf("after erasing the last:\n");
display_list(Begin(&L),End(&L));
printf("the first and the last:\n");
printf("%d\n",Front_date(&L));
printf("%d\n",Back_date(&L));
printf("update the first and the last:\n");
*Front_pointer(&L)=100;
*Back_pointer(&L)=200;
display_list(Begin(&L),End(&L));
Free(&L);
return 0;
}
void display_list(Node *first,Node *last)
{
for(;first!=last;first=Get_next(first))
printf("%d\t",Get_date(first));
printf("\n");
}
//Node.h(結點聲明)
#ifndef NODE_H
#define NODE_H
typedef int Type;
struct Node
{
Type date;
struct Node *prev;
struct Node *next;
};
typedef struct Node Node;
Node *Get_node(Type item,Node *prev0,Node *next0);
Type Get_date(Node *current);
Node *Get_next(Node *current);
Node *Get_prev(Node *current);
void Set_date(Node *current,Type item);
#endif
//Node.c(結點實現)
#include"Node.h"
#include<stdio.h>
Type Get_date(Node *current)
{
return current->date;
}
Node *Get_next(Node *current)
{
return current->next;
}
Node *Get_prev(Node *current)
{
return current->prev;
}
Node *Get_node(Type item,Node *prev0,Node *next0)
{
Node *p;
p=(Node*)malloc(sizeof(Node));
if(p==NULL)
{
printf("Memory allocation failure!");
exit(1);
}
p->date=item;
p->prev=prev0;
p->next=next0;
return p;
}
void Set_date(Node *current,Type item)
{
current->date=item;
}
//List.h(鏈表聲明)
#ifndef LIST_H
#define LIST_H
#include"Node.h"
typedef struct
{
Node *head;
Node *tail;
int size;
}List;
void Init(List *L);
Node *Begin(List *L);
Node *End(List *L);
Node *Insert(List *L,Node *current,Type item);
Node *Erase(List *L,Node *current);
Type *Front_pointer(List *L);
Type Front_date(List *L);
Type *Back_pointer(List *L);
Type Back_date(List *L);
void Push_front(List *L,Type item);
void Push_back(List *L,Type item);
void Pop_front(List *L);
void Pop_back(List *L);
int Empty(List *L);
void Clear(List *L);
void Free(List *L);
#endif
//List.c(鏈表實現)
#include"List.h"
#include<stdio.h>
void Init(List *L)
{
L->head=(Node*)malloc(sizeof(Node));
if(L->head==NULL)
{
printf("Memory allocation failure!");
exit(1);
}
L->head->next=L->head->prev=NULL;
L->tail=(Node*)malloc(sizeof(Node));
if(L->tail==NULL)
{
printf("Memory allocation failure!");
exit(1);
}
L->tail->next=L->tail->prev=NULL;
L->head->next=L->tail;
L->tail->prev=L->head;
L->size=0;
}
Node *Begin(List *L)
{
return L->head->next;
}
Node *End(List *L)
{
return L->tail;
}
Node *Insert(List *L,Node *current,Type item)
{
Node *p=current;
L->size++;
p->prev->next=Get_node(item,p->prev,p);
p->prev=p->prev->next;
return p->prev;
}
Node *Erase(List *L,Node *current)
{
Node *p=current;
Node *re=p->next;
p->prev->next=p->next;
p->next->prev=p->prev;
free(p);
L->size--;
return re;
}
Type *Front_pointer(List *L)
{
Node *current=L->head->next;
return &(current->date);
}
Type Front_date(List *L)
{
Node *current=L->head->next;
return current->date;
}
Type *Back_pointer(List *L)
{
Node *current=L->tail->prev;
return &(current->date);
}
Type Back_date(List *L)
{
Node *current=L->tail->prev;
return current->date;
}
void Push_front(List *L,Type item)
{
Insert(L,Begin(L),item);
}
void Push_back(List *L,Type item)
{
Insert(L,End(L),item);
}
void Pop_front(List *L)
{
Erase(L,Begin(L));
}
void Pop_back(List *L)
{
Erase(L,Get_prev(End(L)));
}
int Empty(List *L)
{
return L->size==0;
}
void Clear(List *L)
{
while(!Empty(L))
Pop_front(L);
L->size=0;
}
void Free(List *L)
{
Clear(L);
free(L->head);
free(L->tail); }
結語
《C語言學習基礎程序》僅爲博主在學習C語言時自己的記錄與積累,加上後期的整理所成。可能對於C語言入門的理解與初步掌握有一定的幫助。
當然,介於當時的水平有限,文章本身可能還存在內容上的紕漏或者錯誤,如果讀者在閱讀中發現錯誤,也請不吝指出,謝謝!
注:《C語言學習基礎程序》會放在附件中,感興趣的小夥伴歡迎下載嗷~
下載鏈接: C語言學習基礎程序——Mr.鵬