• 面试 : C语言 功底 被 鄙视了


    第一道:被鄙视 的 C语言语法问题

    请看 下面 程序 :

    错误程序:

    void GetMemory( char *p )
    {
     p = (char *) malloc( 100 );
    }
    void Test( void ) 
    {
     char *str = NULL;
     GetMemory( str ); 
     strcpy( str, "hello world" );
     printf( “%s”,str );
    }

     这个一个考验对指针理解的题目,上面程序在运行之后:

     1,调用GetMemory( str )后, str并未产生变化,依然是NULL.只是改变的str的一个拷贝的内存的变化    

     2,strcpy( str, "hello world" );程序运行到这将产生错误。

     3,new的时候有可能内存出错,应该在*p = (char *) malloc( num ); 后判断内存是否申请成功,应加上:
         if ( *p == NULL )
       {
         ...//进行申请内存失败处理
       }

    4,动态创建的内存没释放。

    错误分析:

           错认为 GetMemory(char   *p)中的 p “就是” GetMemory(str)中的str。但p“不是”str,它只是“等于”str 。 
    就象:   int   a   =   100;   
                int   b   =   a;       //   现在b等于a   
                b   =   500;         //   现在能认为a   =   500 ?      
      显然不能认为a   =   500,因为b只是等于a,但不是a!  当b改变的时候,a并不会改变,b就不等于a了。    因此,虽然p已经有new的内存,但str仍然是null   

    形参 :只是 又 开辟了 一个  char * 类型的 变量 ,并把 str 的值 赋值 给 p,因此 申请 的 空间地址赋值的 是P,即对形参赋值, 而不是对实参 str赋值,所以 对 str 进行 赋值 会 hardfault !

    那如何  改变 实参 那,那么形参 传递 的应该是 实参 的地址 ,这样才可以改变实参,分析整个过程是调用函数的时候:形参的值 = 实参的值, 函数内部,又对形参的值进行赋值,没有对实参进行赋值!, 实参的 地址 即指针!这道题 要 改变 的是 一个 char * 类型的变量,那么 形参 应该 设置 为 指向 char * 类型变量的指针,即 char **p 即 GetMemory(char   **p),那么  函数调用 的时候应该是GetMemory(&str),这道题 迷惑之处在于 形参 是一个 指针变量,而要改变实参 的值 ,不应该是实参变量的值,而应该传递实参变量的地址!

    第二道:被鄙视 的 C语言语法问题,知乎上可以搜到类似的题目

     char *  类型 的 p,  指向  的 字符串 存放 在 那里?   选项有以下 三种: 即 内存 的 分布区域 划分:

    静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据、全局数据和常量。

    栈区:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。

    堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。 但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,否则,我们认为发生了内存泄漏现象。

    答案 是: 静态存储区。

  • 相关阅读:
    【LeetCode】328. 奇偶链表
    【LeetCode】24. 两两交换链表中的节点
    【LeetCode】83. 删除排序链表中的重复元素
    【LeetCode】141. 环形链表
    【LeetCode】02.07. 链表相交
    【LeetCode】876. 链表的中间结点
    【LeetCode】2. 两数相加
    【LeetCode】02.01. 移除重复节点
    【LeetCode】21. 合并两个有序链表
    【LeetCode】剑指 Offer 06. 从尾到头打印链表
  • 原文地址:https://www.cnblogs.com/suozhang/p/8677585.html
Copyright © 2020-2023  润新知