一.指针数组与二维指针
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;
}