C语言指针总结及实现

来源:互联网 发布:linux系统cd命令 编辑:程序博客网 时间:2024/06/10 22:25

第一部分:指针知识点总结

1、掌握了指针,就掌握了C语言的精髓!计算机中绝大部分数据都放到内存中的,不同的数据放到不同的内存区域中。

内存角度没有数据类型,只有二进制;数据以字节(8位二进制)为单位存取。

不同数据类型占据不同的字节,32位系统中:int 为4个字节,short为2个字节。

2、int i = 5;

printf("%d\n",&i);

int j=5;

printf("%d\n",&j);

3、&i表示:获得变量i所指向内存的地址,地址也是数字。

4、既然&是取地址,那么就可以用int类型存储指针地址:

int iAddr = &i;

short、long、char等的地址都可以用int表示。不过如果用int表示各种指针,那么就不知道内存中到底放的是什么类型(其实内存中也不知道是什么类型,都是一堆字节数据而已)。

一般用“类型指针”:int *iPtr = &i; printf("%d\n",iPtr);结果是一样的。

5、使用*取指针指向的内存数据。 int j=*iPtr;

6、还可以通过指针修改变量的值:

int i = 5;

int *iPtr = &i;

*iPtr = 6;//区别就在于是否是声明,和放在=的左边还是右边没关系

printf("%d\n",i);

7、总结:

*的两个用途:

1)声明的时候用来声明指针变量: int *iPtr;

2)除了声明变量的时候,其他时候*用来表示获取指针指向的数据。

8、每次加一就是指针向前移动指针类型对应的字节数。减法则是相反的。ptr--;

9、指针相减代表计算两个指针的距离(不是字节数,而是“字节数/数据类型的字节长度”)。

10、void *表示一个“不知道类型”的指针,也就不知道从这个指针地址开始多少字节为一个数据。和用int表示指针异曲同工,只是更明确是“指针”。

因此void*只能表示一个地址,不能用来&取值,也不能++--移动指针,因此不知道多少字节是一个数据单位

11、void *就是一个不能动的“地址”,在进行&、移动指针之前必须转型为类型指针

12、void *的用途:在只知道内存,但是不知道是什么类型的时候。

13、栈空间:出了函数范围,内存空间自动释放。定义的局部变量int、局部数组等都在栈空间中。

栈空间的尺寸有最大限制,不适合分配大空间使用;栈空间出了函数范围就释放,不适合要给其他地方使用的内存。好处:不用手动释放内存。

14、注意:一般不要把局部变量的指针做为返回值返回;

15、堆空间:手动分配,使用完成后要手动释放。使用malloc分配,要在内存时候完成后用free释放内存。优点:可以动态分配内存。

16、函数返回指针的方法

方法1:在方法内malloc,用完了由调用者free

方法2:把局部变量定义为static,不适合于多线程调用,如果想保存返回内容,你需要调用者尽快复制一份。

方法3:由调用者分配内存空间,只是把指针发给函数,函数内部把数据拷贝到内存中(推荐)。

17 函数指针与指针函数

 1)指针函数是指带指针的函数,即本质是一个函数。函数返回类型是某一类型的指针

     类型标识符    *函数名(参数表)

      int *f(xy);

首先它是一个函数,只不过这个函数的返回值是一个地址值。函数返回值必须用同类型的指针变量来接受,也就是说,指针函数一定有函数返回值,而且,在主调函数中,函数返回值必须赋给同类型的指针变量。

表示:

float *fun();

float *p;

p = fun(a);

2)函数指针是指向函数的指针变量,即本质是一个指针变量。

 int (*f) (int x); /* 声明一个函数指针 */

 f=func; /* func函数的首地址赋给指针f */

指向函数的指针包含了函数的地址,可以通过它来调用函数。声明格式如下:
        
类型说明符 (*函数名)(参数)
    
