亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

函數返回值與不同存儲位置字符串的“坑”

2019-11-14 08:43:42
字體:
來源:轉載
供稿:網友

通常,我們采用兩種方式從一個函數中(被調用者),將某個有用信息傳遞到另外一個函數中(調用者)。分別是傳參方式與返回值方式①傳參方式:傳參數我們傳遞的是地址(或者值,以傳地址為重點),地址作為傳出參數,其思想是調用者將自己的棧空間給被調用者使用,然后在被調用者結束時調用者授權其使用的棧空間并不會被回收,而調用者就可以從自己的??臻g中取得有用的值;②返回值方式: 被調用者在結束是向調用者返回一個值或者是一個不會被回收的內存地址(或者值)。當然我們也可以使用定義局部變量的方式解決傳參與返回值的麻煩的步驟,但是一有所得,必有所失,全局變量由于其共享性而不是那么的安全。

1、傳參與返回值各自的演示:

我們以簡單的求和([1,n]所有整數之和),實現主函數獲取求和函數的處理結果的例子來做演示:

#include<stdio.h>void add_para(int * sum, int n){ itn i; for(i=1; i<=n; i++) *sum += i; }int add_ret(int n){ return (n*(n+)/2); //返回值}int main(void){ int n = 0, sum = 0; scanf("%d",&n); add_para(&sum, n);//傳參方式 這里寫圖片描述 當然,我們也可以采用參數與返回值雙重返回的方式來傳遞處理結果:

