妈妈再也不用担心我的C语言啦!

妈妈再也不用担心我的C语言啦!


养个好习惯,点个赞,关注再走吧!专升本备考期间总结出来的,建议收藏。


算法总结

x + x + 1 + x + 2 \sqrt{x+x+1+x+2} x+x+1+x+2 是整数

编程,在[1,98]查找并输出所有满足条件“x+x+1+x+2的平方根是整数”的数x(如输出2、11,因为2+3+4的和为9,11+12+13和为36,他们的平方根3、6都是整数)

#include <stdio.h>
#include<math.h>
void main()
{
    
      
    int i,s;
	for(i=1;i<=98;i++) {
    
    
	    s=3*i+3;
		if(sqrt(s)==(int)sqrt(s)){
    
    
			printf("%d\n",i);
		}
    }
}

s(n)=a+aa+aaa+aa…a

#include<stdio.h>
int main()
{
    
    
	int n,a,s=0,term=0;
	printf("a,n=");
	scanf("%d%d", &a, &n);
	for(int i=1; i<=n; i++)
	{
    
    
		term+=a;
		s+=term;
		a*=10;
	}
	printf("%d\n", s);
	return 0;
}

1!+2!+3!+4!+…+20!

#include<stdio.h>
int main()
{
    
    
	int i;
    //定义为double型,以得到更多的精度,否则无法容纳求得的结果
	double s=0,m=1;
	for(i=1; i<=20; i++)
	{
    
    
		m*=i;
		s+=m;
	}
    //输出时,用22.15e格式,使数据宽度为22,数字部分中小数位数为15位
	printf("%22.15e\n", s);
	return 0;
}

生兔子(斐波那契数列)

生兔子:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

#include<stdio.h>
int main()
{
    
    
	long int t1,t2;
	t1=t2=1;
	for(int i=1; i<=20; i++)
	{
    
    
		printf("%12ld%12ld", t1, t2);
		if(i%2==0)
		{
    
    
			printf("\n");	
		}
		t1=t1+t2;
		t2=t1+t2;
	} 
	return 0;
}

0-7能组成的奇数个数

tips:第一位只能为1-7;最后一位只能为1,3,5,7;中间位可以为0-8;

 #include<stdio.h>
 
 int main()
 {
    
    
 	//cnt的初始值为4表示:只有一位数字组成的奇数个数为4个
    long total=4,cnt=4;
    int i;
    for(i=2; i<=8; i++)
    {
    
    
    	printf("%d位数为奇数的个数是%ld\n", i-1, cnt);
		if(i<=2)
		{
    
    
			cnt*=7;	
		}
		else
		{
    
    
			cnt*=8;
		}
		total+=cnt;
	} 
	printf("%d位数为奇数的个数是%ld\n", i-1, cnt);
	printf("奇数的总个数是%ld\n", total);
    return 0;
 }

n阶顺时针螺旋方阵

打印用户指定的n阶顺时针螺旋方阵(n<10)

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	int a[10][10];
	int i,j,k=0,m,n;
	scanf("%d", &n);
	//方阵的层数m与方阵的阶数n的关系:m=(n+1)/2
	if(n%2==0)
	{
    
    
		m=n/2;	
	} 
	else
	{
    
    
		m=(n+1)/2;
	}
	for(i=0; i<m; i++)
	{
    
    
		for(j=i; j<n-i; j++)
		{
    
    
			k++;
			a[i][j]=k;
		}
		for(j=i+1; j<n-i; j++)
		{
    
    
			k++;
			a[j][n-i-1]=k;
		}
		for(j=n-i-2; j>=i; j--)
		{
    
    
			k++;
			a[n-i-1][j]=k;
		}
		for(j=n-i-2; j>=i+1; j--)
		{
    
    
			k++;
			a[j][i]=k;
		}
	}
	for(i=0; i<n; i++)
	{
    
    
		for(j=0; j<n; j++)
		{
    
    
			printf("%5d", a[i][j]);
		}
		printf("\n");
	}
	return 0;
}

求一元二次方程的跟

#include<stdio.h>
#include<math.h>

int main(){
    
    
	double a,b,c,x1,x2,disc,realpart,imagpart;
	scanf("%lf%lf%lf", &a, &b, &c);
	//误差小于10^(-6)
	if(fabs(a)<=1e-6)
	{
    
    
		printf("不是一元二次方程\n");
	}
	else
	{
    
    
		disc=b*b-4*a*c;
		//判断判别式是否小于一个很小的数,1e-6=10^(-6)。若小于此数,就认为disc等于0,有两个相等的实根 
		if(fabs(disc)<=1e-6)
		{
    
    
			printf("两个相等的实根:%8.4f\n", -b/(2*a));
		}
		//disc>0,有两个不相等的实根 
		else if(disc>1e-6)
		{
    
    
			x1=(-b+sqrt(disc))/2*a;
			x2=(-b-sqrt(disc))/2*a;
			printf("两个不等的实根:%8.4f and %8.4f\n", x1, x2);
		}
		//disc<0,有两个不相等的共轭复跟 
		else
		{
    
    
			realpart=-b/(2*a);
			imagpart=sqrt(-disc)/(2*a);
			printf("两个不等的共轭复跟:\n");
			printf("%8.4f+%8.4fi\n", realpart, imagpart);
			printf("%8.4f-%8.4fi", realpart, imagpart);
		}
	}
	return 0;
}

指针交换两个变量(2)

输入两个整数,按先大后小的顺序输出这两个数。请用指针来编程

#include<stdio.h>
 
int main()
{
    
    
	int a,b,*p,*q,*r;
	printf("请输入两个整数:\n");
	scanf("%d,%d",&a,&b);
	p=&a;
	q=&b;
	if(a<b)
	{
    
    
		r=p;
		p=q;
		q=r;
	}
	printf("较大数位%d,较小数位%d。\n",*p,*q);
	
	return 0;
} 
#include<stdio.h>
 
int main()
{
    
    
	int a,b,*p,*q,t;
	printf("请输入两个整数:\n");
	scanf("%d,%d",&a,&b);
	p=&a;
	q=&b;
	if(a<b)
	{
    
    
		t=*p;
		*p=*q;
		*q=t;
	}
	printf("较大数位%d,较小数位%d。\n",a,b);
	
	return 0;
}

二维数组逆序输出

#include<stdio.h>

#define M 2
#define N 3

int main()
{
    
    
	void inverse(int a[][N], int b[][N]);
	int a[M][N],b[M][N],i,j;
	for(i=0; i<M; i++)
	{
    
    
		for(j=0; j<N; j++)
		{
    
    
			scanf("%d", &a[i][j]);
		}
	}
	inverse(a,b);
	for(i=0; i<M; i++)
	{
    
    
		for(j=0; j<N; j++)
		{
    
    
			printf("%d\t", b[i][j]);
		}
		//二维数组输出完一行后记得换行
		printf("\n");
	}
    return 0;
}

void inverse(int a[][N], int b[][N])
{
    
    
	int i,j;
	for(i=0; i<M; i++)
	{
    
    
		for(j=0; j<N; j++)
		{
    
    
			b[M-i-1][N-j-1]=a[i][j];
		}
	}
}

一维数组逆序输出(2)

