(指针+结构体)详解--重点是指针函数,string的实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

(指针+结构体)详解--重点是指针函数,string的实现
⾸先搞清这次整张的讲解的顺序:
⼀,理解指针与变量的却别,还有地址,另外讲解设计指针的内存存储分布图
⼆,c语⾔中既然有指针,还有地址,那么我们不是能永远指下去吗?这样数据是⽆限的,为什么没有报错,如果不是⽆限的,那么地址在哪⾥终⽌呢?
三,结构体,与指针,及malloc的使⽤,以及结构体,及指针存储分布图
四,终极boss:指针函数,指针函数的应⽤,string的实现
步⼊正题:
⼀,理解指针与变量的却别,还有地址,另外讲解设计指针的内存存储分布图
code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node * ptrNode;
typedef struct node{
int value;
ptrNode prev;
ptrNode next;
}*link;
void createLink(link L);
void changeValue(int *p1);
int main(){
int a = 5;
int *p = &a;
printf("%d\n",*p);
printf("&p is %d,p is %d,&a is %d \n",&p,p,&a);
return 0;
}
打印结果:
通过上⾯的图,我们得出其内存存储的分布图:
⼆:c语⾔中既然有指针,还有地址,那么我们不是能永远指下去吗?这样数据是⽆限的,为什么没有报错,如果不是⽆限的,那么地址在哪⾥终⽌呢?
code:
#include <stdio.h>
#include <stdlib.h>
typedef struct node * ptrNode;
typedef struct node{
int value;
ptrNode prev;
ptrNode next;
}*link;
void createLink(link L);
void changeValue(int *p1);
int main(){
int a = 5;
int *p = &a;
// int *q = &&a; //error:label 'a' used but not defined
int *q = &p;
printf("%d\n",*p);
printf("&p is %d,p is %d,&a is %d ,*q is %d,q is %d,&q is %d\n",&p,p,&a,*q,q,&q);
return 0;
}
result :
通过这张图应该就明⽩了,如果⽤指针,便可⽆限指下去,⽽通过⼀个变量寻找其地址的地址,是不可能的
三:结构体,与指针,及malloc的使⽤,以及结构体,及指针存储分布图
理论知识:
结构体,其实本质就是类型,等同于oop⾥⾯的类,但是没有⽅法⽽已。

malloc: (type*)malloc(sizeof(type))
malloc作⽤是将⼀个申请了⼀个type类型⼤⼩的空间,然后将这个空间的⾸地址赋值给了⼀个指针,所以⼀定要知道返回的是指针,如果⽤个
⾮指针的代替将会报错。

test:
#include <stdio.h>
#include <stdlib.h>
typedef struct node * ptrNode;
typedef struct node{
int value;
ptrNode prev;
ptrNode next;
}*link;
void createLink(link L);
void changeValue(int *p1);
int main(){
link L;
L = (link)malloc(sizeof(link*));
createLink(L);
printf("the link is:\n");
printf("the link's value is %d \n",L->value);
printf("the link's prev pointer is %p",L->prev);
printf("the link's next pointer is %p",L->prev);
}
void createLink(link L){
scanf("%d",&(L->value));
L->prev=NULL;
L->next =NULL;
}
result:
通过上⾯代码,看⼀下其结构的内存分布图:
通过这站图,详细分析下结构体(第四节利⽤这节的知识如何实现string 类型的)
⾸先创建了⼀个struct ,利⽤typedef 将⼀个struct* 等名为 link,于是产⽣了⼀个指针类型的值L,此时L是⼀个指针,⽽*L是L指向的值,你可以打印*L,但是从常识来讲,你是打不开了,因为你⽆法将link*格式化,so.....kidding
重点:我们现在声明了⼀个link类型的指针,但是我们是没有申请空间的,所以⾥⾯知道存储了指针,那么我们必须申请空间,但是如果在struct ⾥⾯都是常⽤的类型,那么我们跟不需要申请空间,因为这些操作系统会⾃动将其放⼊栈中,⽽栈是不需要申请空间的,但是指针不⾏,指针你得告诉他要指向哪⾥,如果你知道,那么你也不需要申请空间,但是如果你不需要,⽽之后要⽤到,那么此时我们需要申请空间,来保证之后使⽤指针时(会在指针⾥⾯放东西⽽不是空的),我们就可以直接⽤了,因为指针指向的地⽅早有⼀个空间存放,这样就不会出现segment fault
另外将⼀下我在这⾥⼀个最⼤的误区吧:之前写⼀个link_list ,花了半天时间(⼼塞),其实半个⼩时写出整体的代码,但是⼀些在修⼀些bug,其中⼀个是核⼼:我在main函数中声明了⼀个link的指针类型,但是调⽤了⼀个createlist中申明空间,注意:此时的L地址改变了,所以你的值也会改变,当时没有注意这⼀点,到时后期出现值乱放的问题。

这种问题是很多c语⾔的童鞋们很容易出现错误的点⼦,但是编译器是不会报错的。

解决这个问题的⽅法:必须传地址(亲,不是传指针哦,千万注意,前⾯说过指针是变量,你⼀不⼩⼼改变了指针的值,那就完了),但是你改不了其地址。

所以你想在某个函数⾥⾯修改其值,返回的时候⼜不想改变他,那么亲传地址吧(函数调⽤两种⽅式:传值或传址)
相信这⼀样能让你轻松写出⼀个list了(真正能理解,直接⼀遍,不会出现任何问题就写出了⼀个list)。