int * add_para_ret(int * sum, int n){//傳參方式 itn i; for(i=1; i<=n; i++) *sum += i; return &sum; //返回地址方式}

那么今天我們就重點說說返回值(地址)與傳參的那些問題。

2、返回值的重點:地址返回與值返回

在返回值時,我們經常會返回一個變量的地址,該地址在函數被調函數結束后不會被回收。因為在采用返回值(狹義),而不是一個值的有效地址的時候,返回其實并不起作用(或者說是返回失效)。當然返回地址也會失效,比如局部變量的??臻g在返回給主函數(調用者)時其返回是無效的。 舉個簡單的例子(以上例為母本):

/*地址返回的誤區*/#include<stdio.h>int * add_ret(int n){ int sum = (n*(n+)/2); return &sum; //返回局部??臻g地址}void add_para(int * sum, int n){ itn i; for(i=1; i<=n; i++) *sum += i; }int main(void){ int n = 0,* sum = 0; scanf("%d",&n); sum = add_ret(n);//計算結果是5050 add_para(sum,n);//計算結果是5050的兩倍,當然如果不是那也不意外,因為sum指向的地址被來就已經不屬于它,被別人修改也很正常 printf("sum = %d/n",*sum);//輸出不是正確結果 return 0;}

這里寫圖片描述

我們發現會有警告:函數返回局部變量地址。 并且打印的并不是我們想要的值,雖然這個結果是我們人為造成的(我們用main中的sum接收了一個不可控的局部變量地址,之前的計算結果5050還存在,導致最終結果是預期的兩倍),只需要在add_para()函數中將sum重新初始化,結果就會正確;但是很多情況下即使在add_para()中將sum中重新初始化為0,對于返回的局部變量地址(這塊地址在返回后并不屬于調用方,已被回收只是還沒重新利用,故原有內內容還在)我們不能人為控制。如果在main()輸出sum中內容之前系統用已經用回收的地址干了其他事,那結果就那沒有規律可循了。所以我們在返回地址時,絕對不能返回局部變量地址(??臻g)。

3、字符串地址返回與傳參的“坑”:

這塊才是今天的重頭戲,昨天晚上我寫了一段代碼,出現了段錯誤提示,代碼如下:

#include<stdio.h>#include<errno.h>#include<pthread.h>#include<string.h>#include<stdlib.h>void * task(void *p){ printf("%s/n",(char *)p); p = "hello"; strcpy(p,"hello"); //char st[] = "hello";//st指向棧區,返回的是無效的指針,不能使用 //return st; return p;}int main(void){ char str[] = "abcde"; pthread_t tid; pthread_create(&tid, NULL, task, str); char * retval = "world"; int ret = pthread_join(tid, (void **)&retval); if(ret){ printf("pthread_join error %s/n",strerror(ret)); exit(EXIT_FAILURE); } printf("str = %s/n",str);//str由strcpy(p,"hello");語句改變 printf("res = %s/n",retval);//retval由p="hello";語句改變 return 0;}

這里str采用傳參的方式改變字符串內容,retval采用返回值的方式改變字符串內容,按理說str與retval輸出應該都是”hello”,結果卻總是那么出人意料讓人驚喜。。 這里寫圖片描述

編譯運行之后,我們發現只有第一個printf()輸出了個”abcde”,而后面接著是段錯誤。那么首先我想到的就是返回了局部變量地址,但是并非如此:參數指針p指向的地址并非本函數中的??臻g,pthread_join(tid, (void **)&retval);語句將main()函數中的地址傳給了被調函數(子線程),返回是不會出錯的。而當我仔細觀察了這兩句語句之后:

p = "hello";strcpy(p,"hello");

我發現了端倪所在:p本來指向主線程傳給其的主線程中的地址,單單就每個語句來看:①p = “hello”;這一語句改變了p的指向(改為指向字符常量區),返回p是沒有問題的,②strcpy(p,”hello”);只負責復制不負責修改指向,就像傳參一樣。但是strcpy(p,”hello”);放在了p = “hello”;的后面就引發了段錯誤(strcpy(p,”hello”);放在了p = “hello”;的前面就不會引發),問題在于第一句修改p的指向,“hello”在只讀常量區,也就是說其之不能修改,而后面緊接著就用strcpy修改其值,導致了段錯誤。當我們稍作修改如下,問題立馬解決:

/*修改strcpy(p,"hello");與p = "hello";的順序*/#include<stdio.h>#include<errno.h>#include<pthread.h>#include<string.h>#include<stdlib.h>void * task(void *p){ printf("%s/n",(char *)p); //p = "hello";//修改地址為只讀常量區地址 strcpy(p,"hello");//沒有修改地址,原有地址在main函數中 p = "hello"; /* *注意:第八行與第九行不能同時執行,必須注釋掉一個 *但是當調換8、9行順序后可以同時執行(即9、10行一起執行) *這是因為"hello"在只讀區 *p="hello"是修改p的地址,strcpy是修改p的指向的地址中的值 *8、9行的代碼順序試圖改變只讀區的值,引發段錯誤而退出 *而9、10行的順序不會去修改只讀區的值 * */ //char st[] = "hello";//st指向棧區,返回的是無效的指針,不能使用 return p; //return st;}int main(void){ char str[] = "abcde"; pthread_t tid; pthread_create(&tid, NULL, task, str); char * retval = "world"; int ret = pthread_join(tid, (void **)&retval); if(ret){ printf("pthread_join error %s/n",strerror(ret)); exit(EXIT_FAILURE); } printf("str = %s/n",str);//str由strcpy(p,"hello");語句改變 printf("res = %s/n",retval);//retval由p="hello";語句改變 return 0;}

結果如下(正確結果):

這里寫圖片描述

4、總結:

關于函數/線程的返回值: ①可以以指針作返回值,但是不能直接以數組作返回類型; ②可以返回局部變量,但是不能返回局部變量的指針; ③加了static的局部變量指針可以返回(加static就不再是局部變量); ④函數/線程的返回值必須是一個有效的指針。 最后再加一點:對于返回值不僅要注意??臻g,也要注意全局區、堆區。也就是說對于按址返回的方式,一定要注意在函數執行中其地址是否改變,其地址是否被允許改變,其地址的指向是否被允許改變。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美精品在线网站| 日韩成人中文字幕| 亚洲人a成www在线影院| 亚洲小视频在线| 成人h片在线播放免费网站| 国产成人精品视频| 国产精品久久久久久久久久久久久| 成年无码av片在线| 亚洲精品456在线播放狼人| 久久精品久久久久电影| 亚洲xxxx18| 午夜免费在线观看精品视频| 精品国产一区二区三区在线观看| 26uuu另类亚洲欧美日本一| 成人啪啪免费看| 日韩av在线资源| 欧美亚洲免费电影| 日韩性生活视频| 国产欧美一区二区三区四区| 91美女片黄在线观看游戏| 国模私拍一区二区三区| 国产久一一精品| 欧美电影《睫毛膏》| 久久精品在线视频| 国产精品1区2区在线观看| 不卡av电影在线观看| 岛国av午夜精品| 久久九九国产精品怡红院| 久久久爽爽爽美女图片| 亚洲欧美日韩中文在线| 亚洲一区二区精品| 亲子乱一区二区三区电影| 波霸ol色综合久久| 欧美精品少妇videofree| 精品视频中文字幕| 日韩国产高清污视频在线观看| 久久九九亚洲综合| 有码中文亚洲精品| 日韩av在线免费| 欧美日韩一区二区免费视频| 2019av中文字幕| 91香蕉电影院| 欧美成人小视频| 国产精品主播视频| 欧美高清视频在线播放| 尤物yw午夜国产精品视频| 国产精品午夜国产小视频| 另类图片亚洲另类| 亚洲成人av片在线观看| 国产精品美女主播在线观看纯欲| 91亚洲精品一区二区| 中文字幕日韩在线播放| 97精品视频在线| 欧美成人一区二区三区电影| 国产激情综合五月久久| 亚洲欧洲国产一区| 91深夜福利视频| 亚洲人成网7777777国产| 欧美精品18videos性欧美| 97成人精品区在线播放| 国产网站欧美日韩免费精品在线观看| 国产成+人+综合+亚洲欧美丁香花| 欧美性xxxxhd| 欧美激情区在线播放| 亚洲性夜色噜噜噜7777| 久久久久久国产精品三级玉女聊斋| 97视频在线观看免费高清完整版在线观看| 黄色一区二区三区| 国语自产偷拍精品视频偷| 亚洲一区二区三区视频| 久久精品国产免费观看| 欧洲日韩成人av| 欧美激情乱人伦一区| 伊人青青综合网站| 97在线观看视频| 欧美国产日韩一区二区在线观看| 欧美日韩色婷婷| 韩国19禁主播vip福利视频| 日韩精品在线免费观看视频| 精品一区二区三区四区| 久久香蕉精品香蕉| 亚洲国产精品久久久久久| 国产欧美亚洲视频| 中文字幕亚洲综合| 久久久久国产视频| 青青草国产精品一区二区| 亚洲色图色老头| 欧美色播在线播放| 韩国三级日本三级少妇99| 国语自产精品视频在线看一大j8| 国产91在线播放九色快色| 久久久久九九九九| 亚洲第一国产精品| 国产精品亚洲一区二区三区| 久久久精品国产网站| 精品magnet| 国产又爽又黄的激情精品视频| 亚洲精品一区中文字幕乱码| 热99精品里视频精品| 国产成人在线视频| 日韩极品精品视频免费观看| 福利一区视频在线观看| 91美女片黄在线观| 成人亚洲欧美一区二区三区| 亚洲性视频网址| 亚洲欧美日韩一区二区三区在线| 欧美性高潮在线| 亚洲欧美日韩中文在线制服| 国产91在线高潮白浆在线观看| 亚洲国产精品专区久久| 在线观看国产成人av片| 伊人男人综合视频网| 久久视频中文字幕| 欧美性生交xxxxx久久久| 91精品免费久久久久久久久| 亚洲人成在线一二| 久久久精品一区| 精品无人区乱码1区2区3区在线| 久久精品国产欧美亚洲人人爽| 亚洲第一天堂无码专区| 成人免费自拍视频| 人妖精品videosex性欧美| 国产精品吹潮在线观看| 欧美成人精品不卡视频在线观看| 日韩精品中文字幕视频在线| 久久综合伊人77777蜜臀| 国产成人综合精品在线| 国产精品国产三级国产aⅴ9色| 欧美福利小视频| 97香蕉久久夜色精品国产| 亚洲a成v人在线观看| 欧美日韩国产一区中文午夜| www.亚洲男人天堂| 亚洲免费高清视频| 蜜臀久久99精品久久久久久宅男| 日韩电影中文字幕av| 国产婷婷97碰碰久久人人蜜臀| 成人夜晚看av| 日韩欧美在线网址| 国产成人精品一区二区| 庆余年2免费日韩剧观看大牛| 精品久久国产精品| 欧美男插女视频| 欧美黄色免费网站| 4p变态网欧美系列| 欧美理论电影在线观看| 91黑丝高跟在线| 亚洲成av人片在线观看香蕉| 国产a∨精品一区二区三区不卡| 77777亚洲午夜久久多人| 精品久久久久久久久久久久久| 日本19禁啪啪免费观看www| 91色在线视频| 日本精品久久中文字幕佐佐木| 久久青草精品视频免费观看| 91久久国产综合久久91精品网站| 丰满岳妇乱一区二区三区| 久久久久久久国产精品视频| 国产精品专区第二| 欧美精品做受xxx性少妇| 亚洲成人精品久久久| 久久国产精品免费视频| 亚洲成人黄色网| 91av在线免费观看视频|