VBGood网站全文搜索 Google

搜索VBGood全站网页(全文搜索)

VB爱好者乐园(VBGood)

 找回密码
 立即注册
搜索
楼主: VBProFan

【讨论】关于返回C语言局部指针变量的有趣&奇怪问题

[复制链接]
 楼主| 发表于 2010-5-26 11:43:58 | 显示全部楼层
泡饭你这个代码写得很不严谨啊……虽然返回结果是对的,但是指不定什么时候就出莫名其妙的错误了……

相对标准一点的写法是:
acme_pjz 发表于 2010-5-26 11:23


虽然返回结果是对的,但是在使用返回结果前这个结果已经被其他东西覆盖了,所以用不了了……

加个 static 就放在全局数据区了,不加 static 就放在局部临时堆栈区。
中括号里面的数字不写也行的,编译器会自己扫描代码自动填上去,如果填了反而不好,万一改了后面不记得改数字那就杯具了~~
回复 支持 反对

使用道具 举报

发表于 2010-5-26 11:53:03 | 显示全部楼层
11# VBProFan

一般你的函数返回的不是一个固定的字符串吧,一般都运算一下的……所以要创建一个足够大小的缓冲区……
回复 支持 反对

使用道具 举报

 楼主| 发表于 2010-5-26 14:18:52 | 显示全部楼层
12# acme_pjz

一般字符串函数都不创建空间,而由调用者申请空间,然后把空间首地址传给字符串处理函数,然后函数内操作这片内存……
回复 支持 反对

使用道具 举报

发表于 2010-5-26 15:05:16 | 显示全部楼层
相对标准一点的写法是:
#include <stdio.h>
char *GetString(void)
{
    static char p[最好指定一个大小] = "ABCDE";
    return p;   
}
void main()
{
    printf("%s\n", GetString());
}

acme_pjz 发表于 2010-5-26 11:23


之前在两个cpp里写全局变量,结果得不到预期结果
把变量声明成static也不行
后来就是用这个方法搞定的
在函数内部声明static的空间,然后返回地址
回复 支持 反对

使用道具 举报

发表于 2010-5-26 22:44:57 | 显示全部楼层
13# VBProFan

嗯,不过有些人喜欢写返回内部的字符串指针……
回复 支持 反对

使用道具 举报

发表于 2010-5-28 08:16:47 | 显示全部楼层
泡饭你这个代码写得很不严谨啊……虽然返回结果是对的,但是指不定什么时候就出莫名其妙的错误了……

相对标准一点的写法是:
acme_pjz 发表于 2010-5-26 11:23

要是偶就写成
  1. typedef GetString "ABCDE"或者const GETSTRING = "ABCDE"
复制代码




不过VB有点奇怪,竟然可以
  1. function GetString() as stringGetString="ABCDE"end functionsub main    debug.print GetStringend sub
复制代码
回复 支持 反对

使用道具 举报

发表于 2010-5-28 17:09:56 | 显示全部楼层
16# msflexgrid

typedef GetString "ABCDE"或者const GETSTRING = "ABCDE"
?,你难道不知道#define么????……另外const GETSTRING =***这个好像不行吧,没有变量类型……难道是C#???

VB里面那个String几乎完全不同于char*,估计和<string>差不多,封装了一下……
回复 支持 反对

使用道具 举报

发表于 2010-5-28 21:45:33 | 显示全部楼层
16# msflexgrid  

?,你难道不知道#define么????……另外const GETSTRING =***这个好像不行吧,没有变量类型……难道是C#???

VB里面那个String几乎完全不同于char*,估计和差不多,封装了一下……
acme_pjz 发表于 2010-5-28 17:09


public/private/ const GETSTRING=*** 这是VB
回复 支持 反对

使用道具 举报

发表于 2010-6-20 22:17:44 | 显示全部楼层
1# VBProFan
这个问题也是和底层相关的。在现代的操作系统中,程序运行时内存空间普遍分为四段:代码区(code area)、全局数据区(data area)、堆区(heap area)、栈区(stack area)。其中:
  • 代码区:存放程序的代码,即程序中的各个函数代码块和直接量(常量)。
  • 全局数据区:全局变量和静态变量。
  • 堆区:通过malloc等动态申请的空间。
  • 栈区:局部变量等数据,即各个函数中的数据。
其中代码区时只读区域。


问题中,当使用char p[] = "ABCD";时,是在函数GetString里定义了一个局部变量,因此它是在栈空间里。当函数每次被调用时,都会重新分配空间,并赋初始值,当函数返回时这片空间会被释放。因此在main中显示返回值时,这片空间已经被释放,就是一片乱码。

当使用char *p = "ABCD"; p也是一个局部变量,但它指向了“代码区”的一个地址("ABCD"是直接量,在只读的代码区中,并且位置固定不变,上同)。因此函数仅返回这个字符串的地址,因此可以显示。

总结地说:就是第一段代码里其实有两个值为“ABCD”的字符串(代码区中一个,函数的栈空间里一个),但返回的是栈空间的字符串的地址;第二段则只有在代码区里一个字符串。
回复 支持 反对

使用道具 举报

发表于 2010-6-20 23:27:49 | 显示全部楼层
19# redraiment

好像静态常量区也是只读的吧……
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

文字版|手机版|小黑屋|VBGood  

GMT+8, 2023-3-22 05:24

VB爱好者乐园(VBGood)
快速回复 返回顶部 返回列表