| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 892 人关注过本帖
标题:调用指针的
只看楼主 加入收藏
liu0919
Rank: 2
等 级:论坛游民
帖 子:124
专家分:35
注 册:2013-5-13
收藏
得分:0 
回复 20楼 liu0919
我对调用函数 就是比如 int *(int h)我在书上看到过,不过对加了*调用就不会了
2014-01-02 19:14
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
你1樓代碼的編譯結果是“警告    1    warning C4172: 返回局部变量或临时变量的地址”。

11樓代碼子函數的意圖,是對外部數據a賦值,并返回a自身。這個函數使用了strcpy()複製數據,但沒有限定目標空間的尺寸,當t的數據量比a(函數中的source其實就是上層的a)多時,就會溢出(strcpy()函數本來就是應被廢棄的庫函數)。這還是小問題,那代碼最大的問題,在於誤導調用者main()以爲函數test()真的分配并返回了一個字符串給自己,而沒意識實際上是自己的a字符串被使用,在main()函數中,那個a[]數組看起來被廢棄了,它僅僅把初始化了a[]送給函數test()而已,卻沒有跡象顯示test()會修改a[]的内容,這不僅僅是代碼不清晰,還是誤導性的,當閲讀者看不到test()的實現代碼時,就會莫明其妙。較爲好點的寫法,是這樣:

程序代码:
#include <cstdio>
#include <cstring>

void test(char* source, int size);

int main(int argc, char* argv[])
{
    char a[100];
   
    test(a, sizeof(a) - 1);    // 很明確這將會修改a的内容,而且不需對a初始化
    printf("%s\n", a);         // 明確使用的是a,不是test()產生的字符串,test()祇是負責給a[]賦值而已

    return 0;
}

void test(char* source, int size)
{
    char t[]="这个准备返回给主函数";
     strncpy(source, t, size);
}

不讓test()返回字符指針,是刻意而爲,目的就是避免前述誤導效應,除非設計test()用返回結果標識錯誤狀態,即使是後者,也應使用邏輯型或數值型返回值,不用指針(NULL)。

用char* test()聲明返回字符指針,可能誤導調用者以爲char* p = test(a)也是可以的,似乎test()會給指針p分配内存,實際上沒有,但用我現在這種寫法,你絕不會在沒對char* p分配空間的情況下就調用test(p),因爲在本代碼段就已經看出問題了。也不推薦在test()中用malloc()給指針型參數分配空間然後返回,調用者并不覺得他有free(p)的義務,畢竟不是他malloc()的,那種用法還有更深層的隱患,在多次調用test()的時候就很容易出現内存泄漏了。

[ 本帖最后由 TonyDeng 于 2014-1-2 20:21 编辑 ]
收到的鲜花
  • liu09192014-01-02 22:26 送鲜花  5朵   附言:我很赞同

授人以渔,不授人以鱼。
2014-01-02 20:01
liu0919
Rank: 2
等 级:论坛游民
帖 子:124
专家分:35
注 册:2013-5-13
收藏
得分:0 
回复 22楼 TonyDeng
程序代码:
#include<stdio.h>
char *dd(void);
int main()
{
    printf("%s",dd());

    return 0;
}

char *dd(void)
{
    char *s;
    s=(char*)malloc(3*sizeof(char));
    s[0]='d';
    s[1]='g';
    s[2]='\0';
    return s;
}

#include<stdio.h>  //为什么这个在char *dd(void)将s声明为数组时就不能返回了,而上面那个把它定义为指针时就可以返回
char *dd(void);
int main()
{
    printf("%s",dd());

    return 0;
}

char *dd(void)
{
    char s[3];
    s[0]='d';
    s[1]='s';
    s[2]='\0';
    return s;
}

2014-01-02 22:56
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
數組和指針實際上是不一樣的,前面的僅僅返回一個指針值,跟普通數據一樣,後面是數組,那是局部數據塊。函數返回數據的方式,其實是把要返回的數據複製到某個中間變量中,然後調用者再把該處的數據通過賦值操作取回去,單純的指針值可以賦值,但數組是一塊的,普通的賦值操作沒用(這就是數組和字符串無法使用=操作符的原因),編譯器能檢查出聲明爲指針和聲明爲數組的變量是不一樣的,它知道這樣返回不行,就給出報告。其實像1樓代碼那個警告信息,在舊式編譯器中是沒有的,有些編譯器,給出警告也可以强制忽略通過,祇有把警告級別提升爲錯誤對待的編譯器,才編譯不成功。

23樓第一個代碼,正是我22樓最後一段補充不推薦的東西。用malloc()分配的内存,不會隨著函數的終結而失效,第二種代碼的數組是會失效的,所以前面的編譯器不認爲有問題,後面的就有問題了。

[ 本帖最后由 TonyDeng 于 2014-1-2 23:23 编辑 ]

授人以渔,不授人以鱼。
2014-01-02 23:10
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:0 
以下是引用TonyDeng在2014-1-2 16:40:33的发言:

脫褲子放屁的代碼。說難聽點,把樓主教壞的,就是這種。



我又不是写给你看的   你管得着????

DO IT YOURSELF !
2014-01-03 08:44
快速回复:调用指针的
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019850 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved