在C中理解指针时发现困难

时间:2016-11-08 18:17:29

标签: c pointers

无法理解代码。修正选项 d 但我不明白它是如何 d

#include <stdio.h>
int *m();
void main()
{
    int k = m();
    printf("%d",k);
}
int *m()
{
    int a[2]={5,8};
    return a;
}

选项是:

a)5
b)8
c)什么都没有 d)变化

编译器显示以下警告:

1)warning: return makes integer from pointer without a cast
 return a;
2)warning: function returns address of local variable [-Wreturn-local-addr]

我无法解释这两个。

4 个答案:

答案 0 :(得分:4)

您无法理解该代码,因为它的编写非常糟糕。

主要问题是当a返回时,m()函数中的m数组不再存在,因此指向该数组的任何指针都是不再有效 1 ,并且尝试通过无效指针读取或写入任何内容会导致未定义的行为

&#34;未定义的行为&#34;只是意味着代码是错误的,但编译器并不需要以任何特定的方式处理它。您的程序可能彻底崩溃,可能会进入一个不会显示的状态,直到以后,它可能损坏数据,或可能似乎没有任何问题。

所以是的,结果可能会有所不同,但这种情况已经大大低估了。 答案是&#34; E)行为未定义&#34;。

但代码中还有其他问题。 m()指针返回给int,但程序会将结果分配给普通int,因此会发出第一个警告。编写该代码的人要么不理解类型,要么假设指针值和int值是可互换的(不一定是有效的假设)。

要么是,要么原始代码实际上是

int k = *m();

最后,main()返回int,而不是void,如下所示:

int main( void )  // or int main( int argc, char **argv ) if your program takes
                  // command line arguments.

<小时/>

  1. 显然,a占用的内存位置仍然存在,但在m()退出后,该内存可能会被其他内容覆盖或使用。

答案 1 :(得分:1)

感谢你对你的问题进行更新,我想我现在明白发生了什么。我的C有点生疏,但这里有:

  1. 方法Started POST "/curl_example" for ::1 at 2016-11-08 13:24:46 -0500 Processing by PeopleController#curl_post_example as */* Parameters: {"{first_name"=>">mista, last_name=>wintas}"} Completed 500 Internal Server Error in 0ms (ActiveRecord: 0.0ms) ArgumentError (When assigning attributes, you must pass a hash as an argument.): 返回m(指向int的地址)

  2. 调用int*时,会在堆栈上创建m作为本地数组。然后,它会尝试返回a

  3. 的地址
  4. a完成并将控制权返回给m时,堆栈上由main分配的内存超出范围。 m是该堆栈中超出范围的项目之一。

  5. 因为地址a的数据超出了范围,所以它被认为是“未定义的行为”来访问/取消引用它,这是a(几乎)对{main的作用。 1}}打电话。这是printf警告你的内容。

  6. 答案“变化”,会更加准确,因为“未定义的行为”。

    错误突出显示一个单独的问题:

      

    1)警告:return从指针生成整数而没有强制转换

    2)warning: function returns address of local variable [-Wreturn-local-addr]是否将指针返回给int,但它被分配给m()

答案 2 :(得分:1)

第一个警告(MSVC编译器)

  

int的间接级别与int *

不同

是因为您试图在int k中为main提供指针,这不是指针。

第二次警告

  

返回本地变量或临时地址:a

是因为函数的局部变量在函数返回后失效。

我建议您在函数中使用malloc来获取数组的内存,并将其返回到main中的指针变量。完成后,您可以打印第一个元素。但是我不会发布代码,因为你“从网站上复制了代码”。

答案 3 :(得分:0)

行为“变化”(D)的原因是因为m()正在返回a,这是一个内存地址。每次运行程序时,该地址都可能会发生变化,因为您的操作系统可以将程序加载到它想要的内存中的任何位置。

现在,如果您的程序正在执行我认为您真正想要的程序 - 在m()返回的内存地址处打印内容 - 那将是:

int *k = m();
printf("%d\n", *k);

但是,对于其他答案描述的局部变量问题,这仍然会导致行为“变化”。

您的编译器警告:2)warning: function returns address of local variable [-Wreturn-local-addr]正在发生,因为m()正在返回a,这是一个局部变量。在google上查找“局部变量”以获取更多信息。这很有用:Difference between static, auto, global and local variable in the context of c and c++

您的编译器警告:1)warning: return makes integer from pointer without a cast是因为您将m()的返回值int*存储到变量k中,其类型为{ {1}}。您需要使这些类型相同,以摆脱编译器警告。在google上查找“C指针”以获取更多信息。本教程似乎很合理:http://www.programiz.com/c-programming/c-pointers