将数组a中n个整数按相反顺序存放,分别用数组名做参数和用指针做参数

方法一:用数组名做参数

#include<stdio.h>

int main()
{
    
    
	void reverse(int a[], int n);
	int a[5]={
    
    3,43,-4,45,5};
	int i;
	reverse(a,5);
	for(i=0; i<5; i++)
	{
    
    
		printf("%d\t", a[i]);
	}
    return 0;
}

void reverse(int a[], int n)
{
    
    
	int i,j,t,middle;
	middle=(n-1)/2;
	for(i=0; i<=middle; i++)
	{
    
    
		j=n-1-i;
		t=a[i];
		a[i]=a[j];
		a[j]=t;
	}
}

方法二:用指针做参数

#include<stdio.h>

int main()
{
    
    
	void reverse(int *a, int n);
	int a[5]={
    
    3,43,-4,45,5};
	int i;
	reverse(a,5);
	for(i=0; i<5; i++)
	{
    
    
		printf("%d\t", a[i]);
	}
    return 0;
}

void reverse(int *a, int n)
{
    
    
	int *i,*j,*p,t,middle;
	middle=(n-1)/2;
	i=a;
	j=n-1+a;
	p=middle+a;
	for( ; i<=p; i++,j--)
	{
    
    
		t=*i;//i指向数组的第一个元素
		*i=*j;//j指向数组的最后一个元素
		*j=t;//p指向中间值
	}
}

一维数组找最值

输入10个数,要求输出其中值最大的元素和该数是第几个数。要求用数组元素做函数实参

#include<stdio.h>
int main()
{
    
    
	int max(int x,int y);
	int a[10],i,m,idx;
	for(i=0; i<10; i++)
	{
    
    
		scanf("%d", &a[i]);
	}
	m=a[0];
	for(i=1; i<10; i++)
	{
    
    
		if(max(m,a[i])>m)
		{
    
    
			m=max(m,a[i]);
			idx=i;
		}
	}
	printf("%d %d\n", m, idx+1);
    return 0;
}

int max(int x,int y)
{
    
    
	return x>y?x:y;
}

二维数组输出值

用指针变量输出输出二维数组元素的值

tips:*(p+i)+j是二维数组i行j列的元素地址,而 *( *(p+i)+j)则是i行j列元素的值

#include<stdio.h>

int main(){
    
    
	int a[3][4]={
    
    1,2,3,4,5,6,7,8,9,10,11,12};
	int (*p)[4];
	int i,j;
	p=a;
	for(i=0;i<3;i++){
    
    
		for(j=0;j<4;j++){
    
    
			printf("%2d  ", *(*(p+i)+j));
		}
	}
	return 0;
}

*二维数组找鞍点

找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列上最小。也可能没有鞍点。

#include<stdio.h>
#define N 4
#define M 5
int main()
{
    
    
	int i,j,k,a[N][M],max,maxj,flag;
	for(i=0; i<N; i++)
	{
    
    
		for(j=0; j<M; j++)
		{
    
    
			scanf("%d", &a[i][j]);
		}
	}
	for(i=0; i<N; i++)
	{
    
    
		max=a[i][0];
		maxj=0;
		//找出第i行中的最大数
		for(j=0; j<M; j++)
		{
    
    
			if(a[i][j]>max)
			{
    
    
				//将本行的最大数存放在max中 
				max=a[i][j];
				maxj=j;	
			}
			flag=1;
			for(k=0; k<N; k++)
			{
    
    
				//将最大数和其同列元素相比 
				if(max>a[k][maxj])
				{
    
    
					flag=0;
					continue;
				}
			}
		}
		if(flag)
		{
    
    
			printf("a[%d][%d]=%d\n", i, maxj, max);
			break;
		}
	}
	if(!flag)
	{
    
    
		printf("It is not exist!\n");
	}
	return 0;
}

大小写字母转换

设计函数实现将一个字符串中小写字母转化为大写字母

#include<stdio.h>
#include<ctype.h>

int main()
{
    
    
	void convert(char *s);
	char s[]="124asdfAJLJAsdj4Nr";
	convert(s);
	puts(s);
	return 0;
}

void convert(char *s)
{
    
    
	while(*s!='\0')
	{
    
    
		if(islower(*s))
		{
    
    
			*s=toupper(*s);
		}
		s++;
	}
}

3个整数求大者

调用函数,求3个整数中的大者

#include<stdio.h>
int main()
{
    
    
    int max();
    extern int a,b,c;
    scanf("%d%d%d", &a, &b, &c);
    printf("max=%d\n", max());
}
int a,b,c;
int max()
{
    
    
    int m;
    m=a>b?a:b;
    if(c>m)
    {
    
    
        m=c;
    }
    return m;
}

统计单词个数

#include<stdio.h>

int main()
{
    
    
    char a[81];
    int w=0,n=0;
    gets(a);
    for(int i=0; a[i]!='\0'; i++)
    {
    
    
        if(a[i]==' ')
        {
    
    
            w=0;
        }
        else if(w==0)
        {
    
    
            w=1;
            n++;
        }
    }
    printf("There are %d words int this line.\n", n);
}

统计数字个数

统计给定数据中0到9数字个数

#include<stdio.h>

int main()
{
    
    
	int i,data[20]={
    
    0,1,2,2,3,3,6,3,8,0,1,1,3,4,5,1,7,8,9,3} ;
	int cnt[10]={
    
    0} ;
	for(i=0; i<20; i++)
	{
    
    
		cnt[data[i]]+=1;
	} 
	for(i=0; i<10; i++){
    
    
		printf("数字%d的个数:%d\n",i,cnt[i]);
	}
	return 0;
}

统计字符个数

有一篇文章,共有3行文字,每行有80个字符。要求分别统计出其中英文大写字母、小写字母、数字、空格以及其它字符的个数

#include<stdio.h>

int main()
{
    
    
	char a[3][80];
	int i,j,Letter=0,letter=0,digital=0,space=0,other=0;
	for(i=0; i<3; i++)
	{
    
    
		gets(a[i]);
		for(j=0; j<80&&a[i][j]!='\0'; j++)
		{
    
    
			if(a[i][j]>='A'&&a[i][j]<='Z')
			{
    
    
				Letter++;
			}
			else if(a[i][j]>='a'&&a[i][j]<='z')
			{
    
    
				letter++;
			}
			else if(a[i][j]>='0'&&a[i][j]<='9')
			{
    
    
				digital++;
			}
			else if(a[i][j]==' ')
			{
    
    
				space++;
			}
			else
			{
    
    
				other++;
			}
		}
	}
	
	printf("Letter=%d\nletter=%d\ndigital=%d\nspace=%d\nother=%d\n", Letter, letter, digital, space, other);
	return 0;
}

删除指定字符

#include<stdio.h>

int main()
{
    
    
	void del_char(char a[],char n);
	char a[80],n;
	gets(a);
	n=getchar();
	del_char(a,n);
	return 0;
}

void del_char(char a[],char n)
{
    
    
	char p[80];
	int i,j;
	for(i=0,j=0; a[i]!='\0'; i++)
	{
    
    
		if(n!=a[i])
		{
    
    
			p[j++]=a[i];
		}
	}
	p[j]='\0';
	puts(p);
}

找最大字符串

