[英]Passing pointer arguments in C functions
#include <stdio.h>
// this works
void print_stuff (void* buf) {
printf ("passed arg as buf*: %s\n", buf);
}
/* This works */
void print_stuff_3 (char* buf) {
printf ("passed arg as char*: %s\n", buf);
}
// this does not work
void print_stuff_2 (char** buf) {
printf ("%s\n", *buf);
}
int main () {
char s [] = "hi";
printf ("s = %s\n", s);
// these work
print_stuff (&s);
print_stuff_3 (&s);
// this results in a Segfault
print_stuff_2(&s);
return 0;
}
I am a bit confused about the way things are passed around in C. I feel like &s
should be of type char**
, but it behaves as if it is of type char*
when passed to a function. 我对C语言中的事物传递方式有些困惑。我觉得
&s
应该是char**
类型,但是在传递给函数时,它的行为就像是char*
类型。 Why does this behaviour happen? 为什么会发生这种现象?
In particular, print_stuff_2
segfaults, whereas I thought that print_stuff_3
would give an error. 特别是
print_stuff_2
segfaults,而我认为print_stuff_3
会给出错误。
EDIT: To clarify, I expected print_stuff(&s)
and print_stuff_3(&s)
to fail (while they succeed), while print_stuff_2(&s)
fails, whereas I feel it should succeed. 编辑:澄清一下,我期望
print_stuff(&s)
和print_stuff_3(&s)
失败(虽然它们成功了),而print_stuff_2(&s)
失败了,但是我认为它应该成功。
You need to remember that strings are not fundamental types in C. They are arrays of characters. 您需要记住,字符串不是C中的基本类型。它们是字符数组。 Therefore
因此
char s [] = "hi";
makes s
a char *
(in terms of variable type), ie a pointer to the first character of a 3 character array ( h
, i
and NUL
). 使
s
为char *
(就变量类型而言),即指向3个字符数组的第一个字符( h
, i
和NUL
)的指针。
So in order to pass a pointer to the string, you what to use your print_stuff_3
, as printf()
's %s
argument takes exactly that (a pointer to the string, ie a pointer to the first character). 因此,为了传递一个指向字符串的指针,您需要使用
print_stuff_3
,因为printf()
的%s
参数采用了该参数(指向字符串的指针,即指向第一个字符的指针)。 Call this with print_stuff_3(s)
. 调用
print_stuff_3(s)
。
print_stuff
works because a pointer is a pointer. print_stuff
之所以有效,是因为指针是指针。 It will be translated to a void *
pointer on calling print_stuff
, then printf()
's %s
will convert it back to a char *
. 它将在调用
print_stuff
转换为void *
指针,然后printf()
的%s
会将其转换回char *
。 Call this with print_stuff(s)
. 用
print_stuff(s)
调用它。
print_stuff_2
doesn't work because you are taking the address of where s
is stored. print_stuff_2
不起作用,因为您要使用存储s
的地址。 Had you written char *s = "hi";
你写过
char *s = "hi";
吗char *s = "hi";
that would work if you used print_stuff_2(&s)
. 如果您使用
print_stuff_2(&s)
,它将起作用。 You'd pass the address of the pointer, then dereference that (to get the value of the pointer, ie the pointer to the first character) in by using *buf
. 您将传递指针的地址,然后使用
*buf
取消引用该指针(以获取指针的值,即指向第一个字符的指针)。 Except buf
then would be a poor choice of name, as you would be passing a pointer to a pointer to characters. 除了
buf
之外,名称的选择很差,因为您要传递一个指向字符的指针。
The complication is as follows. 并发症如下。 As it is, you are doing
&s
which just returns s
when you have 正因为如此,你在做
&s
刚刚返回s
当你有
char s [] = "hi";
(see How come an array's address is equal to its value in C? ), but returns the address at which the pointer variable s
is stored on the stack if you have: (请参阅数组的地址如何等于其在C中的值? ),但如果有以下情况,则返回将指针变量
s
存储在堆栈上的地址:
char *s = "hi";
Taking the address of an array doesn't really make sense (so evaluates to the address of the first element). 取数组的地址实际上没有任何意义(因此求值第一个元素的地址)。 You need to use
char *s = "hi";
您需要使用
char *s = "hi";
if you want to take the address of the pointer. 如果要获取指针的地址。
In C, array names are decays to pointer to its first element when passed to a function in most cases. 在C语言中,大多数情况下,数组名称在传递给函数时会衰减指向其第一个元素的指针。 When passing
s
to the function print_stuff
, s
decays to pointer to h
. 将
s
传递给函数print_stuff
, s
衰减为指向h
指针。 No need to pass it with &
. 无需使用
&
传递它。 &s
is of pointer to array ( char (*)[3]
) type, ie, it is giving the address of the entire array s
. &s
指向数组( char (*)[3]
)类型的指针,即,它给出了整个数组s
的地址。
In function call 在函数调用中
print_stuff_3 (&s);
your compiler should warn you 您的编译器应警告您
[Warning] passing argument 1 of 'print_stuff_3' from incompatible pointer type [enabled by default]
I feel like
&s
should be of typechar*
*, but it behaves as if it is of typechar*
when passed to a function.我觉得
&s
应该是char*
*类型,但是当传递给函数时,它的行为就像是char*
类型。 Why does this behavior happen?为什么会发生这种现象?
No. You thought wrong. 不,你想错了。 &s is of type
char (*)[3]
. &s的类型为
char (*)[3]
。
void print_stuff (void* buf)
& void print_stuff_3 (char* buf)
In both functions, buf
is of char *
taking address as argument. void print_stuff (void* buf)
和void print_stuff_3 (char* buf)
在两个函数中, buf
都是char *
以address作为参数。 Which should be print_stuff (s)
& print_stuff_3 (s)
respectively as s
is the base address of char array s
. 应
print_stuff (s)
& print_stuff_3 (s)
分别为s
是字符数组的基地址s
。 So you shouldn't pass &s
which is address of s
. 因此,您不应传递
&s
这是s
地址。
As the below function buf
is of type char **
, it will expect address of address like print_stuff_2(&s)
provided your declaration is char *s = "hi"
, 由于以下函数
buf
的类型为char **
,因此如果您的声明为char *s = "hi"
,它将期望使用类似于print_stuff_2(&s)
地址的地址,
void print_stuff_2 (char** buf) {
printf ("%s\n", *buf);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.