`

C语言传值操作

阅读更多

C语言传值操作

    C语言中的函数参数传递都是传值操作,所以要使被调用函数改变调用函数的属性内容,则需要传递所需修改属性的指针——属性地址。

   例1:

void GetMemory(char *p)
{
    p = (char *)malloc(100);
}

void Test(void)
{
    char *str = NULL;
    GetMemory(str); 
    strcpy(str, "hello world");
    printf(str);
}

 

    请问运行Test 函数会有什么样的结果?

    答: 因为GetMemory函数接收的是str指针的拷贝 ,所以,当其退出时,str的拷贝p在栈中的内容会被释放,并且以上操作对Test 函数中的str没有影响, str一直都是 NULL strcpy(str, "hello world"); 将使 程序崩溃。

 
   例2:
Void GetMemory2(char **p, int num)
{
    *p = (char *)malloc(num);
}

void Test(void)
{
    char *str = NULL;
    GetMemory(&str, 100);
    strcpy(str, "hello");  
    printf(str);   
}
 

    请问运行Test 函数会有什么样的结果?

    答: 1 )能够输出hello; 2 )内存泄漏

     原因:以上两个对照说明形参只能传递地址不能传递值。

  例3:

char *GetMemory(void)
{  
    char p[] = "hello world";  //此行将p[]改成*p就对了,此时p[]存在
    return p;                         //于栈里边,*p的话字符串存于常量区
}

void Test(void)
{
    char *str = NULL;
    str = GetMemory();
    printf(str);
}

 

请问运行Test 函数会有什么样的结果?

 

    请问运行Test 函数会有什么样的结果?

    答: 可能是乱码。 因为GetMemory 返回的是指向“栈内存”的指针,该指针的地址不是 NULL ,但其原现的内容已经被清除,新内容不可知。

  例4:

void Test(void)
{
    char *str = (char *) malloc(100);
    strcpy(str, “hello”);
    free(str);
    if(str != NULL)
    {
      strcpy(str, “world”);
      printf(str);
     }
}
 

   答:篡改动态内存区的内容,后果难以预料,非常危险。

   因为free(str); 之后,str 成为野指针,

   if(str != NULL) 语句不起作用。谨记malloc之后一定记得free,free之后将指针NULL一下,以免形成野指针。
 
  以下摘自其他地方:
 例5:
void GetMemory(char **p,int num)
{ 
    /*p,指向指针的指针,*p,p指向的指针(即str),**p,最终的对象,str指向的单元*/
  *p=(char *)malloc(num);  
    //申请空间首地址付给传入的被p指向的指针,即str
}  
  
int main()
{
         char *str=NULL;
   GetMemory(&str,100);   //传入指针变量本身的地址
   strcpy(str,"hello");
   free(str);
   if(str!=NULL)
   {
      strcpy(str,"world");
   }       
   printf("\n str is %s",str); 软件开发网 www.mscto.com
   getchar();
}  
 
  问输出结果是什么?
  
   答案:输出str is world。
  free 只是释放的str指向的内存空间,它本身的值还是存在的.所以free之后,有一个好的习惯就是将str=NULL.此时str指向空间的内存已被回收,如果输出语句之前还存在分配空间的操作的话,这段存储空间是可能被重新分配给其他变量的,尽管这段程序确实是存在大大的问题(上面各位已经说得很清楚了),但是通常会打印出world来。这是因为,进程中的内存管理一般不是由操作系统完成的,而是由库函数自己完成的。当你malloc一块内存的时候,管理库向操作系统申请一块空间(可能会比你申请的大一些),然后在这块空间中记录一些管理信息(一般是在你申请的内存 前面一点),并将可用内存的地址返回。但是释放内存的时候,管理库通常都不会将内存还给操作系统,因此你是可以继续访问这块地址的。

分享到:
评论

相关推荐

    C语言解析教程(原书第4版)(美) 凯利.pdf

    5.7 函数调用和传值调用 5.8 开发大型程序 5.9 使用断言 5.10 作用域规则 5.10.1 平行和嵌套代码块 5.10.2 以调试为目的使用代码块 5.11 存储类型 5.11.1 auto存储类型 5.11.2 extern存储类型 5.11.3 register存储...

    谭浩强C语言设计第三版.pdf

     4.1.4 虚实结合与传值调用  4.1.5 递归函数  4.2 变量的存储属性  4.2.1 变量的作用域与生存期  4.2.2 C语言中变量的存储类型  4.2.3 通过const声明将变量存储在只读区  4.3 模块的编译与链接  4.3.1 分别...

    C语言进阶 作者 Wrestle.Wu

     堆和栈、全局变量和局部变量、生存期和作用域、内部函数和外部函数、指针变量、指针数组和数组指针、指针函数和函数指针、传址和传值、递归和嵌套、结构体和共用体、枚举、位域等较难理解的核心概念的阐述和对比...

    C语言进阶-牟海军.pdf

     堆和栈、全局变量和局部变量、生存期和作用域、内部函数和外部函数、指针变量、指针数组和数组指针、指针函数和函数指针、传址和传值、递归和嵌套、结构体和共用体、枚举、位域等较难理解的核心概念的阐述和对比...

    C语言实现的银行家算法

    刚编出的操作系统中银行家算法实现。其中的安全性算法没有分成子函数,整个程序只有main()函数,很简陋,望大虾们指点用子函数实现安全性算法的方法...主要是传值问题..或是跟好的实现方法.谢谢...

    数据结构(C语言描述)

    1.2.1 传值参数 2 1.2.2 模板函数 3 1.2.3 引用参数 3 1.2.4 常量引用参数 4 1.2.5 返回值 4 1.2.6 递归函数 5 1.3 动态存储分配 9 1.3.1 操作符new 9 1.3.2 一维数组 9 1.3.3 异常处理 10 1.3.4 操作符delete 10 ...

    C# WPF 通过委托实现多窗口间的传值的方法

    在使用WPF开发的时候就不免会遇到需要两个窗口间进行传值操作,当然多窗口间传值的方法有很多种,本文介绍的是使用委托实现多窗口间的传值。 在上代码之前呢,先简单介绍一下什么是C#中的委托(如果只想了解如何传值...

    C#.net常用函数和方法集

    C#调用C语言DLL文件示范 28 在C#中调用windowsAPI函数实例 31 使用C#跨平台调用p/invokeDllImport 32 C#调用C动态库 37 C#操作数据库简介 38 NET(C#)连接各类数据库 40 C#页面传值 44 C#存储过程从入门到熟练 51 asp...

    c++编程思想及读后感

    目 录 译者序 前言 第1章 对象的演化 1 1.1 基本概念 1 ...10.3.1 传值方式传递和返回 179 10.3.2 拷贝构造函数 182 10.3.3 缺省拷贝构造函数 187 10.3.4 拷贝构造函数方法的选择 188 10.4 指向成员的指针

    C++编程思想(中文版) chm

    本书作者根据自己学习C++的亲身体会及多年教学经验,用...10.3.1 传值方式传递和返回 179 10.3.2 拷贝构造函数 182 10.3.3 缺省拷贝构造函数 187 10.3.4 拷贝构造函数方法的选择 188 10.4 指向成员的指针 >>>>>>>>>.

    Go语言圣经,golang学习入门到精通

    Go从C语言继承了相似的表达式语 法、控制流结构、基础数据类型、调用参数传值、指针等很多思想,还有C语言一直所看中的编译后机器 码的运行效率以及和现有操作系统的无缝适配。 Go项目包括编程语言本身,附带了相关...

    the go programing language

    Go语言有时候被描述为“C类似语言”,...Go从C语言继承了相似的表达式语法、控制流结构、基础数据类型、调用参数传值、指针等很多思想,还有C语言一直所看中的编译后机器码的运行效率以及和现有操作系统的无缝适配。

    程序设计基础(C) 视频.txt

    4.2.2函数的传值调用80 4.2.3函数的引用调用81 4.2.4数组作为函数参数83 4.3函数的嵌套调用和递归调用85 4.3.1函数的嵌套调用85 4.3.2函数的递归调用86 4.4带默认形参值的函数90 4.5内联函数和重载函数92 4.5.1内联...

    C++编程思想.rar

    目 录 译者序 前言 第1章 对象的演化 1 1.1 基本概念 1 ...10.3.1 传值方式传递和返回 179 10.3.2 拷贝构造函数 182 10.3.3 缺省拷贝构造函数 187 10.3.4 拷贝构造函数方法的选择 188 10.4 指向成员的指针

    go语言圣经 .pdf

    这个功能使得开发者再不用绞尽脑汁的想到底怎么返回值的设计,也不用为了传值专门定义一个结构体。 3.并发编程  Go语言天然并发,只需要关键字“go”就可以让函数并发执行,使得并发编程变得更为简单,这也是Go...

    C++高级参考手册 完全自学 内容详细 讲解通俗易懂

    目 录 译者序 前言 第1章 对象的演化 1.1 基本概念 1.1.1 对象:特性+行为 ...10.3.1 传值方式传递和返回 10.3.2 拷贝构造函数 10.3.3 缺省拷贝构造函数 10.3.4 拷贝构造函数方法的选择 10.4 指向成员的指针

    C++编程思想 例子和叙述讲解C++编程

    第1章 对象的演化 1 1.1 基本概念 1 1.1.1 对象:特性+行为 1 ...10.3.1 传值方式传递和返回 179 10.3.2 拷贝构造函数 182 10.3.3 缺省拷贝构造函数 187 10.3.4 拷贝构造函数方法的选择 188 10.4 指向成员的指针

    C++编程思想.pdf

    C++编程思想 目 录 译者序 前言 第1章 对象的演化 1 ...10.3.1 传值方式传递和返回 179 10.3.2 拷贝构造函数 182 10.3.3 缺省拷贝构造函数 187 10.3.4 拷贝构造函数方法的选择 188 10.4 指向成员的指针 ......

    C++编程思想

    目 录 译者序 前言 第1章 对象的演化 1 1.1 基本概念 1 ...10.3.1 传值方式传递和返回 179 10.3.2 拷贝构造函数 182 10.3.3 缺省拷贝构造函数 187 10.3.4 拷贝构造函数方法的选择 188 10.4 指向成员的指针

    C++编程思想 PDF

    目 录 译者序 前言 第1章 对象的演化 1 ...10.3.1 传值方式传递和返回 179 10.3.2 拷贝构造函数 182 10.3.3 缺省拷贝构造函数 187 10.3.4 拷贝构造函数方法的选择 188 10.4 指向成员的指针

Global site tag (gtag.js) - Google Analytics