有3个字符串,要求找出其中最大者

#include<stdio.h>
#include<string.h>
int main()
{
    
    
    char str[3][20];
    char string[20];
    int i;
    for(i=0; i<3; i++)
    {
    
    
        gets(str[i]);
    }
    if(strcmp(str[0],str[1])>0)
    {
    
    
        strcpy(string,str[0]);
    }
    else
    {
    
    
        strcpy(string,str[1]);
    }
    if(strcmp(str[2],string)>0)
    {
    
    
        strcpy(string,str[2]);
    }
    printf("\nthe largest string is:%s\n", string);
    return 0;
}

求pi的近似值

用pi/4=1-1/3+1/5-1/7+…公式求pi的近似值,知道发现某一项的绝对值小于1e-6为止(该项不累加)。

#include<stdio.h>
#include<math.h>
int main()
{
    
    
    int sign=1;
    double pi=0.0,n=1.0,term=1.0;
    while(fabs(term)>=1e-6)
    {
    
    
        pi+=term;
        n+=2;
        sign=-sign;
        term=sign/n;
    }
    printf("pi=%10.8f\n", pi*4);
    return 0;
}

字符串复制(5)

tips:将字符串中从第m个字符开始的n个字符复制到另一个字符串

  • 对gets()和puts()的使用
  • gets()函数用来从标准输入设备(键盘)读取字符串直到换行符结束,但换行符会被丢弃然后在末尾添加’\0’字符
  • puts()输出字符串时遇到’\0’(即:字符结束符)才停止;并且自动在字符串末尾添加一个换行符
#include<stdio.h>

int main()
{
    
    
	char a[100],b[100];
	int m,n,i;
	gets(a);
	scanf("%d %d", &m, &n);
    //i从0开始加并且条件是小于要复制的个数(即i<n),因为放入新数组后,下标从零开始
    //好像是废话,因为数组下标本来就是从0开始哈哈哈
	for(i=0; i<n; i++)
    {
    
    
        //如果不好理解,可以代数进去
		b[i]=a[m+i-1];
	}
	printf("%s\n", b);
	return 0;
}

将字符串a复制为字符串b

方法一:下标法

#include<stdio.h>

int main(){
    
    
	char a[]="I am a student!",b[100];
    int i;
	// *(a+1) 相当于 a[i] 同理:*(b+i) 相当于 b[i]
	for(i=0; *(a+i)!='\0'; i++)
	{
    
    
		*(b+i)=*(a+i);
	}
	*(b+i)='\0';
	printf("%s\n", a);
	//可直接用 puts(b) 输出在字符数组,或者用格式字符串 %s 
	for(i=0; b[i]!='\0'; i++)
	{
    
    
		printf("%c", b[i]);
	}
	return 0;
}

方法二:指针法

#include<stdio.h>

int main(){
    
    
	char a[]="I am a student!",b[100],*p1,*p2;
	for(p1=a,p2=b; *p1!='\0'; p1++,p2++)
	{
    
    
		*p2=*p1;
	}
	*p2='\0';
	printf("string a is:%s\n", a);
	printf("string b is:%s\n", b);
	return 0;
}

用函数调用实现字符串的复制(用字符数组做参数;形参用字符指针变量)

方法一:形参用字符数组做参数

#include<stdio.h>

int main()
{
    
    
	void copy_string(char a[], char b[]);
	char a[100]="I am a student!",b[100];
	copy_string(a,b);
	puts(a);
	puts(b);
	return 0;	
} 

void copy_string(char a[], char b[])
{
    
    
	int i;
	for(i=0; a[i]!='\0'; i++)
	{
    
    
		b[i]=a[i];
	}
	b[i]='\0';
}

方法二:形参用指针参数

#include<stdio.h>

int main()
{
    
    
	void copy_string(char a[], char b[]);
	char *a="I am a student!",b[100];
	copy_string(a,b);
	puts(a);
	puts(b);
	return 0;	
} 

void copy_string(char *a, char *b)
{
    
    
	for( ; *a!='\0'; a++,b++)
	{
    
    
		*b=*a;
	}
	*b='\0';
}

字符串逆序

#include<stdio.h>
#include<string.h>

int main()
{
    
    
    //中间变量 t 就是一个交换器
	char a[100],t;
	int i,j,k;
	scanf("%s", &a);
	k=strlen(a);
    //看到这个for语句不要懵,注意`;`即可
	for(i=0,j=k-1; i<k/2; i++,j--)
    {
    
    
		t=a[i];
		a[i]=a[j];
		a[j]=t;
	}
	printf("%s\n", a);
	return 0;
}

字符串插入

从键盘输入一个字符串a,并在串中的最大元素后边插入另外输入的字符串b

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	char a[100],b[]="@#@",max;
	int i=0,j;
	gets(a);
	max=a[i];
	for(i=0; a[i]!='\0'; i++)
	{
    
    
		if(max<a[i])
		{
    
    
			max=a[i];
			j=i;
		}
	}
	i=strlen(a)+strlen(b)-1;
	for( ; i>j; i--)
	{
    
    
		a[i]=a[i-strlen(b)];
	}
	j=0;
	i++;
	while(b[j]!='\0')
	{
    
    
		a[i]=b[j];
		printf("%c\n", a[i]);
		i++;
		j++;
	}
	puts(a);
	return 0;
}

字符串比较

比较两个字符串,若s1>s2,输出一个正数;若s1=s2,输出0;若s1<s2,输出一个复数,输出的值是两个字符串相应字符的ASCII码的差值。

#include<stdio.h>
int main()
{
    
    
    char s1[80],s2[80];
    gets(s1);
    gets(s2);
    int i=0,rel;
    while(s1[i]==s2[i]&&s1[i]!='\0')
    {
    
    
    	i++;
	}
	if(s1[i]=='\0'&&s2[i]=='\0')
	{
    
    
		rel=0;
	}
	else
	{
    
    
		rel=s1[i]-s2[i];
	}
	printf("%d\n", rel);
    return 0;
}

从键盘输入两个字符串a和b,要求不用库函数strcat把字符串b的前五个字符连接到字符串a中;如果b的长度小于5,则把b的所有元素都连接到a中

#include<stdio.h>

int main()
{
    
    
	char a[100],b[100];
	int i=0,j;
	gets(a);
	gets(b);
	while(a[i]!='\0')
	{
    
    
		i++;
	}
	for(j=0; j<5&&b[j]!='\0'; j++)
	{
    
    
		a[i++]=b[j];
	}
	a[i]='\0';
	puts(a);
	return 0;
}

九九乘法表

#include<stdio.h>

int main()
{
    
    
    int i,j;
    for(i=1; i<=9; i++)
    {
    
    
    	for(j=1; j<=i; j++)
    	{
    
    
    		printf("%dx%d=%-3d ", j, i, i*j);
		}
		printf("\n");
	}
	return 0;
}

杨辉三角形

#include <stdio.h>
#define N 10 
int main()
{
    
    
	int a[N][N], i, j;
	for(i=0; i<N; i++)
	{
    
    
		//列必须小于等于行 ,否则换行
		for(j=0; j<=i; j++)
		{
    
    
			//第零列、行列相等(也就是两条斜边)值为1 
			if(i==j || j==0)
			{
    
    
				a[i][j]=1;
			}
			else
			{
    
    
				//前一行、前一列 + 前一行、同一列 
				a[i][j]=a[i-1][j-1]+a[i-1][j];
			}
			printf("%6d", a[i][j]);
		}
		printf("\n");
	}
	return 0;	
}