四,终极boss:指针函数,指针函数的应⽤,string的实现
先来个实例:
code:
/*
conclusion:if you send value (include pointer),then the value's in the function will change ,it leads to your
don't changing your value
but if you send a address ,then your address won't change ,and the real
value will also come back main function!
*/
#include <stdio.h>
#include <stdlib.h>
typedef struct node * ptrNode;
typedef struct node{
int value;
ptrNode prev;
ptrNode next;
}*link;
void createLink(link L);
void changeValue(int *p1);
int main(){
link L;
void (*func)(link);
L = (link)malloc(sizeof(link*));
func = createLink;
func(L);
//createLink(L);
printf("the link is:\n");
printf("the link's value is %d \n",L->value);
printf("the link's prev pointer is %p",L->prev);
printf("the link's next pointer is %p",L->prev);
}
void createLink(link L){
scanf("%d",&(L->value));
L->prev=NULL;
L->next =NULL;
}
输出结果:
其内存存储分布图:
图⽚说明:⾸先声明⼀个变量,为函数类型指针变量,利⽤这个变量指向函数,然后直接调⽤指针变量,这样就完成了通过传值⽅式,将⼀个函数当做参数,传⼊另外⼀个函数去了。

下⾯利⽤⼀个实例来说明,将⼀个函数如果通过参数传⼊,并且使⽤的。

code :
#include <stdio.h>
#include <stdlib.h>
typedef struct node * ptrNode;
typedef struct node{
int value;
ptrNode prev;
ptrNode next;
}*link;
typedef int (*fun)(int);
void createLink(link L,fun L1);
void changeValue(int *p1);
int function(int x);
int main(){
link L;
fun func;
L = (link)malloc(sizeof(link*));
func = &function;
createLink(L,func);
//createLink(L);
printf("the link is:\n");
printf("the link's value is %d \n",L->value);
printf("the link's prev pointer is %p",L->prev);
printf("the link's next pointer is %p",L->prev);
}
int function(int x){
return x;
}
void createLink(link L,fun L1){
int value = 0;
scanf("%d",&(L->value));
L->prev=NULL;
L->next =NULL;
value = L1(L->value);
printf("the value of the funciton return is %d\n",value);
}
result :
分析:
整体思路:
⾸先分析⼀个问题,C语⾔⾥⾯参数必须是指针或者变量,⽽函数是什么?函数名是⼀个指针变量,他有地址,这个指针变量是指其⾥⾯存储空间的⾸地址,⽽地址是指向这个变量的。


之前说过,如果我们把指针变变量赋值给指针,这样会出现⼀个问题,当我们采⽤函数传值的时候,可能值是不会改变的,但是,如果将其地址传给指针,那么我们就能很好的控制这个函数了。

所以,我们要声明⼀个函数类型的指针,⽽不是⼀个值,然后这个指针必须指向其函数地址才⾏。

技术拆分分析:
如何判断函数类型,如:type function(type ,type){}--》通过这个函数,我们来分析其结构,⾸先是⼀个type,说明函数变量的类型是⼀个type类型的,function是函数名,
(type,type)是其函数变量的组成,最后{}是函数⾥⾯的value,这个可以不⽤
通过上⾯我们知道函数的类型是type,那么我们需要⼀个指向函数地址的指针,这点很重要,是指向函数地址的指针,函数是type类型,那么其地址的类型呢type&,然后传递的时候参数不可以使⽤
&来传递的,所有我们需要声明⼀个函数指针,申明⽅式typedef type (*func)(type,type),这样我们就得到⼀个函数指针func是指向函数的地址
⾥⾯插⼀个东西:typedef type* func1 与typedef type (*func2)有什么区别呢?其实很简单 func1和func2都是指针,但是指的东西是不同的,第⼀个你是直接指向某个变量,第⼆个你是指向某个变量的地址,
另外采⽤数学等式来⽐较更加直观:type* = func1 1式---- type = *func1 2式 ----将1式进⾏转化 type = &func1,这两个式⼦应该很好说明了这两种的不同点了。

⽤指针调⽤函数,是直接采⽤⼆式的,应为func是变量,你如果利⽤⼀式采⽤指针指⼀个变量会出问题,⽽利⽤变量值变量就不会出问题。

问题⼆:如果实现⼀个string类型,其实通过上⾯的,基本可以知道如何实现⼀个string 类型了
代码:typedef char* string
采⽤上⾯的思想,去理解这个代码:string⾸先就是⼀个指针,所以他需要指向⼀个地址,⼀个可⾏的地址(系统的就会出问题),直接使⽤string 其实就是利⽤其指针指向了第⼀个变量的地址。

最后⼀个问题:利⽤函数当做参数来使⽤,采⽤qsort函数(改版)
code:
#include <stdio.h>
#include <stdlib.h>
#
typedef struct node * ptrNode;
typedef struct node{
int value;
ptrNode prev;
ptrNode next;
}*link;
typedef char* string;
typedef int (*fun)(int);
typedef int (*fun1)(const void*,const void*);
void createLink(link L,fun L1);
void changeValue(int *p1);
int function(int x);
int cmp(const void*a,const void *b){
return *(char*)a-*(char*)b;
}
int main(){
string s;
scanf("%s",s);
fun1 point;
point = &cmp;
qsort(s,strlen(s),sizeof(s[0]),point);
printf("the string is :%s\n",s);
return 0;
}
result:
其中利⽤以上知识实现了⼀个string还有将cmp转化⼀个指针变量就⾏处理了!下⼀章利⽤指针来实现⼀个⼀元多项式的表⽰及相加!。

相关文档
最新文档