C语言学习2

一.指针的学习

1.函数指针的学习

函数指针定义格式:类型名 (*函数名)(函数参数列表);

注意:函数指针声明为指针,它与变量指针不同之处是,它不是指向变量,而是指向函数

int (*pa)(int,int)

上述便是一个函数指针的类型;

2.函数指针数组

int *(*p(int))[3]

例如上述代码,第一眼看见是不是就蒙了,别急我们慢慢分析。

int p; //这是整数型变量p

int *p; //这是整数型指针p

int *p[3]; //这是长度为3的整数型指针数组p,元素为整数型指针

int (*p)[3]; //这是一个数组指针,指向一个长度为3的整数型数组

int p(int); //这是函数声明

 int *p(int); //这是函数声明

 int (*p)(int); //这是函数指针,指向有一个整数型形参和整数型返回值的函数

 int (*p[3])(int);//这是函数指针数组,每个元素指向有一个整数型形参和整数型返回值的函数

 int *(*p(int)); //这是函数声明,指向整数型指针的指针

看完了上面的例子,让我们来看看下面这个有趣的代码

(*(void(*)())0)()

    尝试理解下面这串代码。加油加油!!冲冲冲!

学习了函数指针数组,我们可以尝试将我们用函数指针数组来简化一个加减乘除的计算器。

#include<stdio.h>
#include<stdlib.h>
int sub(int a,int b)
{
	return a+b; 
}
int jian(int a,int b)
{
	return a-b; 
}
int cheng(int a,int b)
{
	return a*b; 
}
int chu(int a,int b)
{
	return a/b; 
}
int main ()
{
	printf("==========================\n");
	printf("========1.整数加法========\n"); 
	printf("========2.整数减法========\n");
	printf("========3.整数乘法========\n"); 
	printf("========4.整数除法========\n"); 
	printf("========0.退出程序========\n");
	printf("==========================\n"); 
	int a,b;
	printf("请您输入您想要使用的功能>:");
	int i;
	scanf("%d",&i);
	if(i>=1&&i<=4)
	{
		printf("请您输入两个整数:");
		scanf("%d,%d",&a,&b);
		 
		
		int(*parr[5])(int,int)={NULL,sub,jian,cheng,chu};
		
	  printf("%d",(*parr[i])(a,b));
	  return 0;
	 } 
	 else if(i==0)
	 {
	 	exit(0);
	 }
	 else if(i>4)
	 {
	 	printf("您的输入有误!");
	  } 
	 
 } 

相信大家都会,这里就直接上代码。

2.指针常见的错误(小汇总)

注意:数组名!=&数组名

         函数名=&函数名。

#include<stdio.h>
int main ()
{
	int a[5]={1,2,3,4,5};
	int *ptr=(int*)(&a+1);
	printf("%d %d",*(a+1),*(ptr-1));
}

例如上面这串代码,

第一次输出中,a为数组首元素地址,数组首元素地址+1后解引用,指向下一位,故输出结果为2

第二次ptr中&a跨越了整个数组,ptr-1之后再解引用指向5,故输出结果为5;

注意注意!重头戏来了

#include<stdio.h>
int main ()
{
	int a[3][4]={0};
	printf("%d\n",sizeof(a));
	printf("%d\n",sizeof(a[0][0]));
	printf("%d\n",sizeof(a[0]));
	printf("%d\n",sizeof(a[0]+1));
    printf("%d\n",sizeof(*(a[0]+1)));
	printf("%d\n",sizeof(a+1));
	printf("%d\n",sizeof(*(a+1)));
	printf("%d\n",sizeof(&a[0]+1));
	printf("%d\n",sizeof(*(&a[0]+1)));
	printf("%d\n",sizeof(*a));
	printf("%d\n",sizeof(a[3]));
	printf("%d",1);
	return;
}

温馨提示:

sizeof(数组名),这里数组为整个数组,计算的是整个数组的大小;