折半查找法

从键盘输入一个整数,用折半查找法找出该数在10个有序整型数组a中的位置。若该数不在a中,则打印出相应信息

#include<stdio.h>

int main()
{
    
    
	int a[10]={
    
    1,3,5,7,9,11,13,15,17,19},n;
    int low=0,high=9,mid;
	scanf("%d", &n);
	while(low<=high)
	{
    
    
		mid=(low+high)/2;
		if(n==a[mid])
		{
    
    
			break;
		}
		else if(n>a[mid])
		{
    
    
			low=mid+1;
		}
		else
		{
    
    
			high=mid-1;
		}
	}
	if(low<=high)
	{
    
    
		printf("Found! position is %d\n", mid);
	}
	else
	{
    
    
		printf("Not found %d\n", n);
	}
	return 0;
}

百钱买百鸡

鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一,百钱买百鸡。问鸡翁、母、雏各几何?输出所有买法,每一种鸡至少要一只

#include <stdio.h>

int main( )                      
{
    
     
    int roo,hen,chick;
    for(roo=1; roo<20; roo++)
    {
    
    
    	for(hen=1; hen<33; hen++)
    	{
    
    
    		chick=100-roo-hen;
    		if(roo*5+hen*3+chick/3==100)
    		{
    
    
    			printf("roo=%d, hen=%d, chick=%d\n", roo, hen, chick);
			}
		}
	}
	return 0;	
}

最大公约数

#include<stdio.h>
int main()
{
    
    
	int m,n,t,r,p=0;
	scanf("%d%d", &m, &n);
	p=m*n;
	if(m>n)
	{
    
    
		t=m;
		m=n;
		n=t;
	}
	while(n!=0)
	{
    
    
		r=m%n;
		m=n;
		n=r;
	}
	printf("%d %d", m, p/m);
	return 0;
}

乒乓球比赛

两个乒乓球队进行比赛,各出3人。甲队为A,B,C3人,乙队为X,Y,Z3人。已知A不和X比,C不和X,Z比,请编程找出3对赛手的名单

#include <stdio.h>
int main()
{
    
    
    char i,j,k;
    for(i='X'; i<='Z'; i++)
    {
    
    
    	for(j='X'; j<='Z'; j++)
    	{
    
    
    		if(i!=j)
    		{
    
    
    			for(k='X'; k<='Z'; k++)
    			{
    
    
    				if(k!=i&&k!=j)
    				{
    
    
    					if(i!='X'&&k!='X'&&k!='Z')
    					{
    
    
    						printf("A---%c\nB---%c\nC---%c\n", i, j, k);
						}
					}
				}
			}
		}
	}
    return 0;
}

判断第几天

给出年、月、日,计算该日是该年的第几天

#include<stdio.h>
int main()
{
    
    
    int sum_day(int month,int day);
    int leap(int year);
    int year,month,day,days=0;
    scanf("%d-%d-%d", &year, &month, &day);
    days=sum_day(month,day);
    if(leap(year)&&month>=3)
    {
    
    
        days+=1;
	}
    printf("%d\n", days);
    return 0;
}
int sum_day(int month,int day)
{
    
    
    int day_tab[13]={
    
    0,31,28,31,30,31,30,31,31,30,31,30,31};
    for(int i=1; i<month; i++)
    {
    
    
        day+=day_tab[i];
	}
    return day;
}
int leap(int year)
{
    
    
    int leap=(year%4==0&&year%100!=0)||year%400==0;
    return leap;
}

插入排序

#include<stdio.h>
int main()
{
    
    
    int a[11]={
    
    2,12,13,22,49,58,132,144,194,920};
    int i,j,t1,t2,n;
    scanf("%d", &n);
    int len=sizeof(a)/sizeof(a[0]);
    if(n>=a[9])
    {
    
    
    	a[10]=n;
	}
	else
	{
    
    
		for(i=0; i<len-1; i++)
		{
    
    
			if(n<a[i])
			{
    
    
				t1=a[i];
				a[i]=n;
				for(j=i+1; j<len; j++)
				{
    
    
					t2=a[j];
					a[j]=t1;
					t1=t2;
				}
				break;
			}
		}
	}
	for(i=0; i<len; i++)
	{
    
    
		printf("%5d", a[i]);
	} 
    return 0;
}

冒泡排序

#include<stdio.h>

int main()
{
    
    
	int a[10]={
    
    2,12,43,-222,49,58,232,4,-594,90};
    int i,j,t;
    int len=sizeof(a)/sizeof(a[0]);
	for(i=0; i<len-1; i++)
	{
    
    
		for(j=0; j<len-1-i; j++)
		{
    
    
			if(a[j]>a[j+1])
			{
    
    
				t=a[j];
				a[j]=a[j+1];
				a[j+1]=t;
			}
		}
	}
	for(i=0; i<len; i++)
	{
    
    
		printf("%5d", a[i]);
	}
    return 0;
}

选择排序

#include<stdio.h>

int main()
{
    
    
	int a[10]={
    
    2,12,43,-222,49,58,232,4,-594,90};
	int min,t,i,j;
	int len=sizeof(a)/sizeof(a[0]);
	for(i=0; i<len-1; i++)
	{
    
    
		min=i;
		for(j=i+1; j<len; j++)
		{
    
    
			if(a[min]>a[j])
			{
    
    
				min=j;
			}
		}
		t=a[i];
		a[i]=a[min];
		a[min]=t;
	}
	for(i=0; i<len; i++)
	{
    
    
		printf("%5d", a[i]);
	}
	return 0;
}

水仙花数

#include<stdio.h>
int main()
{
    
    
	int a,b,c;
	for(int i=100; i<=999; i++)
	{
    
    
		a=i/100;
		b=i/10%10;
		c=i%10;
		if(i==a*a*a+b*b*b+c*c*c)
		{
    
    
			printf("%d\n", i);
		}
	}
	return 0;
}

逆序输出(2)

逆序输出:你的程序会读入一系列的正整数,预先不知道正整数的数量,一旦读到-1,就表示输入结束。然后,按照输入相反的顺序输出所读到数字,不包括最后标识结束的-1

#include<stdio.h>

int main(){
    
    
	int n,i,a[10];
	for(i=0; ; )
	{
    
    
		scanf("%d", &n);
		if(n==-1)
		{
    
    
			break;
		}
		a[i++]=n;
	}
	for(i=i-1; i>=0; i--)
	{
    
    
		printf("%d\t", a[i]);
	}
	return 0;
}

逆序的三位数:

#include<stdio.h>

int main(){
    
    
	int n,a,b,c;
	scanf("%d", &n);
	a=n/100;
	b=n/10%10;
	c=n%10;
	n=c*100+b*10+a;
	printf("%d", n);
	return 0;
} 

数列求和

有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13…求出这个数列的前20项之和

#include<stdio.h>
int main()
{
    
    
    int i;
    double s=0,a=2,b=1,t;
    for(i=1; i<=20; i++)
    {
    
    
    	s+=a/b;
    	t=a;
    	a=a+b;
    	b=t;
	}
	printf("%16.10f\n", s);
    return 0;
}

