C/指针进阶

一.指针数组与二维指针

1.指针数组:变量类型 *指针[n],这种形式来定义,比如char *c[3]。如图表示c  c[0]与字符型数据的关系。

#include<stdio.h>
int main(void)
{
	int a[2][3]={1,2,3,4,5,6};
	char *c[3]={"abcd","bbbb","cccc"};

	printf("a=%d\n",a);
	printf("&a[0]=%d\n",&a[0]);
	printf("a[0]=%d\n",a[0]);
	printf("%d  %d  %d\n",&a[0][0],&a[0][1],&a[1][0]);


	printf("c=%d\n",c);
	printf("&c[0]=%d\n",&c[0]);

	printf("*c=%d\n",*c);
	printf("c[0]=%d\n",c[0]);


	printf("c[0]=%s\n",c[0]);
	printf("c=%s\n",c);	
	return 0;
}

输出结果:c是c[0]的地址,c代表的内容*c即c[0]里面存的内容,也是一个指针,指向字符型数据首地址。对c进行字符串输出没有任何意义,因为c这个二维指针并不指向字符串。对于二维数组a[2][3],a=&a[0]=&a[0][0]。

2.不能用二维指针指向二维数组

#include<stdio.h>
int main(void)
{
  char c[2][2]={'a','b','c','d'};
  char *b, **chr;
  chr=c;//错误
  chr=b;//正确
  return 0;
}

不能这样指,因为c与&c[0]以及&c[0][0]一样,如果chr=c,*chr='a',但实际上*chr指向的还是地址,关键就是二维数组的 &c[0]和&c[0][0]地址一样,相当于二维指针中间少了一维。

二,链表学习

//利用链表构建
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct student_node
{
	int num;
	char name[20];               
	int score;
	struct student_node *next;
};
struct student_node *build(struct student_node *head);//新建链表
struct student_node *delete1(struct student_node *head,int num);//删除链表
void print(struct student_node *head);//遍历链表
int main(void)
{
	int chioce;
	int num;
//	char name[20];
	int size=sizeof(struct student_node);
	struct student_node *head;
	do{
		printf("1:build  2:delete1  3:print  0:exit");
		scanf("%d",&chioce);
	    switch(chioce)
		{
		case 1:
			head=build(head);
			break;
	
		case 2:
			printf("delete num:");
			scanf("%d",&num);
			head=delete1(head,num);
			break;
		case 3:
			print(head);
			break;
		case 0:
			break;
		}
	}while(chioce!=0);
	return 0;
}
struct student_node *build(struct student_node *head)
{
	struct student_node *p,*end;
	int num,score;
	char name[20];
	head=NULL;
	end=head;
	printf("put in:num  name score ");
    scanf("%d%s%d",&num,name,&score);
	int size=sizeof(struct student_node);
	while(num!=0)
	{
		p=(student_node*)malloc(size); //开辟动态存储空间   
		p->num=num;
		strcpy(p->name,name);
		p->score=score;
		p->next=NULL;

		if(head==NULL)//为空,直接添加
		{
		head=p;
		head->next=NULL;
		end=head;
		scanf("%d%s%d",&num,name,&score);
		}
		else {
		end->next=p;
		end=p;
		scanf("%d%s%d",&num,name,&score);
		}
	}
	return head;
}
struct student_node *delete1(struct student_node *head,int num)
{
	struct student_node *ptr1,*ptr2;
	if((head!=NULL)&&(head->num==num))
	{
		ptr1=head;
		head=head->next;
		free(ptr1);
	}
	if(head==NULL)
	{
		return NULL;
	}
	ptr1=head;
	ptr2=head->next;
	while(ptr2!=NULL)
	{
		if(ptr2->num==num)
		{
			ptr1->next=ptr2->next;
			free(ptr2);
		}
		else 
		{
			ptr1=ptr2;
			ptr2=ptr1->next;
		}
	}
	return head;

}
void print(struct student_node *head)
{
	struct student_node *ptr;
	ptr=head;
	if(ptr==NULL)
	{
		printf("nothing");
		return;
	}
	printf("All data:\n");
	printf("num\tname\tscore\n");
	for(ptr=head;ptr!=NULL;ptr=ptr->next)
	{
		printf("%d\t%s\t%d\n",ptr->num,ptr->name,ptr->score);
	}
}

三,杂记

1.为什么定义函数里面形参定义的是数组,但是当带入实参的时候带入的是数组的地址,节省内存空间,假如数组非常大的话,拷贝过去肯定会加大内存开销。

2.函数嵌套,用指针指向该被嵌套的函数。

//对于函数套函数
#include<stdio.h>
#include<math.h>
double f1(double x);
double calc(double(*f)(double),double a,double b);
int main(void)
{
	double m;
	double a,b;
	printf("输入a和b:");
	scanf("%lf%lf",&a,&b);
	m=calc(f1,a,b);
	printf("结果:%lf",m);
	return  0;
}
double f1(double x)
{
	return x*x;
}
double calc(double(*f)(double),double a,double b)// 指针指向的函数怎么表示:函数返回类型(*指针)(函数使用数据类型)
{
	double result;
	result=(b-a)/2*((*f)(a)+(*f)(b));
	return result;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值