C中的指针需要解释这个微小的代码

时间:2016-09-29 12:24:24

标签: c pointers pass-by-reference

#include <stdio.h>

int* func()
{
    static int a = 5; /* line 5 */
    printf("%d\n",++a);
    return &a; /* line 7 */
}

int main(void)
{
    int *b = func(); /* line 12 */
    (*b)++;
    func();
}

这是编码作业的测试代码示例,因此不一定是最佳的。我有c ++和Java的基本知识,但是这些是C中的指针,我遇到了麻烦。

  1. func()的返回类型是指针,但它返回整数的地址(第7行)。整数是静态的(第5行)是否必须对此做任何事情?

  2. 第12行实际上做了什么?

  3. 此代码的输出为:

    6

    8

6 个答案:

答案 0 :(得分:5)

  

整数是静态的(第5行)是否必须对此做任何事情?

是。否则返回指向自动局部变量的指针将调用未定义的行为。

程序终止时static局部变量的生命周期结束。因此,它的内存位置被分配到程序结束,因此可以返回它的位置。

(*b)++;行取消引用b指向的值,然后将该值递增1。

答案 1 :(得分:2)

指针与Java或C ++引用没有什么不同,C ++允许使用指针。

以下是发生的事情:

func包含静态变量a。静态变量的生命周期延伸到整个程序,并且在调用main之前初始化C(可能在编译或启动时)。这里func增加并打印其静态变量的值并返回其地址。

main最初调用func并将静态变量的地址存储在指针b中。 b用于增加静态变量的值,并再次调用func

答案 2 :(得分:2)

  

我有c ++基础知识

不,你真的没有。我将解释所有内容,但你应该明白,这不是一些奇怪的C风格的东西,它是基本的C,而且(虽然它们是不同的语言),基本的C ++。如果你不理解指针,你最多只知道一个简化的Java风格的C ++子集。

  1.   

    func()的返回类型是指针,但它返回整数的地址(第7行)。整数是静态的(第5行)是否必须对此做任何事情?

    我不完全确定你的问题在这里。

    整数a 静态,这是真的,它与函数的工作原理有关。但是,它与获取地址的语法无关。

    您的功能与此完全相同:

    /* static */ int global_a = 5;
    int* func2()
    {
        printf("%d\n",++global_a);
        return &global_a;
    }
    

    除了global_a对同一翻译单元中的其他代码可见,原始static a仅在函数内可见。否则他们会有相同的生命和行为。

    请注意,我为static注释了global_a限定符 - 它仍然合法,但在全局而非功能范围内意味着略有不同。

      

    ...返回类型是指针,但它返回整数的地址......

    没关系,与a的生命周期无关。整数(&a的地址是指针int *。这就是表达的意思。对于所有变量都是如此,static关键字不会改变任何内容。

    static关键字影响影响的是a的生命周期 - 如上所述,它为其提供与全局相同的生命周期,同时保持其名称仅限于在功能里面。比较其他版本:

    int* func()
    {
        /*static*/ int a = 5;
        printf("%d\n",++a);
        return &a;
    }
    

    这完全被打破了。

    • 首先,它将始终打印6,因为每次调用该函数时,它都会创建一个名为a的新局部变量,将其设置为5,然后递增它。相反,static a初始化为5次,每次调用函数时a都会增加。

    • 其次,返回局部变量的地址是有问题的,因为在调用者接收指针时a将不复存在。您不能对返回的指针执行任何操作,除非astatic,或全局,或者超出函数调用的时间。

  2.   

    第12行实际上做了什么?

    int *b声明一个名为b的变量,指向整数

    的类型指针

    = func()调用我们刚刚讨论的函数func()

    int *b = func();调用函数func,并将结果(指针,即a的地址)分配给变量b

    因此,b现在是指向整数的指针。有问题的整数是a,它存在于func范围之外,因为它是静态的,即使我们无法在该范围之外通过名称引用它。

    表达式*b 取消引用指针,这在此上下文中是一个不幸的名称,因为它实际上产生了int&类型的引用,仍然是{{1} }。

答案 3 :(得分:1)

Func()有一个本地“静态”变量a,这意味着a在函数的所有调用之间共享。

该函数返回指向此变量的指针。通过这个指针,func()之外的世界可以访问这个本地静态。

因此在第12行中,在main()中,创建了一个指针并初始化为指向a。无论何时你去除了b,你都可以直接访问a(包括修改)的内容

答案 4 :(得分:0)

我认为静态变量存在初始化问题,因为 初始化是在编译时从代码赋予值的那些。这些通常存储在DS中,尽管这是特定于编译器的。

另一种类型是未初始化的静态,它在运行时初始化并存储到BSS段中,但这又是编译器特定的

 #include <stdio.h>

int* func()
 {
   static int a;
   a = 5;
   printf("%d\n",++a);
   return &a;
 }

int main(void)
{
  int *b = func();
  (*b)++;
  func();
 }

此代码输出

6

6

但区别仅在于初始化

答案 5 :(得分:-3)

1)在函数外部返回局部变量的地址不是一个好主意,因此你必须将局部变量定义为静态变量.....所以第5行与此无关。 .........它应该只返回a而不是返回&amp; a。

return a;