打印图形

    *
   ***
  *****
 *******
  *****
   ***
    *
#include <stdio.h>
#include<math.h>

int main()
{
    
    
    int i,j,k;
    for(i=1; i<=4; i++)
    {
    
    
    	for(j=1; j<=5-i; j++)
    	{
    
    
    		printf(" ");
		}
		for(k=1; k<=2*i-1; k++)
		{
    
    
			printf("*");
		}
		printf("\n");
	}
	for(i=1; i<=3; i++)
	{
    
    
		for(j=1; j<=i+1; j++)
		{
    
    
			printf(" ");
		}
		for(k=1; k<=7-2*i; k++)
		{
    
    
			printf("*");
		}
		printf("\n");
	}
    return 0;
}
* * * * *
  * * * * *
    * * * * *
      * * * * *
        * * * * *
#include <stdio.h>
#include<math.h>

int main()
{
    
    
    int i,j,k;
    for(i=0; i<5; i++)
    {
    
    
    	for(j=1; j<=i; j++)
    	{
    
    
    		printf("  ");
		}
		for(k=0; k<5; k++)
		{
    
    
			printf("* ");
		}
		printf("\n");
	}
    return 0;
}

电文密码(2)

有一行电文,已按下面规律译成密码:A=>Z,B=>Y,C=>X… a=>z,b=>y,c=>x… 即将第一个字母变成第26个字母,第i个字母变成第(26-i+1)个字母,非字母字符不变。编程将密码译回原文,并输出密码和原文

#include<stdio.h>
int main()
{
    
    
    char a[81];
    int i;
    gets(a);
    for(i=0; a[i]!='\0'; i++)
    {
    
    
    	if(a[i]>='A'&&a[i]<='Z')
    	{
    
    
    		//第i个字母:26-i+1 => 26-(a[i]-64)+1 => 91-a[i]
    		//该字母的ASCII码:91-a[i]+64 => 115-a[i] 
    		a[i]=155-a[i];
		}
		else if(a[i]>='a'&&a[i]<='z')
		{
    
    
			//第i个字母:26-i+1 => 26-(a[i]-96)+1 => 123-a[i]
			//该字母的ASCII码:123-a[i]+96 => 219-a[i] 
			a[i]=219-a[i];
		}
	}
	puts(a);
    return 0;
}

将字母A变成字母E,a变成e,即变成其后的第4个字母,W变成A,X变成B,Y变成C,Z变成D。如“China!”转换为“Glmre!”。

#include<stdio.h>
int main()
{
    
    
	char c;
	while((c=getchar())!='\0')
	{
    
    
		if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))
		{
    
    
			if((c>='w'&&c<='z')||(c>='W'&&c<='Z'))
			{
    
    
				c=c+4-26;
			}
			else
			{
    
    
				c=c+4;
			}
		}
		printf("%c", c);
	}
    return 0;
}

自由落体

一个球从100m高度自由落下,每次落地后反跳回原高度的一半,再落下,再反弹。求它在第10次落地时,共经过多少米,第10次反弹多高。

#include<stdio.h>
int main()
{
    
    
	double sn=100,hn=sn/2;
	int n;
	for(n=2; n<=10; n++)
	{
    
    
		sn+=2*hn;
		hn/=2;
	}
	printf("第10次落地时共经过%f米\n", sn);
	printf("第10次反弹%f米\n", hn);
    return 0;
}

猴子吃桃

猴子第1天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上就只剩一个了。求第1天共摘了多少个桃子。

#include<stdio.h>
int main()
{
    
    
	int day,x1,x2;
    day=9;
    x2=1;
    while(day>0)
    {
    
    
        x1=(x2+1)*2;
        x2=x1;
        day--;
    }
    printf("total=%d\n", x1);
}

递归求n!

#include <stdio.h>
int main()
{
    
    
	int f(int n);
	int n;
	scanf("%d", &n);
	printf("%d!=%d\n", n, f(n));
    return 0;
}

int f(int n)
{
    
    
	int x;
	if(n<0)
	{
    
    
		printf("n<0,data error!");
	}
	else if(n==0||n==1)
	{
    
    
		x=1;
	}
	else
	{
    
    
		x=f(n-1)*n;
	}
	return x;
}

学生年龄

有5个学生坐在一起,第1个学生10岁,第2个学生比第1个学生大2岁,第3个学生比第2个学生大2岁…依次类推,第5个学生比第4个大2岁,求第5个学生的年龄。

#include <stdio.h>
int main()
{
    
    
	int age(int n);
	printf("%d\n", age(5));
    return 0;
}

int age(int n)
{
    
    
	int c;
	if(n==1)
	{
    
    
		c=10;
	}
	else
	{
    
    
		c=age(n-1)+2;
	}
	return c;
}

数字空格

写一个函数,输入一个4位数字,要求输出这4个数字字符,但每两个数字间空一个空格。如输入1990,应输出"1 9 9 0"。

#include<stdio.h>
#include<string.h>
int main()
{
    
    
    void insert(char arr[]);
    char str[80];
    printf("input four digits:");
    gets(str);
    insert(str);
    return 0;
}

void insert(char arr[])
{
    
    
    for(int i=strlen(arr); i>0; i--)
    {
    
    
        arr[2*i]=arr[i];
        arr[2*i-1]=' ';
    }
    puts(arr);
}

数组逆序(2)

将数组a中n个整数按相反的顺序存放

#include<stdio.h>
int main()
{
    
    
	void fun(int a[],int n);
    int a[10]={
    
    10,20,30,40,50,60,70,80,90,100};
    printf("original:\n");
    for(int i=0; i<10; i++)
    {
    
    
    	printf("%5d", a[i]);
	}
	fun(a,10);
    printf("\noriginal:\n");
    for(int i=0; i<10; i++)
    {
    
    
    	printf("%5d", a[i]);
	}
    return 0;
}
void fun(int a[],int n)
{
    
    
	int i,j,t,m=(n-1)/2;
	for(i=0; i<=m; i++)
	{
    
    
		j=n-1-i;
		int t=a[i];
		a[i]=a[j];
		a[j]=t;
	}
}

用指针

#include<stdio.h>
int main()
{
    
    
	void fun(int a[],int n);
    int a[10]={
    
    10,20,30,40,50,60,70,80,90,100};
    printf("original:\n");
    for(int i=0; i<10; i++)
    {
    
    
    	printf("%5d", a[i]);
	}
	fun(a,10);
    printf("\noriginal:\n");
    for(int i=0; i<10; i++)
    {
    
    
    	printf("%5d", a[i]);
	}
    return 0;
}
void fun(int a[],int n)
{
    
    
	int *p,*i,*j,t,m=(n-1)/2;
	i=a;
	j=n-1+a;
	p=a+m;
	for( ; i<=p; i++,j--)
	{
    
    
		t=*i;
		*i=*j;
		*j=t;
	}
}

*最长单词

写一个函数,输入一行字符,将此字符串中最长的单词输出

#include<stdio.h>
#include<string.h>