&数组名,这里的数组名表示整个该数组,取出的是整个数组的地址;

除此之外所有数组名都表示首元素地址

 这里先将答案给大家,下次C语言总结会重点知识。

二.算法的学习

本周学习了桶排序,冒泡排序,快速排序;但仅仅只是了解,距离灵活运用,还have a long way to go...

1.桶排序

桶排序中,我们让一个数组升序排序,可以计算这个数组出现了几次,然后根据出现的次数来进行打印。这里直接上代码。

#include<stdio.h>
int main()
{
	int i,j,k,n,t;
	int a[1000]={0};
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
	scanf("%d",&t);
	a[t]++;
	}
	for(j=999;j>=0;j--){
		for(k=1;k<=a[j];k++)
		printf("%d\t",j);
	} 
 } 

2.冒泡排序

这里为了复习结构体,将冒泡跟结构体联系在了一起,输入学生的名字和成绩,就会按照成绩的高低来以此输出他们的名字。

#include<stdio.h>
//int main()
//{
	//int i=0;
	//i=i++;
	//printf("%d",i); 
 //} 
 struct student {
 	char name[22];
 	int score;
 };
 
int main ()
{
	struct student a[100],t;
	int i,j,n;
	scanf("%d",&n);
	for(i=1;i<=n;i++)
	{
		scanf("%S %d",a[i].name,&a[i].score);
		
	}
	for(i=1;i<=n-1;i++)
	{
		for(j=1;j<=n-1;j++)
		if(a[j].score<a[j+1].score)
		{
			t=a[j];
			a[j]=a[j+1];
			a[j+1]=t;
		 } 
	}
	 for(i=1;i<=n;i++)
	 printf("%s\n",a[i].name);
}

快速拍戏当前还学的不精,就不再这里献丑了。

三.复习

1.青蛙跳台阶问题(函数递归)

#include<stdio.h>
int jumpstep1(int k)
{
	if(k==1)
	return 1;
	if(k==2)
	return 2;
	if(k>2)
	return jumpstep1(k-1)+jumpstep1(k-2);
	
}
int jumpstep2(int q)
{
	if(q==1)
	
	return 1;
	if(q==2)
	return 2;
	if(q==3)
	return 4;
	if(q>4)
	return jumpstep2(q-1)+jumpstep2(q-3)+jumpstep2(q-2);
 } 




int main()
{
     int i;
     printf("请您输入台阶的个数>:")	;
     scanf("%d",&i);
     int j;
     j=jumpstep1(i);
     printf("青蛙跳台阶的方法为:%d\n",j);
 
  printf("假设这次青蛙每次能跳三个台阶\n");
   printf("请您输入台阶的个数>:")	;
   
  int a;
  scanf("%d",&a);
  int b;
  b=jumpstep2(a);
  
   printf("青蛙跳台阶的方法为:%d\n",b);
 } 

PS:当只有一个台阶,只能跳一次;

当有两个台阶,可以跳一次或者两次;

当三个台阶,就有前面两次合起来的总跳法;

就是n-1加上n-2这样的递归。(在后面还加上了如果一跳三个台阶的方法,大家可以康康)

2.数组的复习

2.1.求最小值和其下表

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

2.2回文字符串的判断

#include<stdio.h>
int main()
{
	int i,k,s;
	char line[80];
	k=0;
	while ((line[k]=getchar())!='\n')//字符串的输入
	k++;
	line[k]='\0';//k加完后的值
	i=0;
	s=k;
	k=k-1;
	while(i<k)
	{
		if(line[i]!=line[k])
		break;
		i++;
		k--;
	}//跳出循环,出现两种情况。
	if(i>=k)
	{
		for(i=0;i<s;i++)
		printf("%c",line[i]);//输出字符串
		printf("\n");
		printf("Yes");
	}
	else
	{
		for(i=0;i<s;i++)
		printf("%c",line[i]);
		printf("\n");
		printf("No");
	}
	return 0;
}

   

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值