林锐《高质量c/c++编程》:指针参数是如何传递内存的?一问

mengguangyao 2004-10-11 02:57:01
指针参数是如何传递内存的?
如果函数的参数是一个指针,不要指望用该指针去申请动态内存。
Test 函数的语句GetMemory(str, 200)并没有使str 获得期望的内存,str 依旧是NULL,
为什么?
void GetMemory(char *p, int num)
{
p = (char *)malloc(sizeof(char) * num);
}
void Test(void)
{
char *str = NULL;
GetMemory(str, 100); // str 仍然为 NULL
strcpy(str, "hello"); // 运行错误
}
毛病出在函数GetMemory 中。编译器总是要为函数的每个参数制作临时副本,指针
参数p 的副本是 _p,编译器使 _p = p。
--如果函数体内的程序修改了_p 的内容,就导致参数p 的内容作相应的修改。这就是指针可以用作输
--出参数的原因。在本例中,_p 申请了新的内存,只是把_p 所指的内存地址改变了,但是p 丝毫未
--变。所以函数GetMemory并不能输出任何东西。
事实上,每执行一次GetMemory 就会泄露一块内存,因为没有用free 释放内存。

以上摘自林锐《高质量..》
问题:
在--标出的一段中:
有“如果函数体内的程序修改了_p 的内容,就导致参数p 的内容作相应的修改。”--明明说能改
和“在本例中,_p 申请了新的内存,只是把_p 所指的内存地址改变了,但是p 丝毫未变”--可是..
这两句让我云里雾里,哪位大虾给个解释?
谢谢!
...全文
263 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
zengcity 2004-10-22
  • 打赏
  • 举报
回复
好贴,学习~
nlstone 2004-10-11
  • 打赏
  • 举报
回复
在delete []s;一句处报错,是何原因?谢谢!
---------------------------------------
注意观察s自new开始后的地址变化!

s = "";这样的操作可不是你想像的给s所在地址赋值


用指针做参数的时候,实际就是传指针自身的值(也就是指针的地址,一个32位int)
如果你想在函数内改变指针的指向或为指针new空间,通常是用指针的指针作参数(char** p)
ywfscu 2004-10-11
  • 打赏
  • 举报
回复
c语言里函数传递都是传值,包括指针,!
mengguangyao 2004-10-11
  • 打赏
  • 举报
回复
“指针作为参数,仍是值传递”?我记得好像是“传递地址”啊。如果是“值传递”,那怎么才是传地址呢?
另外:
如果我在main()函数中,先初始化s,即如下代码
void func(char *str)
{
str = "hello world";
}
void main()
{
char *s = new char[20];
s = "";

func(s);
printf("%s",s);
delete []s;
}
在delete []s;一句处报错,是何原因?谢谢!
kobefly 2004-10-11
  • 打赏
  • 举报
回复
"hello world";
存放在静态存储区
所以S得值没有改变
出了函数
加上本来没有初始化
所以输出乱码
zhangfjj 2004-10-11
  • 打赏
  • 举报
回复
指针作为参数,仍是值传递,
但传递的是指针值,
这样就可以间接访问被调函数之外的变量了。就是这!!!!
zhangfjj 2004-10-11
  • 打赏
  • 举报
回复
void func(char *str)
{
str = "hello world";//改成这样可能更清楚些
}
void main()
{
char *s = new char[20];

func(s);
printf("%s",s);
delete []s;
}

main() s
******
* *---->指向new char[20],其值为这20个字节的首地址,它们未初始化
******
------------------------------
func()
str
******
* *---->接收了实参s的值,同样指向20个字节的首地址
******

在函数中,改变的是str的指向,
str="hello,world!"
返回时,释放str,实参s的值并未变化
所以输出乱码。

mengguangyao 2004-10-11
  • 打赏
  • 举报
回复
void func(char *s)
{
s = "hello world";
}
void main()
{
char *s = new char[20];

func(s);
printf("%s",s);
delete []s;
}
输出的是乱码。(在vc6.0下)
我想知道为什么?
kobefly 2004-10-11
  • 打赏
  • 举报
回复
输出hello world啊
说得说是s不会改变
但是s指向得内容会改变

void func(char *s)
{ char *ss = "not hello word!";
s = ss;
}
void main()
{
char *s = new char[20];

func(s);
printf("%s",s);
delete []s;
}
输出hello world
而不是not hello world

hackingtruth 2004-10-11
  • 打赏
  • 举报