int main()
{
    
    
	int alphabetic(char);
	int longest(char []);
	int i;
	char line[100];
	printf("input one line:\n");
	gets(line);
	printf("The longest word is:");
	for(i=longest(line); alphabetic(line[i]); i++)
	{
    
    
		printf("%c", line[i]);
	}
    return 0;
}

int alphabetic(char c)
{
    
    
	if((c>='a'&&c<='z')||(c>='A'&&c<='Z'))
	{
    
    
		return 1;
	}
	else
	{
    
    
		return 0;
	}
}

int longest(char string[])
{
    
    
	int len=0,i,length=0,flag=1,place=0,point;
	for(i=0; i<=strlen(string); i++)
	{
    
    
		if(alphabetic(string[i]))
		{
    
    
			if(flag)
			{
    
    
				//point 表示当前单词的起始位置(用下标表示) 
				point=i;
				//flag=1 表示单词开始,等于0表示未开始 
				flag=0;
			}
			else
			{
    
    
				//len 表示当前单词已累计的字母个数 
				len++;
			}
		}
		else
		{
    
    
			flag=1;
			if(len>=length)
			{
    
    
				//length 表示先前单词中最长单词的长度
				//place 表示最长单词的起始位置 
				length=len;
				place=point;
				len=0;
			}
		}
	}
	return place;
}

*二分法

用二分法求下面方程在(-10,10)之间的跟:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0MhjuBRO-1622860361151)(file://D:\Study\blogImg\image-20210526154956234.png?lastModify=1622017241)]

#include<stdio.h>
#include<math.h>
int main()
{
    
    
    float x0,x1,x2,fx0,fx1,fx2;
    do
    {
    
    
    	printf("enter x1 & x2:");
    	scanf("%f%f", &x1, &x2);
    	fx1=x1*((2*x1-4)*x1+3)-6;
    	fx2=x2*((2*x2-4)*x2+3)-6;
	}while(fx1*fx2>0);
	do
	{
    
    
		x0=(x1+x2)/2;
		fx0=x0*((2*x0-4)*x0+3)-6;
		if(fx0*fx1<0)
		{
    
    
			x2=x0;
			fx2=fx0;
		}
		else
		{
    
    
			x1=x0;
			fx1=fx0;
		}
	}while(fabs(fx0)>=1e-5);
	printf("x=%6.2f\n", x0);
    return 0;
}

*魔方阵

#include<stdio.h>

int main()
{
    
    
	int a[20][20]={
    
    0},n,i,j,k;
	scanf("%d", &n);
    //1放在第一行中间一列
	j=n/2+1;
	a[1][j]=1;
	i=1;
	for(k=2; k<=n*n; k++)
	{
    
    
        //从2开始直到n*n止,各数依次按下列规则存放:
        //每一个数存放的行比前一个数的行数减1,列数加1
		i=i-1;
		j=j+1;
		if(i<1&&j>n)
		{
    
    
			i=i+2;
			j=j-1;
		}
		else
		{
    
    
            //如果上一数的行数为1,则下一个数的行数为n(指最下一行)
			if(i<1)
			{
    
    
				i=n;
			}
            //当上一个数的列数为n时,下一个数的列数应为1
			if(j>n)
			{
    
    
				j=1;
			}
		}
		if(a[i][j]==0)
		{
    
    
			a[i][j]=k;
		}
		else
		{
    
    
			i=i+2;
			j=j-1;
			a[i][j]=k;
		}
	}
	for(i=1; i<=n; i++)
	{
    
    
		for(j=1; j<=n; j++)
		{
    
    
			printf("%5d", a[i][j]);
		}
		printf("\n");
	}
	return 0;
}

*迭代法(3)

用迭代法求x=sqrt(a)。求平方根的迭代公式为

在这里插入图片描述

要求前后两次求出的x的差的绝对值小于1e-5。

#include<stdio.h>
#include<math.h>
int main()
{
    
    
    float a,x0,x1;
    scanf("%f", &a);
    x0=a/2;
    x1=(x0+a/x0)/2;
    do
    {
    
    
        x0=x1;
        x1=(x0+a/x0)/2;
    }while(fabs(x0-x1)>=1e-5);
    printf("The square root of %5.2f is %8.5f\n", a, x1);
    return 0;
}

用牛顿迭代法求下面方程在1.5附近的根:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1KdyseH2-1622860361156)(D:/Study/blogImg/image-20210526154956234.png)]

牛顿迭代公式为:

在这里插入图片描述

#include<stdio.h>
#include<math.h>
int main()
{
    
    
    double x1,x0,f,f1;
    x1=1.5;
    do
    {
    
    
        x0=x1;
        f=((2*x0-4)*x0+3)*x0-6;
        f1=(6*x0-8)*x0+3;
        x1=x0-f/f1;
    }while(fabs(x0-x1)>=1e-5);
    printf("The root of equation is %5.2f\n", x1);
    return 0;
}

用牛顿迭代法求根。方程为

在这里插入图片描述

,系数a,b,c,d的值依次为1,2,3,4,由主函数输入。求x在1附近的一个实根。求出根后由主函数输出。

#include<stdio.h>
#include<math.h>
int main()
{
    
    
    float solut(float a,float b,float c,float d);
    float a,b,c,d;
    scanf("%f%f%f%f", &a, &b, &c, &d);
    printf("x=%10.7f\n", solut(a,b,c,d));
    return 0;
}
float solut(float a,float b,float c,float d)
{
    
    
    float x=1,x0,f,f1;
    do
    {
    
    
        x0=x;
        f=x0*((a*x0+b)*x0+c)+d;
        f1=x0*(3*a*x0+2*b)+c;
        x=x0-f/f1;
    }while(fabs(x-x0)>=1e-3);
    return x;
}

*n阶勒让德多项式

#include<stdio.h>
#include<math.h>
int main()
{
    
    
	float p(int n,int x);
	int n,x;
	scanf("%d%d", &n, &x);
	printf("n=%d,x=%d\n", n, x);
	printf("P%d(%d)=%6.2f\n", n, x, p(n,x));
	return 0;
}

float p(int n,int x)
{
    
    
	if(n==0)
	{
    
    
		return 1;
	}
	else if(n==1)
	{
    
    
		return x;
	}
	else
	{
    
    
		return (2*n-1)*x*p(n-1,x)-(n-1)*p(n-2,x)/n;
	}
}

汉诺塔

#include<stdio.h>
int main()
{
    
    
	void hanoi(int n,char one,char two,char three);
	int m;
	scanf("%d", &m);
	hanoi(m,'A','B','C'); 
    return 0;
}

void hanoi(int n,char one,char two,char three)
{
    
    
	void move(char x,char y);
	if(n==1)
	{
    
    
		move(one,three);
	}
	else
	{
    
    
		hanoi(n-1,one,three,two);
		move(one,three);
		hanoi(n-1,two,one,three);
	}
}

void move(char x,char y)
{
    
    
	printf("%c-->%c\n", x, y);
}

回文数(2)

方法一:

#include<stdio.h>
#include<string.h>

int main( )                      
{
    
     
    char a[100];
    int i,j;
    gets(a);
    j=strlen(a)-1;
    for(i=0; i<j; i++,j--)
    {
    
    
    	if(a[i]!=a[j])
    	{
    
    
    		break;
		}
	}
	if(i>=j)
	{
    
    
		printf("该字符串是回文\n");
	}
	else
	{
    
    
		printf("不是\n");
	}
	return 0;	
}

