C语言学习与感悟——《C语言学习基础程序》

前言

博主在几年前的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.鹏

发布了13 篇原创文章 · 获赞 29 · 访问量 1990

猜你喜欢

转载自blog.csdn.net/qq_41618424/article/details/104594240