C語(yǔ)言中函數(shù)返回值不一致問題
C語(yǔ)言函數(shù)返回值不一致
在運(yùn)行成程序上有時(shí)會(huì)發(fā)現(xiàn)函數(shù)內(nèi)部的值與返回到主函數(shù)的值會(huì)相差很多出現(xiàn)隨機(jī)值,但是它們的地址卻相同!**一般的原因多是內(nèi)存污染,多發(fā)于函數(shù)返回?cái)?shù)組地址**或返回主函數(shù)后直接應(yīng)用。
例如下面的兩個(gè)程序,不用關(guān)心它做了什么,只需觀察它們的不同點(diǎn)(已注釋)
#include <stdio.h> #include <ctype.h> int *count_e(char *str); int main(){ char str[] = {"abc,cba,def"}; int *a,i; a = count_e(str); puts("\n"); for(i=0;i<5;i++){ printf(" a[%d] = %d ; &a = %p;\n",i,a[i],&a[i]); } free(a); return 0; } int *count_e(char *str){ if(str == NULL) return NULL; int ls[5] = {0}; //關(guān)鍵?。。?nèi)存污染問題! int i,k,t; i = k = t = 0; while(isspace(str[i])) i++; while(str[i]){ if(isupper(str[i])){ ls[1]++;k=1; }else if(islower(str[i])){ ls[2]++;k=1; }else if(isdigit(str[i])){ ls[4]++;k=1; }else if(isspace(str[i])){ t = 1; }else{ ls[3]++;t=1; } if(k==1 && t ==1){ ls[0]++; k = t = 0; } i++; } for(t=0;t<5;t++) printf("ls[%d] = %d ; &ls[i] = %p\n",t,ls[t],&ls[t]); if(! isspace(str[--i])) ls[0]++; return ls; }
運(yùn)行如下:
ls[0] = 2 ; &ls[i] = 000000000062FDB0
ls[1] = 0 ; &ls[i] = 000000000062FDB4
ls[2] = 9 ; &ls[i] = 000000000062FDB8
ls[3] = 2 ; &ls[i] = 000000000062FDBC
ls[4] = 0 ; &ls[i] = 000000000062FDC0 // ?。?!a[0] = 239139376 ; &a = 000000000062FDB0;
a[1] = 32760 ; &a = 000000000062FDB4;
a[2] = 1 ; &a = 000000000062FDB8;
a[3] = 0 ; &a = 000000000062FDBC;
a[4] = 11146080 ; &a = 000000000062FDC0; // ?。?!注意
------------------------------------分割線-----------------------------------------
#include <stdio.h> #include <ctype.h> int *count_e(char *str); int main(){ char str[] = {"abc,cba,def"}; int *a,i; a = count_e(str); for(i=0;i<5;i++){ printf(" a[%d] = %d ; &a = %p;\n",i,a[i],&a[i]); } free(a); return 0; } int *count_e(char *str){ if(str == NULL) return NULL; int *ls = (int *)calloc(5,sizeof(int)); //ls[5] = {0}; !??!注意不同?。?!內(nèi)存污染問題!** int i,k,t; i = k = t = 0; while(isspace(str[i])) i++; while(str[i]){ if(isupper(str[i])){ ls[1]++;k=1; }else if(islower(str[i])){ ls[2]++;k=1; }else if(isdigit(str[i])){ ls[4]++;k=1; }else if(isspace(str[i])){ t = 1; }else{ ls[3]++;t=1; } if(k==1 && t ==1){ ls[0]++; k = t = 0; } i++; } for(t=0;t<5;t++) printf("ls[%d] = %d ; &ls[i] = %p\n",t,ls[t],&ls[t]); if(! isspace(str[--i])) ls[0]++; return ls; }
運(yùn)行如下:
ls[0] = 2 ; &ls[i] = 00000000001D1430
ls[1] = 0 ; &ls[i] = 00000000001D1434
ls[2] = 9 ; &ls[i] = 00000000001D1438
ls[3] = 2 ; &ls[i] = 00000000001D143C
ls[4] = 0 ; &ls[i] = 00000000001D1440 //?。。。?/p>a[0] = 3 ; &a = 00000000001D1430;
a[1] = 0 ; &a = 00000000001D1434;
a[2] = 9 ; &a = 00000000001D1438;
a[3] = 2 ; &a = 00000000001D143C;
a[4] = 0 ; &a = 00000000001D1440; // ?。。?!
此示例運(yùn)用了分配內(nèi)存的方法cmalloc()函數(shù)來替代直接創(chuàng)建的數(shù)組;
這是我在學(xué)習(xí)是遇到的小陷阱,根據(jù)電腦系統(tǒng)與編譯器的不同可能不會(huì)出錯(cuò),具體污染原因還是沒有整明白。還是要注意留心。
函數(shù)的返回值注意事項(xiàng)
函數(shù)的返回值
一般情況下,通過函數(shù)的調(diào)用,使調(diào)用函數(shù)可以獲得被調(diào)用函數(shù)的函數(shù)值,這個(gè)值就叫做返回值。
注意事項(xiàng)
①、有的函數(shù)有返回值,有的函數(shù)沒有返回值,具體看函數(shù)的聲明類型,如果返回值類型為 void 則為無返回值類型;
②、函數(shù)的返回值是通過函數(shù)中的 return 語(yǔ)句獲得的。一個(gè)函數(shù)中可以有一個(gè)以上的return語(yǔ)句,執(zhí)行到哪個(gè)return就從哪個(gè)return返回了,return語(yǔ)句執(zhí)行完之后,他之后的代碼不會(huì)被執(zhí)行;
③、函數(shù)內(nèi)部的return返回值類型要與函數(shù)本身定義時(shí)候的返回值類型一致,即使不一致也是可以相互轉(zhuǎn)化的,最終以函數(shù)定義時(shí)候的返回值類型為主進(jìn)行轉(zhuǎn)化,若轉(zhuǎn)化不了則編譯期間就報(bào)錯(cuò)了;
④、原則上一個(gè)函數(shù)只能有一個(gè)返回值,若要返回多個(gè)值則可以通過參數(shù)返回或者返回結(jié)構(gòu)類型等等。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)貪吃蛇游戲(單人版)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)貪吃蛇游戲單人版,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06c++11中regex正則表達(dá)式示例簡(jiǎn)述
這篇文章主要給大家介紹了關(guān)于c++11中regex正則表達(dá)式的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用c++11具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11C語(yǔ)言實(shí)現(xiàn)頁(yè)面置換 先進(jìn)先出算法(FIFO)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)頁(yè)面置換,先進(jìn)先出算法(FIFO),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12