方法二:使用指针

#include<stdio.h>
#include<string.h>

int main( )                      
{
    
     
    char a[100],*p1,*p2; 
    gets(a);
    p1=a;
    p2=a+strlen(a)-1;
    for( ; p1<p2; p1++,p2--)
    {
    
    
    	if(*p1!=*p2)
    	{
    
    
    		break;
		}
	}
	if(p1>=p2)
	{
    
    
		printf("该字符串是回文\n");
	}
	else
	{
    
    
		printf("不是\n");
	}
	return 0;	
}

完数

输出1000以内的完数

#include<stdio.h>
int main()
{
    
    
    int i,j,s;
    for(i=2; i<1000; i++)
    {
    
    
        s=0;
        for(j=1; j<i; j++)
        {
    
    
            if(i%j==0)
            {
    
    
                s+=j;
            }
        }
        if(i==s)
        {
    
    
            printf("%d, its factors are ", i);
            for(j=1; j<i; j++)
            {
    
    
                if(i%j==0)
                {
    
    
                    printf("%d ", j);
                }
            }
            printf("\n");
        }
    }
    return 0;
}

素数(4)

输入一个大于3的整数n,判定它是否为素数(prime,又称质数)

#include<stdio.h>
int main()
{
    
    
    int n,i;
    scanf("%d", &n);
    for(i=2; i<=n-1; i++)
    {
    
    
        if(n%i==0)
        {
    
    
            break;
        }
    }
    //如果n能被2~(n-1)之间的一个整数整除,则必然是由break语句导致循环提前结束
    //即i并未达到n的值,循环就终止了
    if(i<n)
    {
    
    
        printf("%d is not a prime.\n", n);
    }
    else
    {
    
    
        printf("%d is a prime.\n", n);
    }
}
#include<stdio.h>
#include<math.h>
int main()
{
    
    
    int n,i;
    scanf("%d", &n);
    int k=sqrt(n);
    for(i=2; i<=k; i++)
    {
    
    
        if(n%i==0)
        {
    
    
            break;
        }
    }
    //如果n不能被2~k之间的任一整数整除,则在完成最后一次循环后,i还要加1
    if(i<=k)
    {
    
    
        printf("%d is not a prime.\n", n);
    }
    else
    {
    
    
        printf("%d is a prime.\n", n);
    }
}

求100~200间的全部素数

#include<stdio.h>
#include<math.h>
int main()
{
    
    
    int n,i,k,m=0;
    for(n=101; n<=200; n+=2)
    {
    
    
    	k=sqrt(n);
    	for(i=2; i<=k; i++)
    	{
    
    
    		if(n%i==0)
    		{
    
    
    			break;
			}
		}
		//若i>=k+1,表示n未曾被整除 
		if(i>=k+1)
		{
    
    
			printf("%5d", n);
			m++;
		}
		if(m%10==0)
		{
    
    
			printf("\n");
		}
	}
    return 0;
}

用删选法求100之内的素数

#include<stdio.h>
#include<math.h>

int main()
{
    
    
	int a[101];
	int i,j,n;
	for(i=1; i<101; i++)
	{
    
    
		a[i]=i;	
	}
	a[1]=0;//先将1挖掉,因为1不是素数 
	for(i=2; i<sqrt(100); i++)
	{
    
    
		for(j=i+1; j<=100; j++)
		{
    
    
			if(a[i]!=0&&a[j]!=0)
			{
    
    
				if(a[j]%a[i]==0)
				{
    
    
					a[j]=0;
				}
			}
		}
	}
	printf("\n");
	for(i=2,n=0; i<=100; i++)
	{
    
    
		if(a[i]!=0)
		{
    
    
			printf("%5d", a[i]);
			n++;
		}
		if(n==10)
		{
    
    
			printf("\n");
			n=0;
		}
	}
	printf("\n");
	return 0;
} 

递归

计算e=1 + 1/1! + 1/2! + 1/3! +…+1/n! 的值并输出 (设n=20)

#include<stdio.h>

int main()
{
    
    
	long f(int n);
	double s=1.0;
	for(int i=1; i<=20; i++)
	{
    
    
		s+=1.0/f(i);
	}
	printf("%f\n", s);
	return 0;
}

long f(int n)
{
    
    
	if(n==1)
	{
    
    
		return 1;
	}
	else
	{
    
    
		return n*f(n-1);
	}
}

指针变量与一维数组

一个整型数组里的5个元素由键盘输入,将每个元素变为原来的两倍后再依次输出。请用指针来编程

tips:

  • 指针+i=&数组名[某数+i](一维数组特别的性质)
  • 指针=&数组名[某数]
  • *指针=指针指定的变量的值
  • &数组名[某数] 相当于 数组名+某数 比如:(p=&a[0]可以改为p=a+0)
  • 数组名[某数] 相当于* (数组名+某数) 比如:(a[i]=a[i]* 2可以改为* (a+i)=* (a+i)*2)
#include<stdio.h>

int main()
{
    
    
	int i,a[5],*p;
	p=&a[0];//p=a+0
	for(i=0; i<5; i++)
	{
    
    
		scanf("%d", p+i);//&a[i]
		*(p+i)=*(p+i)*2;//a[i]=a[i]*2
	}
	for(i=0; i<5; i++)
	{
    
    
		printf("%d\t", *(p+i));//a[i]
	}
	return 0;
}

指针变量与一维数组相关函数

