C指针的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("%d ",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=%.2f x2=%.2f ", x1,x2); else printf("无实根! "); getchar(); return 0; } /* x1=2.27 x2=-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 %f ",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 %p ", array); while (length--) { printf(" [%zu] at %p -> %p", length, array + length, *(array + length)); if (*(array + length)) { printf(" -> %d", *(int*)*(array + length)); } printf(" "); } } 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 -> %d ", &testData, testData); *(test + 1) = (void*)&testData; printIntArray(test, n); /* Prints 123, as expected */ printf("Array[1] = %d ", *(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)); // callee bool 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] <<" "; cout << endl; sort(a, 10, decreaseInt); for ( i = 0; i < 10; ++i) cout << a[i] <<" "; cout << endl; sort(b, 10, increaseString ); for (i = 0; i < 10; ++i) cout << b[i] <<" "; cout << endl; sort(b, 10, decreaseString); for ( i = 0; i < 10; ++i) cout << b[i] <<" "; 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 #include int** demo(int r,int c) { int **ap = (int**)malloc(sizeof(int*)*r); for(int i=0;i #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 %d ",a,b); double c=3,d=4; swap2(&c,&d,sizeof(double)); printf("%f %f ",c,d); getchar(); return 0; }
4 用于指向数组名(数组指针)#include void funcP(int *p,int r,int c) { for(int i=0;i #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("%s ", token); token = strtok(NULL, s); } printf(" "); 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 #include using 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<
短短的五句话,说透了人性!(精辟)作者拾壹言01序言人活一世,最难的不是赚钱,而是学会说透人性。如果你不会说话,那么可以先去学会闭嘴。因为,说出一句话,要花上很多力气,即使是很小的一件事,也需要花费许多时间来完成。
清荷札记阅尽千帆,初心依旧阅尽千帆,初心依旧作者清荷札记时光不语,亲情恒久,犹如人生中意味深长的祈念,让爱静静地待在我的平淡日常中,人生一辈子,都是因果。生活的意味,仿佛能在庸常的光尘中,早已经成为我心中期
这世界很喧嚣,做你自己就好云朵也是一种风景,眼泪也是一种品尝。风吹过,浪埋过,岩石依旧在泰戈尔1。总是假装很乖,可我知道,有时候,你也会累2。我明白,颤抖着的指尖是你满腹的心事3。笑一个吧!就当是对自己的奖
当你25岁,身边的人都结婚了,你会恐慌吗?头号解忧馆很喜欢这句话有人22岁就开始相夫教子,有人32岁了还在追求梦想,有人为了车房拼了一辈子,而有一些人,买一辆摩托车就走遍大好河山。生活是自己的,千万别为难自己,有什么样的能
为什么工地塔吊下永远有冰红茶1hr牛老师认为冰红茶是世界上最好的饮料。好喝,量大,不花钱。我说前两个我都理解,最后一个我不能理解,啥时候冰红茶不要钱了?牛老师笑了,傻子才去超市买,真聪明人都去塔吊下捡,那里总
红网夜读坚守那个纯粹的自己用声音传递温暖,欢迎收听红网夜读,我是田萌,田野的田,萌芽的萌。王尔德说不要虚掷你的黄金时代,不要去倾听枯燥乏味的东西,不要设法挽留无望的失败,不要把你的生命献给无知平庸和低俗。活
无语!格力地产血亏近30亿格力地产发布财报,预计2022年亏损23。86亿元至28。63亿元。晚间,格力地产对外发布公告称,预计过往的2022年将亏损近乎30亿元,而去年同期尚有净利润3。21亿元。这也意味
诗歌王三炯蓉城的冬天(组诗)文王三炯冬天不会缺席昨夜的西风在窗外呜咽冬带着一路奔波的疲惫努力地摇着我的窗户想告诉我她的来到今晨下着小雨冷空气不需要湿润气流的温存受到委屈的气流降落到地面不料做了西风的帮凶着秋装
退休过后,不要去显摆这3样东西,退休后更要谨慎做人当我们退休后,我们脱离了复杂的职场环境,经常会和身边的人或者要好的朋友相聚,因此更加会放松地去谈论一些事情。殊不知,我们退休后想要生活得更加快乐,却需要更加地注重一些事情,要不然很
诸城谋划106个重点项目,总投资577。49亿近日,山东省人民政府下发了关于下达2023年省重大项目名单的通知,诸城市共有4个项目成功列入2023年省重大项目,入选个数列潍坊县市区第一。项目分别为诸城泰石投资控股集团智能网联和
阿里巴巴西溪全球总部扩容!新地块规划方案公示钱江晚报小时新闻记者印梦怡日前,未来科技城管委会发布了一则项目规划方案公示,阿里巴巴西溪全球总部又一块拼图揭开神秘面纱。阿里西溪园区B区东侧扩容6。2万方该地块位于余杭区五常街道,