带有指针的 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
的地址并将其传递给 isEven
。 isEven
参数 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
}
我正在尝试编写代码来检查 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
的地址并将其传递给 isEven
。 isEven
参数 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;
}
有几个问题大家都总结了。
如果你仍然想坚持你的例子(你不应该,更喜欢
#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
}