大家好!指针的10种经典应用场合今天让小编来大家介绍下关于指针例子,以下是小编对此问题的归纳整理,让我们一起来看看吧!
都说指针是c语言的精髓,那指针究竟有哪些经典应用场合呢?
指针有三大类:指向数据的指针,指向函数的指针和范型指针(void*)。
其经典的应用场合,可以分为以下10类:
1 与函数相关的使用
1.1 在函数中用作输出型参数,产生副作用(更新被调函数中的局部变量的值);
1.2 在函数中用作输出型参数,用于返回多个值;
1.3 在函数中用作输入型参数,指向复合类型,避免传值的副作用(性能损耗);
1.4 用做函数返回值,返回一个左值;
1.5 用于指向函数的函数指针,使用函数指针调用回调函数;
2 用于指向堆内存;
3 与void配合使用,用void*来表示一个泛型指针;
4 用于指向数组名(数组指针);
5 用于指向字符串常量(字符串常量指针);
6 在数据结构中,用作链式存储;
附加:在字符串、文件操作中跟踪操作位置;
1 与函数相关的使用
1.1 在函数中用作输出型参数,产生副作用(更新被调函数中的局部变量的值)
#include void demo(int *ap,int size, int *max){ *max=ap[0]; for(int i=1;i*max) *max = ap[i];}int main(){ int max,ap[5]={1,2,8,4,5}; demo(ap,5,&max); printf("%dn",max); getchar(); return 0;}
1.2 在函数中用作输出型参数,用于返回多个值
#include #include int equationsolve(double a,double b,double c,double *x1,double *x2){ int delta = a*a-4*a*c; if(delta>=0) { *x1 = (-b sqrt(delta))/2*a; *x2 = (-b-sqrt(delta))/2*a; return 1; } else return 0;}int main(void){ double x1,x2; if(equationsolve(1,3,-14,&x1,&x2)) printf("x1=%.2fnx2=%.2fn", x1,x2); else printf("无实根!n"); getchar(); return 0;}/*x1=2.27x2=-5.27*/
1.3 在函数中用作输入型参数,指向复合类型,避免传值的副作用(性能损耗)
#include typedef struct inventory{ int sku; char name[36]; char unit[12]; char supplier[48]; double price; double stock;}inven;void demo(const inven *p){ printf("the amounts is %fn",p->price * (*p).stock); // ……}int main(){ inven inven={123,"carban fibre","kg","uc",128,100}; demo(&inven); getchar(); return 0;}
1.4 用做函数返回值,返回一个左值
#include #include #include void printintarray(void** array, size_t length) { printf("array at %pn", array); while (length--) { printf(" [%zu] at %p -> %p", length, array length, *(array length)); if (*(array length)) { printf(" -> %d", *(int*)*(array length)); } printf("n"); } } void* getelement(void** array, size_t index) { return *(array index); } int main(int argc, char** argv) { const size_t n = 5; size_t i; /* n element array */ void** test = malloc(sizeof(void*) * n); i = n; while (i--) { *(test i) = null; } /* set element [1] */ int testdata = 123; printf("testdata at %p -> %dn", &testdata, testdata); *(test 1) = (void*)&testdata; printintarray(test, n); /* prints 123, as expected */ printf("array[1] = %dn", *(int*)getelement(test, 1)); getchar(); return 0; }
返回左值在c 中应用比较多,特别是用引用来返回左值,如返回ostream&,或重载[]、=等运算符。
1.5 用于指向函数的函数指针,使用函数指针调用回调函数
// 通用的冒泡排序函数的应用#include #include using namespace std;template void sort(t a[], int size, bool (*f)(t,t)); // calleebool increaseint(int x, int y) {return x0;} // callbackee4 int main() // caller{ int a[] = {3,1,4,2,5,8,6,7,0,9}, i; char *b[]= {"aaa","bbb","fff","ttt","hhh","ddd","ggg","www","rrr","vvv"}; sort(a, 10,increaseint ); for (i = 0; i < 10; i) cout << a[i] <<"t"; cout << endl; sort(a, 10, decreaseint); for ( i = 0; i < 10; i) cout << a[i] <<"t"; cout << endl; sort(b, 10, increasestring ); for (i = 0; i < 10; i) cout << b[i] <<"t"; cout << endl; sort(b, 10, decreasestring); for ( i = 0; i < 10; i) cout << b[i] <<"t"; cout << endl; while(1); return 0;}// 通用的冒泡排序函数template void sort(t a[], int size, bool (*f)(t,t)){ bool flag; int i, j; for (i = 1; i < size; i) { flag = false; for (j = 0; j
2 用于指向堆内存
实质也是通过库函数(malloc.h)返回void*指针。
#include #include int** demo(int r,int c){ int **ap = (int**)malloc(sizeof(int*)*r); for(int i=0;i
3 与void配合使用,用void*来表示一个泛型指针
#include #include #include int swap2(void *x, void *y, int size){ void *tmp; if((tmp=malloc(size)) == null) return -1; memcpy(tmp,x,size); memcpy(x,y,size); memcpy(y,tmp,size); free(tmp); return 0;}int main(){ int a=3,b=4; swap2(&a,&b,sizeof(int)); printf("%d %dn",a,b); double c=3,d=4; swap2(&c,&d,sizeof(double)); printf("%f %fn",c,d); getchar(); return 0;}
4 用于指向数组名(数组指针)
#include void funcp(int *p,int r,int c){ for(int i=0;i
5 用于指向一个字符串常量(字符串常量指针)
const char* demo(){ //char sa[] = "hello!"; const char *sp = "hello!"; return sp;}
关于字符数组和字符指针可以图示如下:
在字符指针数组,数组元素是一个字符指针,用于指向一个字符串常量,如:
char *pmonth[] = {"january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december"};char *week[10] = { "mon","tue","wed","thu","fri","sat","sun"};char* color[]={"红-red","橙-orange","黄-yellow","绿-green","青-cyan","蓝-blue","紫-purple"};char *gans[10] = {"甲","乙","丙","丁","戊","己","庚","辛","壬","癸"};char* zhis[12] = {"子","丑","寅","卯","辰","巳","午","未","申","酉","戌","亥"};char* animals[12] = {"鼠","牛","虎","兔","龙","蛇","马","羊","猴","鸡","狗","猪"};
6 在数据结构中,用作链式存储
#define elementtype inttypedef struct lnode {telementtype data;tstruct lnode *next;} lnode, *linklist;
附加:在字符串、文件操作中跟踪操作位置。
如分割字符串函数strtok():
char *strtok(char s[], const char *delim);
对该函数的一系列调用将str拆分为标记(token),这些标记是由分隔符中的任何字符分隔的连续字符序列。
在第一次调用时,函数需要一个c风格字符串作为str的参数,str的第一个字符用作扫描标记的起始位置。在随后的调用中,函数需要一个空指针,并使用最后一个标记结束后的位置作为扫描的新起始位置。
要确定标记的开头和结尾,函数首先从起始位置扫描未包含在分隔符中的第一个字符(它将成为标记的开头)。然后从这个标记的开头开始扫描分隔符中包含的第一个字符,它将成为标记的结尾。如果找到终止的空字符,扫描也会停止。
标记的末端将自动替换为空字符,函数将返回标记的开头。
在对strtok的调用中找到str的终止空字符后,对该函数的所有后续调用(以空指针作为第一个参数)都会返回空指针。
找到最后一个标记的点由函数在内部保留,以便在下次调用时使用(不需要特定的库实现来避免数据争用)。
#include #include int main(){ char str[80] = "this is - www.runoob.com - website"; const char s[2] = "-"; char *token; /* 获取第一个子字符串 */ token = strtok(str, s); /* 继续获取其他的子字符串 */ while (token != null) { printf("%sn", token); token = strtok(null, s); } printf("n"); for (int i = 0; i < 34;i ) printf("%c", str[i]); return (0);}
二进制文件的随机读写:
在标记文件信息的结构体file中,包含3个标识文件操作位置的指针。
typedef struct _iobuf { char *_ptr; //文件操作的下一个位置 int _cnt; //当前缓冲区的相对位置 char *_base; //指基础位置(即是文件的其始位置) int _flag; //文件标志 int _file; //文件的有效性验证 int _charbuf; //检查缓冲区状况,如果无缓冲区则不读取 int _bufsiz; //缓冲区大小 char *_tmpfname; //临时文件名}file;
code demo:
#include // 按记录分块读写文件#include #include#includeusing namespace std;class student{public: student(void) {} student(int n, char nam[20], float s): num(n),score(s) { strcpy(name,nam); } void setnum(int n) { num=n; } void setname(char nam[20]) { strcpy(name,nam); } void setscore(float s) { score=s; } void show() { cout<
-end-
本文到此结束,希望对大家有所帮助。
本文地址:http://m.06567.cn/zhdt/723709.html