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

Pointers in C. Need explanation for this tiny code

#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() 的 return 类型是指针,但它 return 是整数的地址(第 7 行)。整数是静态的这一事实(第 5 行)与此有什么关系吗?

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

这段代码的输出是:

6

8

Does the fact that integer is static(line 5) have to do anything with this?

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

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

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

Func() 有一个局部 "static" 变量 a,这意味着 a 在函数的所有调用之间共享。

函数returns指向这个变量的指针。通过这个指针,func() 之外的世界可以访问这个局部静态。

因此在第 12 行的 main() 中,创建并初始化了一个指向 a 的指针。每当你撤销 b 时,你就直接访问 a 的内容(包括修改)

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

return a;

指针与 Java 或 C++ 引用没有太大区别,C++ 允许使用指针。

事情是这样的:

func 包含一个静态变量 a。静态变量的生命周期贯穿整个程序,在 C 中,在调用 main 之前初始化(可能在编译或启动时)。这里 func 增加并打印它的静态变量的值和 returns 它的地址。

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

I have basic knowledge of c++

不,你真的不知道。我将解释一切,但你应该明白这不是一些奇怪的 C 风格的东西,它是基本的 C,还有(尽管它们是不同的语言)基本的 C++。如果你不理解指针,你最多知道一个简化的、Java 风格的 C++ 子集。

  1. func()'s return type is pointer but it returns the adress of the integer (line7). Does the fact that integer is static(line 5) have to do anything with this?

    我不太确定你的问题是什么。

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

    您的功能实际上与此相同:

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

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

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

    ... return type is pointer but it returns the address of the integer ...

    很好,与 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. What does line 12 actually do?

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

    的指针

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

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

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

    表达式 *b 取消引用指针 ,在这种情况下这是一个不幸的名称,因为它实际上产生了类型 int& 的引用,仍然至 a.

我认为初始化静态变量存在问题,因为 初始化是在编译时从代码中赋予值的那些。这些通常存储在 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

但区别仅在于初始化