有两个小组,分别有 5 名学生和 10 名学生。请编程输入这些学生的成绩,并调用一个 aver 函数求这两个小组的平均分(要求形参和实参都是用指针变量

tips:

  • 函数声明:数组名[] 改成 *p
  • 函数解释:数组名[i] 改成 *(p+i)
  • 函数使用:数组名 改成 q(使用前需先关联)
#include<stdio.h>

int main()
{
    
    
	float avg(float *p, int n);//函数声明 a[]改成*p
	float a[5],b[10],*q1,*q2;
	int i;
	//使用前先关联 
	q1=&a[0];
	q2=&b[0];
	for(i=0; i<5; i++)
	{
    
    
		scanf("%f", &a[i]);
	}
	printf("\n");
	for(i=0; i<10; i++)
	{
    
    
		scanf("%f", &b[i]);
	}
	printf("\n");
	printf("第一组成绩:%f\n", avg(q1,5));//函数使用 a改成q1
	printf("第二组成绩:%f\n", avg(q2,10));//函数使用 b改成q2 
	return 0;
}

float avg(float *p, int n)//函数定义 a[]改成*p
{
    
    
	//函数解释 
	float sum=0;
	for(int i=0; i<n; i++)
	{
    
    
		sum+=*(p+i);//a[i]改成*(p+i)
	}
	return sum/n;
}

指针变量与二维数组

已知整型二维数组a[3] [4]={1,2,3,4,5,6,6,5,4,3,2,1}。请用指针变量输出二维数组各个元素的值

tips:

  • 指针+i=&(数组名[数a] [数b]后面第i个元素)(二维数组特别的性质)
  • 指针=&数组名[数a] [数b]
  • *指针=指针指定的变量的值
  • &数组名[数a] [数b] 相当于 数组名[数a]+数b 也相当于 数组名[0]+a*列数+b
  • 数组名[数a] [数b] 相当于 *(数组名[数a]+数b)

比如&a[0] [0]可以写成a[0]+0,0省略后就是a[0];&a[2] [3]可以写成a[0]+2*4+3(二维数组有4列),运算一下后半部分,结果就是a[0]+11

#include<stdio.h>

int main()
{
    
    
	int a[3][4]={
    
    1,2,3,4,5,6,6,5,4,3,2,1},*p;
	for(p=&a[0][0]; p<=&a[2][3]; p++)
	{
    
    
		if((p-&a[0][0])%4==0)
		{
    
    
			printf("\n");
		}
		printf("%d\t", *p);
	}
	return 0;
}

指针变量与二维数组相关函数

1:有3名学生学习4门课,学生一的成绩分别是65,67,70,60。学生二的成绩分别是80,87,90,81。学生三的成绩分别是90,99,93,98。将上述成绩输入二维数组,并通过函数输出三人的总平均分

方法一(形参实参都是数组名):

#include<stdio.h>

int main()
{
    
    
	float shuchu(float a[][4], int n);
	float fenshu[3][4]={
    
    65,67,70,60,80,87,90,81,90,99,93,98};
	shuchu(fenshu,12);
	return 0;
}

float shuchu(float a[][4], int n)
{
    
    
	float sum=0;
	int i,j;
	for(i=0; i<3; i++)
	{
    
    
		for(j=0; j<4; j++)
		{
    
    
			sum+=a[i][j];
		}
	}
	printf("三人的总平均分为:%f\n", sum/n);
}

方法二(形参是指针变量,实参是数组名):

tips:

  • 函数声明:数组名[] [某数] 改成 *p
  • 函数解释:数组名[i] [j] 改成 * (p+i*列数+j)
  • 函数使用:数组名 改成 *数组名
#include<stdio.h>
 
int main()
{
    
    
	void shuchu(float *p,int n);
	float fenshu[3][4]={
    
    65,67,70,60,80,87,90,81,90,99,93,98};
	shuchu(*fenshu,12);
	
	return 0;
}
 
void shuchu(float *p,int n)
{
    
    
	float sum=0;
	int i;
	//使用指针的时候,原先的双循环是没有必要的,原先双循环的意思就是从0加到11。
	//因为原来是二维数组,所以又得捣腾行又得捣腾列 ,所以用了双重for循环。
	//而当我们转换成为指针的时候,指针是不管行和列的,它就是排着往后加,所以用一个循环语句就够了。 
	for(i=0;i<=11;i++)
	{
    
    
		sum+=*(p+i);
	}
	//for(i=0;i<=2;i++)
	//{
    
    
		//for(j=0;j<=3;j++)
		//{
    
    
			//sum+=*(p+i*4+j);
		//}
	//}
	printf("三人的总平均分为%f\n",sum/n);
}

方法三:如果题目要求我们形参是指针变量,实参也是指针变量,那就按照以下三步来修改(前两步没变)

  • 函数声明:数组名[] [某数] 改成 *p
  • 函数解释:数组名[i] [j] 改成 * (p+i*列数+j)
  • 函数使用:数组名 改成 q(使用前要先关联)
#include<stdio.h>
 
int main()
{
    
    
	void shuchu(float *p,int n);
	float fenshu[3][4]={
    
    65,67,70,60,80,87,90,81,90,99,93,98};
	int *q;
	q=&fenshu[0][0];
	shuchu(q,12);//使用指针q前需要先定义,并且和数组的第一个元素相关联 
	
	return 0;
}
 
void shuchu(float *p,int n)
{
    
    
	float sum=0;
	int i; 
	for(i=0;i<=11;i++)
	{
    
    
		sum+=*(p+i);
	}
	printf("三人的总平均分为%f\n",sum/n);
}

用指向二维数组行变量的指针做形参

1:有3名学生学习4门课,学生一的成绩分别是65,67,70,60。学生二的成绩分别是80,87,90,81。学生三的成绩分别是90,99,93,98。将上述成绩输入二维数组,并通过函数输出第2个学生的各科成绩

tips:

  • 函数声明:数组名[] [某数] 改成 (*p)[某数]
  • 函数解释:数组名[i] [j] 改成 * (*p+i)+j)
#include<stdio.h>
 
int main()
{
    
    
	void shuchu(float (*p)[4],int n);//原来为float a[][4]
	float fenshu[3][4]={
    
    {
    
    65,67,70,60},{
    
    80,87,90,81},{
    
    90,99,93,98}};
	shuchu(fenshu,2);
	
	return 0;
}
 
void shuchu(float (*p)[4],int n)//原来为float a[][4]
{
    
    
	int i;
	printf("第%d个学生的各科成绩是\n",n);
	for(i=0;i<=3;i++)
	{
    
    
		printf("%f\t",*(*(p+n-1)+i));//原来为a[n-1][i]
	}
	printf("\n");
}

指针变量与字符串

和指针与一维数组的用法是完全一样的

1:定义字符串a为“I am shuaibi!”,将其赋值到字符串b里,并输出字符串b

#include<stdio.h>
 
int main()
{
    
    
	int i;
	char a[100]={
    
    'I',' ','a','m',' ','s','h','u','a','i','b','i','!'};
	char b[100],*p,*q;
	p=a;
	q=b;
	for(i=0; *(p+i)!='\0'; i++)
	{
    
    
		*(q+i)=*(p+i);
	}
	*(q+i+1)='\0';
	printf("字符串b:");
	for(i=0; *(q+i)!='\0'; i++)
	{
    
    
		printf("%c", *(q+i));
	}
	return 0;
}

指针与一维二维数组的数值关系

一般来说我们都明白以下两点:

  1. 指针=&值
  2. 值=*指针

但有些时候,不一定是这样写,而是采用了一些简便写法。简便写法写起来不要用&和[],是比较省事的。但这时候读起程序来就比较费劲了。其实简便写法的规律就是以下两条:

  1. &a[i]=a+i
  2. a[i]=*(a+i)

交换两个数

输入a和b两个整数,按先大后小的顺序输出a和b。(要求:a和b的值不变,交换指针变量的p1和p2的值)

#include<stdio.h>
int main()
{
    
    
	int a,b,*p1,*p2,*p;
    scanf("%d%d", &a, &b);
    p1=&a;
    p2=&b;
    if(a<b)
    {
    
    
        //也可以改为 p1=&b; p2=&a; 程序更加简练
        p=p1;
        p1=p2;
        p2=p;
    }
    printf("max=%d min=%d\n", *p1, *p2);
    return 0;
}

用函数处理,而且用指针类型的数据作函数参数

#include<stdio.h>
int main()
{
    
    
    void swap(int *p1,int *p2);
    int a,b,*p1,*p2;
    scanf("%d%d", &a, &b);
    p1=&a;
    p2=&b;
    if(a<b)
    {
    
    
        swap(p1,p2);
    }
    printf("max=%d min=%d\n", a, b);
    return 0;
}
void swap(int *p1,int *p2)
{
    
    
    int t;
    t=*p1;
    *p1=*p2;
    *p2=t;
}

猜你喜欢

转载自blog.csdn.net/weixin_44337241/article/details/117588351