網站首頁 編程語言 正文
C語言函數返回值不一致
在運行成程序上有時會發現函數內部的值與返回到主函數的值會相差很多出現隨機值,但是它們的地址卻相同!**一般的原因多是內存污染,多發于函數返回數組地址**或返回主函數后直接應用。
例如下面的兩個程序,不用關心它做了什么,只需觀察它們的不同點(已注釋)
#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}; //關鍵!!!內存污染問題!
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;
}
運行如下:
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}; !!!注意不同!!!內存污染問題!**
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;
}
運行如下:
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 //!!!!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; // !!!!
此示例運用了分配內存的方法cmalloc()函數來替代直接創建的數組;
這是我在學習是遇到的小陷阱,根據電腦系統與編譯器的不同可能不會出錯,具體污染原因還是沒有整明白。還是要注意留心。
函數的返回值注意事項
函數的返回值
一般情況下,通過函數的調用,使調用函數可以獲得被調用函數的函數值,這個值就叫做返回值。
注意事項
①、有的函數有返回值,有的函數沒有返回值,具體看函數的聲明類型,如果返回值類型為 void 則為無返回值類型;
②、函數的返回值是通過函數中的 return 語句獲得的。一個函數中可以有一個以上的return語句,執行到哪個return就從哪個return返回了,return語句執行完之后,他之后的代碼不會被執行;
③、函數內部的return返回值類型要與函數本身定義時候的返回值類型一致,即使不一致也是可以相互轉化的,最終以函數定義時候的返回值類型為主進行轉化,若轉化不了則編譯期間就報錯了;
④、原則上一個函數只能有一個返回值,若要返回多個值則可以通過參數返回或者返回結構類型等等。
總結
原文鏈接:https://blog.csdn.net/m0_46248694/article/details/108041286
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-03-24 詳析C#的協變和逆變_C#教程
- 2022-07-08 python?讀寫csv文件方式(創建,追加,覆蓋)_python
- 2022-01-01 element對穿梭框對接口返回的數據其他字段進行校驗多個校驗
- 2022-10-31 Python?NumPy創建數組方法_python
- 2023-03-19 Python學習之configparser模塊的使用詳解_python
- 2022-06-22 python?實現?mp3Play?音頻播放_python
- 2023-03-18 Kotlin?Fragment使用方法詳解_Android
- 2022-06-07 使用Docker創建FTP服務器的過程解析_docker
- 欄目分類
-
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支