带有指针的 void 函数

Void function with a pointer

我正在尝试编写代码来检查 int 指针是否为偶数。
我的代码是这样的:

#include <stdio.h>
#include <string.h>

void isEven (int *isFlag, int num) {
    if (num % 2 == 0) {
        *isFlag = 1;
    } else {
        *isFlag = 0;
    }
}

int main() {
    int num = 4;
    int *isFlag = 0;
    isEven(isFlag, num);
    printf("%d", isFlag);
}  

但是我遇到了分段错误,我希望看到 isFlag = 1,代码中有什么问题? (我知道我们可以做得更好,但我正在努力理解指针)

int *isFlag = 0;isFlag 定义为指向 int 的指针,并将其初始化为指向“无处”。 (当常量0用于指针时,表示空指针,不指向任何对象或函数。)

您不需要在 main 例程中为此函数创建指针。您可以用 int isFlag = 0; 定义一个普通的 int,然后用 isEven(&isFlag, num);.

int 的地址传递给 isEven

&isFlag 将获取 isFlag 的地址并将其传递给 isEvenisEven 参数 int *isFlag 将具有该指针的值。尽管它与 main 中的 isFlag 同名,但它是不同的对象,因为它是在不同的范围内定义的(在函数参数内而不是在 main 内),它有不同的类型;它将是指向 int 的指针。因此,您将它用作 isEven 中的 *isFlag 来访问它指向的 int

您将 isFlag 声明为 main 中的指针并将其设置为 NULL 指针常量。然后,您将该 NULL 指针传递给 isEven,它试图取消引用它。取消引用 NULL 指针会触发 undefined behavior,在这种情况下会导致崩溃。

isFlag 定义为 int 并将其地址传递给 isEven

int main() {
    int num = 4;
    int isFlag;
    isEven(&isFlag, num);
    printf("%d", isFlag);
}  

what is the problem in the code?

让你的编译器告诉你它认为你的代码可能有什么问题,然后再问我们:

如果你这样做,编译器会告诉你(以 gcc 为例):

<source>: In function 'main':
<source>:16:14: warning: format '%d' expects argument of type 'int', but argument 2 has
type 'int *' [-Wformat=]
   16 |     printf("%d", isFlag);
      |             ~^   ~~~~~~
      |              |   |
      |              int int *
      |             %ls

这并不是 您遇到分段错误的原因,但它确实告诉您您正在将指向 int 的指针视为 =11=]。 printf() 指令是这样的——但更普遍的情况是这样。因此,您对 0 的初始化是您初始化 int 的方式...正如其他答案所解释的那样,这不是您想要做的。

你的代码的问题是你似乎打错了,因为你还没有扎实的指针知识。

在此声明中

int *isFlag = 0;

你声明了一个空指针,因为它是由整数常量 0 初始化的。因此使用空指针访问内存会导致未定义的行为。

另一方面,在这个声明中

printf("%d", isFlag);

您正在输出变量 isFlag 作为类型 int 的变量。

您需要将变量声明为确实具有 int 类型,并通过指向它的指针通过引用将其传递给函数。

main 中的代码看起来像

int main( void ) {
    int num = 4;
    int isFlag = 0;
    isEven( &isFlag, num );
    printf("%d", isFlag);
}  

函数isEven也可以定义得更简单

void isEven( int *isFlag, int num ) {
    *isFlag = num % 2 == 0;
}

有几个问题大家都总结了。

如果你仍然想坚持你的例子(你不应该,更喜欢 ),你仍然可以通过以下方式实现它,通过为 ptr 分配内存:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void isEven (int *isFlag, int num) {
    if (num % 2 == 0) {
        *isFlag = 1;
    } else {
        *isFlag = 0;
    }
}
int main() {
    int num = 4;
    int *isFlag;

    isFlag = malloc(sizeof(int));
    isEven(isFlag, num);
    printf("%d\n", *isFlag); // also use *isFlag to print the value at ptr's address
    printf("%p\n", isFlag); // print isFlag's address
}