回复
以前也迷惑过. 不过我认为. 指针_P, 改变了它的值, 就会反应到P中, 应该说的是它所指向的内容, 而它本身的值改变的话, 是不会影响到P的.

同意 jumpandfly(飞狐)
mengguangyao 2004-10-11
  • 打赏
  • 举报
回复
俺不懂...
那么下面这个函数输出什么呢?
void func(char *s)
{
s = "hello world";
}
void main()
{
char *s = new char[20];

func(s);
printf("%s",s);
delete []s;
}
jumpandfly 2004-10-11
  • 打赏
  • 举报
回复
“如果函数体内的程序修改了_p 的内容,就导致参数p 的内容作相应的修改。”--说的是p指向的内容被改写,而不是p自己被改,可能是作者省了几个字吧

kobefly 2004-10-11
  • 打赏
  • 举报
回复
呵呵
这个问题啊
他是说指针做参数
指针得值
即所指向得地址是不会改变得
你用它得副本另外申请内存
是它得副本指向了新得地址
而传入参数是不变得拉
高质量C/C++编程指南.PDF 作者:林锐 目录: 前 言 第1章 文件结构 1.1 版权和版本的声明 1.2 头文件的结构 1.3 定义文件的结构 1.4 头文件的作用 1.5 目录结构 第2章 程序的版式 2.1 空行 2.2 代码行 2.3 代码行内的空格 2.4 对齐 2.5 长行拆分 2.6 修饰符的位置 2.7 注释 2.8 类的版式 第3章 命名规则 3.1 共性规则 3.2 简单的Windows应用程序命名规则 3.3 简单的Unix应用程序命名规则 第4章 表达式和基本语句 4.1 运算符的优先级 4.2 复合表达式 4.3 if 语句 4.4 循环语句的效率 4.5 for 语句的循环控制变量 4.6 switch语句 4.7 goto语句 第5章 常量 5.1 为什么需要常量 5.2 const 与 #define的比较 5.3 常量定义规则 5.4 类中的常量 第6章 函数设计 6.1 参数的规则 6.2 返回值的规则 6.3 函数内部实现的规则 6.4 其它建议 6.5 使用断言 6.6 引用与指针的比较 第7章 内存管理 7.1内存分配方式 7.2常见的内存错误及其对策 7.3指针与数组的对比 7.4指针参数是如何传递内存的? 7.5 free和delete把指针怎么啦? 7.6 动态内存会被自动释放吗? 7.7 杜绝“野指针” 7.8 有了malloc/free为什么还要new/delete ? 7.9 内存耗尽怎么办? 7.10 malloc/free 的使用要点 7.11 new/delete 的使用要点 7.12 一些心得体会 第8章 C++函数的高级特性 8.1 函数重载的概念 8.2 成员函数的重载、覆盖与隐藏 8.3 参数的缺省值 8.4 运算符重载 8.5 函数内联 8.6 一些心得体会 第9章 类的构造函数、析构函数与赋值函数 9.1 构造函数与析构函数的起源 9.2 构造函数的初始化表 9.3 构造和析构的次序 9.4 示例:类String的构造函数与析构函数 9.5 不要轻视拷贝构造函数与赋值函数 9.6 示例:类String的拷贝构造函数与赋值函数 9.7 偷懒的办法处理拷贝构造函数与赋值函数 9.8 如何在派生类中实现类的基本函数 9.9 一些心得体会 第10章 类的继承与组合 10.1 继承 10.2 组合 第11章 其它编程经验 11.1 使用const提高函数的健壮性 11.2 提高程序的效率 11.3 一些有益的建议 参考文献 附录A :C++/C代码审查表 附录B :C++/C试题 附录C :C++/C试题的答案与评分标准
高质量C++编程指南(林锐)DOC版和pdf的合集 目 录 前 言 6 第1章 文件结构 11 1.1 版权和版本的声明 11 1.2 头文件的结构 12 1.3 定义文件的结构 13 1.4 头文件的作用 13 1.5 目录结构 14 第2章 程序的版式 15 2.1 空行 15 2.2 代码行 16 2.3 代码行内的空格 17 2.4 对齐 18 2.5 长行拆分 19 2.6 修饰符的位置 19 2.7 注释 20 2.8 类的版式 21 第3章 命名规则 22 3.1 共性规则 22 3.2 简单的WINDOWS应用程序命名规则 23 3.3 简单的UNIX应用程序命名规则 25 第4章 表达式和基本语句 26 4.1 运算符的优先级 26 4.2 复合表达式 27 4.3 IF 语句 27 4.4 循环语句的效率 29 4.5 FOR 语句的循环控制变量 30 4.6 SWITCH语句 30 4.7 GOTO语句 31 第5章 常量 33 5.1 为什么需要常量 33 5.2 CONST 与 #DEFINE的比较 33 5.3 常量定义规则 33 5.4 类中的常量 34 第6章 函数设计 36 6.1 参数的规则 36 6.2 返回值的规则 37 6.3 函数内部实现的规则 39 6.4 其它建议 40 6.5 使用断言 41 6.6 引用与指针的比较 42 第7章 内存管理 44 7.1内存分配方式 44 7.2常见的内存错误及其对策 44 7.3指针与数组的对比 45 7.4指针参数是如何传递内存的? 47 7.5 FREE和DELETE把指针怎么啦? 50 7.6 动态内存会被自动释放吗? 50 7.7 杜绝“野指针” 51 7.8 有了MALLOC/FREE为什么还要NEW/DELETE ? 52 7.9 内存耗尽怎么办? 53 7.10 MALLOC/FREE 的使用要点 54 7.11 NEW/DELETE 的使用要点 55 7.12 一些心得体会 56 第8章 C++函数的高级特性 57 8.1 函数重载的概念 57 8.2 成员函数的重载、覆盖与隐藏 60 8.3 参数的缺省值 63 8.4 运算符重载 64 8.5 函数内联 65 8.6 一些心得体会 68 第9章 类的构造函数、析构函数与赋值函数 69 9.1 构造函数与析构函数的起源 69 9.2 构造函数的初始化表 70 9.3 构造和析构的次序 72 9.4 示例:类STRING的构造函数与析构函数 72 9.5 不要轻视拷贝构造函数与赋值函数 73 9.6 示例:类STRING的拷贝构造函数与赋值函数 73 9.7 偷懒的办法处理拷贝构造函数与赋值函数 75 9.8 如何在派生类中实现类的基本函数 75 9.9 一些心得体会 77 第10章 类的继承与组合 78 10.1 继承 78 10.2 组合 80 第11章 其它编程经验 82 11.1 使用CONST提高函数的健壮性 82 11.2 提高程序的效率 84 11.3 一些有益的建议 85 参考文献 87 附录A :C++/C代码审查表 88 附录B :C++/C试题 93 附录C :C++/C试题的答案与评分标准 97
高质量C/C++编程指南》,作者:林锐,pdf 格式,大小 327KB。 目录: 前 言 ......................................................................................................................................6 第1 章文件结构....................................................................................................................8 1.1 版权和版本的声明........................................................................................................8 1.2 头文件的结构...............................................................................................................8 1.3 定义文件的结构...........................................................................................................8 1.4 头文件的作用...............................................................................................................8 1.5 目录结构.......................................................................................................................8 第2 章程序的版式................................................................................................................8 2.1 空行 ...............................................................................................................................8 2.2 代码行...........................................................................................................................8 2.3 代码行内的空格...........................................................................................................8 2.4 对齐 ...............................................................................................................................8 2.5 长行拆分.......................................................................................................................8 2.6 修饰符的位置...............................................................................................................8 2.7 注释 ...............................................................................................................................8 2.8 类的版式.......................................................................................................................8 第3 章命名规则....................................................................................................................8 3.1 共性规则.......................................................................................................................8 3.2 简单的 WINDOWS 应用程序命名规则.........................................................................8 3.3 简单的 UNIX 应用程序命名规则..................................................................................8 第4 章表达式和基本语句....................................................................................................8 4.1 运算符的优先级...........................................................................................................8 4.2 复合表达式...................................................................................................................8 4.3 IF 语句...........................................................................................................................8 4.4 循环语句的效率...........................................................................................................8 4.5 FOR 语句的循环控制变量............................................................................................8 4.6 SWITCH 语句..................................................................................................................8 4.7 GOTO 语句......................................................................................................................8 第5 章常量............................................................................................................................8 5.1 为什么需要常量...........................................................................................................8 5.2 CONST 与#DEFINE 的比较...........................................................................................8 5.3 常量定义规则...............................................................................................................8 5.4 类中的常量...................................................................................................................8 第6 章函数设计....................................................................................................................8 高质量C++/C 编程指南,v 1.0 2001 Page 4 of 101 6.1 参数的规则...................................................................................................................8 6.2 返回值的规则...............................................................................................................8 6.3 函数内部实现的规则....................................................................................................8 6.4 其它建议.......................................................................................................................8 6.5 使用断言.......................................................................................................................8 6.6 引用与指针的比较........................................................................................................8 第7 章内存管理....................................................................................................................8 7.1 内存分配方式................................................................................................................8 7.2 常见的内存错误及其对策.............................................................................................8 7.3 指针与数组的对比........................................................................................................8 7.4 指针参数是如何传递内存的?.....................................................................................8 7.5 FREE 和DELETE 把指针怎么啦?.................................................................................8 7.6 动态内存会被自动释放吗? ........................................................................................8 7.7 杜绝“野指针” ...........................................................................................................8 7.8 有了 MALLOC/FREE 为什么还要NEW/DELETE ?.......................................................8 7.9 内存耗尽怎么办?........................................................................................................8 7.10 MALLOC/FREE 的使用要点.........................................................................................8 7.11 NEW/DELETE 的使用要点...........................................................................................8 7.12 一些心得体会.............................................................................................................8 第8 章 C++函数的高级特性.................................................................................................8 8.1 函数重载的概念...........................................................................................................8 8.2 成员函数的重载、覆盖与隐藏....................................................................................8 8.3 参数的缺省值...............................................................................................................8 8.4 运算符重载...................................................................................................................8 8.5 函数内联.......................................................................................................................8 8.6 一些心得体会...............................................................................................................8 第9 章类的构造函数、析构函数与赋值函数.....................................................................8 9.1 构造函数与析构函数的起源........................................................................................8 9.2 构造函数的初始化表....................................................................................................8 9.3 构造和析构的次序........................................................................................................8 9.4 示例:类STRING 的构造函数与析构函数..................................................................8 9.5 不要轻视拷贝构造函数与赋值函数............................................................................8 9.6 示例:类STRING 的拷贝构造函数与赋值函数..........................................................8 9.7 偷懒的办法处理拷贝构造函数与赋值函数.................................................................8 9.8 如何在派生类中实现类的基本函数............................................................................8 9.9 一些心得体会...............................................................................................................8 第10 章类的继承与组合......................................................................................................8 高质量C++/C 编程指南,v 1.0 2001 Page 5 of 101 10.1 继承 .............................................................................................................................8 10.2 组合 .............................................................................................................................8 第11 章其它编程经验..........................................................................................................8 11.1 使用 CONST 提高函数的健壮性..................................................................................8 11.2 提高程序的效率..........................................................................................................8 11.3 一些有益的建议..........................................................................................................8 参考文献................................................................................................................................8 附录A :C++/C 代码审查表................................................................................................8 附录B :C++/C 试题............................................................................................................8 附录C :C++/C 试题的答案与评分标准.............................................................................8
目 录 前 言6 第1 章 文件结构 1.1 版权和版本的声明. 1.2 头文件的结构. 1.3 定义文件的结构. 1.4 头文件的作用. 1.5 目录结构. 第2 章 程序的版式 2.1 空行. 2.2 代码行. 2.3 代码行内的空格. 2.4 对齐. 2.5 长行拆分. 2.6 修饰符的位置. 2.7 注释. 2.8 类的版式. 第3 章 命名规则 3.1 共性规则. 3.2 简单的WINDOWS 应用程序命名规则. 3.3 简单的UNIX 应用程序命名规则 第4 章 表达式和基本语句 4.1 运算符的优先级. 4.2 复合表达式. 4.3 IF 语句 4.4 循环语句的效率. 4.5 FOR 语句的循环控制变量. 4.6 SWITCH 语句. 4.7 GOTO 语句. 第5 章 常量 5.1 为什么需要常量. 5.2 CONST 与 #DEFINE 的比较. 5.3 常量定义规则. 5.4 类中的常量. 第6 章 函数设计 高质量C++/C 编程指南,v 1.0 2001 Page 4 of 101 6.1 参数的规则. 6.2 返回值的规则. 6.3 函数内部实现的规则. 6.4 其它建议. 6.5 使用断言. 6.6 引用与指针的比较. 第7 章 内存管理 7.1 内存分配方式 7.2 常见的内存错误及其对策 7.3 指针与数组的对比 7.4 指针参数是如何传递内存的? 7.5 FREE 和DELETE 把指针怎么啦? 7.6 动态内存会被自动释放吗?. 7.7 杜绝“野指针”. 7.8 有了MALLOC/FREE 为什么还要NEW/DELETE ?. 7.9 内存耗尽怎么办?. 7.10 MALLOC/FREE 的使用要点 7.11 NEW/DELETE 的使用要点. 7.12 一些心得体会 第8 章 C++函数的高级特性 8.1 函数重载的概念. 8.2 成员函数的重载、覆盖与隐藏. 8.3 参数的缺省值. 8.4 运算符重载. 8.5 函数内联. 8.6 一些心得体会. 第9 章 类的构造函数、析构函数与赋值函数 9.1 构造函数与析构函数的起源. 9.2 构造函数的初始化表. 9.3 构造和析构的次序. 9.4 示例:类STRING 的构造函数与析构函数 9.5 不要轻视拷贝构造函数与赋值函数. 9.6 示例:类STRING 的拷贝构造函数与赋值函数 9.7 偷懒的办法处理拷贝构造函数与赋值函数. 9.8 如何在派生类中实现类的基本函数. 9.9 一些心得体会. 第10 章 类的继承与组合. 高质量C++/C 编程指南,v 1.0 2001 Page 5 of 101 10.1 继承 10.2 组合 第11 章 其它编程经验. 11.1 使用CONST 提高函数的健壮性 11.2 提高程序的效率 11.3 一些有益的建议 参考文献 附录A :C++/C 代码审查表. 附录B :C++/C 试题. 附录C :C++/C 试题的答案与评分标准.
作者:林锐 前 言... 6 第1章 文件结构... 11 1.1 版权和版本的声明... 11 1.2 头文件的结构... 12 1.3 定义文件的结构... 13 1.4 头文件的作用... 13 1.5 目录结构... 14 第2章 程序的版式... 15 2.1 空行... 15 2.2 代码行... 16 2.3 代码行内的空格... 17 2.4 对齐... 18 2.5 长行拆分... 19 2.6 修饰符的位置... 19 2.7 注释... 20 2.8 类的版式... 21 第3章 命名规则... 22 3.1 共性规则... 22 3.2 简单的Windows应用程序命名规则... 23 3.3 简单的Unix应用程序命名规则... 25 第4章 表达式和基本语句... 26 4.1 运算符的优先级... 26 4.2 复合表达式... 27 4.3 if 语句... 27 4.4 循环语句的效率... 29 4.5 for 语句的循环控制变量... 30 4.6 switch语句... 30 4.7 goto语句... 31 第5章 常量... 33 5.1 为什么需要常量... 33 5.2 const 与 #define的比较... 33 5.3 常量定义规则... 33 5.4 类中的常量... 34 第6章 函数设计... 36 6.1 参数的规则... 36 6.2 返回值的规则... 37 6.3 函数内部实现的规则... 39 6.4 其它建议... 40 6.5 使用断言... 41 6.6 引用与指针的比较... 42 第7章 内存管理... 44 7.1内存分配方式... 44 7.2常见的内存错误及其对策... 44 7.3指针与数组的对比... 45 7.4指针参数是如何传递内存的?... 47 7.5 free和delete把指针怎么啦?... 50 7.6 动态内存会被自动释放吗?... 50 7.7 杜绝“野指针”... 51 7.8 有了malloc/free为什么还要new/delete ?... 52 7.9 内存耗尽怎么办?... 53 7.10 malloc/free 的使用要点... 54 7.11 new/delete 的使用要点... 55 7.12 一些心得体会... 56 第8章 C++函数的高级特性... 57 8.1 函数重载的概念... 57 8.2 成员函数的重载、覆盖与隐藏... 60 8.3 参数的缺省值... 63 8.4 运算符重载... 64 8.5 函数内联... 65 8.6 一些心得体会... 68 第9章 类的构造函数、析构函数与赋值函数... 69 9.1 构造函数与析构函数的起源... 69 9.2 构造函数的初始化表... 70 9.3 构造和析构的次序... 72 9.4 示例:类String的构造函数与析构函数... 72 9.5 不要轻视拷贝构造函数与赋值函数... 73 9.6 示例:类String的拷贝构造函数与赋值函数... 73 9.7 偷懒的办法处理拷贝构造函数与赋值函数... 75 9.8 如何在派生类中实现类的基本函数... 75 9.9 一些心得体会... 77 第10章 类的继承与组合... 78 10.1 继承... 78 10.2 组合... 80 第11章 其它编程经验... 82 11.1 使用const提高函数的健壮性... 82 11.2 提高程序的效率... 84 11.3 一些有益的建议... 85 参考文献... 87 附录A :C++/C代码审查表... 88 附录B :C++/C试题... 93 附录C :C++/C试题的答案与评分标准

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