其实这里不能称为函数名,应该叫做指针的变量名。这个特殊的指针指向一个返回整型值的函数。指针的声明笔削和它指向函数的声明保持一致。

        
指针名和指针运算符外面的括号改变了默认的运算符优先级。如果没有圆括号,就变成了一个返回整型指针的函数的原型声明。


第二部分:C语言指针

#include<stdio.h>#include<string.h>void subFun(int *a);int parseNum(int num, int *a, int *b, int *c);int endWith(char *str, char *substr);void structPoint();void parseFile(char *fileName, char *file, char *suff);typedef void (*ptrFun)(int i);typedef int (*pMaxFun)(void *a, void *b);void print(int i);void printMax();void main(){//**********数组名传参********///*int a[] = {1, 2, 3, 4, 5};printf("%d\n", sizeof(a)/sizeof(int));subFun(a);*///**********提取每位数字********///*int num = 345;int g, s, b;int reg = parseNum(num, &g, &s, &b);if(0 == reg){printf("error in parse!!!");}else{printf("num is: %d, %d, %d, %d", num, g, s, b);}*///********字符结束判断********///*printf("%d\n", endWith("sping", "ing"));printf("%d\n", endWith("sping", "eng"));printf("%d\n", endWith("sping", "zzzzzing"));*///********结构体指针********///*structPoint();*///*******函数指针********///*ptrFun p = print;p(88);*///****函数指针应用 - 求数组中最大值****///*printMax();*///*****函数返回指针的方法******//char fileName[] = "hello_world.jpg";char file[20] = {0};char suff[20] = {0};parseFile(fileName, file, suff);printf("文件名:%s, 后缀名:%s", file, suff);}void parseFile(char *fileName, char *file, char* suff){if(fileName == NULL){return;}char *Ptr = fileName;while(*Ptr != '\0'){Ptr++;}char *endPtr = Ptr;while(*Ptr != '.'){Ptr--;}memcpy(file, fileName, (Ptr - fileName)*sizeof(char));memcpy(suff, Ptr+1, (endPtr - Ptr)*sizeof(char));}void *Max(void *num, int len, int iSize, pMaxFun pFun){int i;char *ptr = (char *)num;char *max = ptr;for(i=0; i<len; i++){char *addstr = ptr + i*iSize;if(pFun(addstr, max)>0){max = addstr;}}return max;}int compareFun(void *a, void *b){int *num1 = (int *)a;int *num2 = (int *)b;return *num1-*num2;}void printMax(){int num[] = {3,4,6,1,3,5,2,7,2,1};int *pMax = (int *)Max(num, sizeof(num)/sizeof(int), sizeof(int), compareFun);printf("max is: %d\n", *pMax);}int parseNum(int num, int *a, int *b, int *c){if(num<0 || num>999){return 0;}*a = num / 100;*b = (num /10)%10;*c = num%10;return 1;}void subFun(int *a){printf("%d\n", sizeof(a));}int endWith(char *str, char *substr){if(NULL == str || NULL == substr){return 0;}int len=0;while('\0' != *str){len++;str++;}int sublen=0;while('\0' != *substr){sublen++;substr++;}if(len <= sublen){return 0;}printf("len = %d, sublen = %d\n", len, sublen);int i;for(i=0; i<=sublen; i++){if(*str != *substr){return 0;}str--;substr--;}return 1;}typedef struct _Person {char *name;int age;double money;}Person;void structPoint(){Person p1;memset(&p1, 0, sizeof(Person));p1.name = "sping";p1.age = 20;p1.money = 500.;printf("%s, %d, %lf\n", p1.name, p1.age, p1.money);Person p2 = p1;Person *p3 = &p1;printf("%s, %d, %lf\n", p2.name, p2.age, p2.money);printf("%s, %d, %lf\n", p3->name, p3->age, p3->money);p1.money = 5000.;}void print(int i){printf("num: %d\n", i);}


0 0