[英]Get value without dereferencing the pointer in C
I'm a little bit confused with the pointer in C. My understanding is that to get a value from a pointer we need to put asterisk in the front (dereferencing). 我对C中的指针有点困惑。我的理解是,要从指针获取值,我们需要在前面添加星号(解除引用)。 So why is the below code where I define two pointers and then assign to them what argvs point to work just fine?
那么为什么下面的代码我定义了两个指针,然后分配给他们什么argvs指向工作就好了? However if I put asterisks in the
printf
it doesn't work? 但是,如果我在
printf
星号,它不起作用? Ie if my arguments are file_one
and file_two
the output will be file_one file_two
即如果我的参数是
file_one
和file_two
则输出将是file_one file_two
Thanks 谢谢
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
char *File_1, *File_2;
File_1 = argv[1];
File_2 = argv[2];
printf("%s %s\n", File_1, File_2);
return EXIT_SUCCESS;
}
The 'argument vector' argv
is a pointer to a pointer (type char**
). 'argument
argv
是一个指针指针( char**
类型)。 The assignment in the code assigns argv[1]
(which is of type char*
) to File_1
(which is also of type char*
). 代码中的赋值将
argv[1]
(其类型为char*
)分配给File_1
(也是char*
类型)。 In total, a char*
is copied to another char*
. 总的来说,
char*
被复制到另一个char*
。 The pointers are not dereferenced any further as otherwise only one char
would be copied, which is not desired. 指针不会被进一步解除引用,否则只会复制一个
char
,这是不希望的。 In C, character strings are usually implemented as char*
, and copying of only one char
would contradict this semantic. 在C中,字符串通常实现为
char*
,并且只复制一个char
会与此语义相矛盾。
char *p = argv[1];
agrv
is a double pointer so it can hold pointers argv[0]
argv[1]
and so on. agrv
是一个双指针,所以它可以保存指针argv[0]
argv[1]
,依此类推。
Now argv[1]
is a pointer. 现在
argv[1]
是一个指针。 So the address of this pointer is being assigned to another pointer p
of same type char
因此,该指针的地址被分配给相同类型
char
另一个指针p
Example: 例:
char **p = malloc(sizeof(char*) * 2);/* double pointer */
p[0] = malloc(20); /* memory allocated to single pointer */
p[1] = malloc(20); /* memory allocated to single pointer */
strcpy(p[0],"string");
strcpy(p[1],"another");
printf("%s\n",p[0]);
printf("%s\n",p[1]);
In 2D space 在2D空间
int **p; /* Here p is double pointer */
*p is a single pointer.
As already pointed out in another answer %s
expects char *
and you just pass the pointer of type char and allow the printf()
to do job of dereferencing 正如在另一个答案中已经指出的那样,
%s
期望char *
并且您只需传递char类型的指针并允许printf()
执行解除引用的工作
PS : *p = p[0] PS :* p = p [0]
From printf(3)
, here's the documentation for the s
conversion specifier (ie %s
): 从
printf(3)
,这里是s
转换说明符的文档(即%s
):
If no l modifier is present: The const char * argument is expected to be a pointer to an array of character type (pointer to a string).
如果不存在l修饰符: const char *参数应该是指向字符类型数组(指向字符串的指针)的指针。 Characters from the array are written up to (but not including) a terminating null byte ('\\0');
数组中的字符被写入(但不包括)终止空字节('\\ 0'); if a precision is specified, no more than the number specified are written.
如果指定了精度,则不会写入指定的数量。 If a precision is given, no null byte need be present;
如果给出精度,则不需要存在空字节; if the precision is not specified, or is greater than the size of the array, the array must contain a terminating null byte.
如果未指定精度,或者大于数组的大小,则数组必须包含终止空字节。
So basically printf
is dereferencing it inside itself. 所以基本上
printf
本身就是取消引用它。 If you do a double indirection then it may lead to UB, because: 如果你做双重间接,那么它可能会导致UB,因为:
printf("%s %s\n", *File_1, *File_2);
The above sends 1st char pointed by File_1
and File_2
and then printf
would try to dereference it again inside thinking you sent a pointer to char when you actually sent a char. 上面发送了
File_1
和File_2
指向的第一个字符,然后printf
会尝试再次取消引用它,以为你在实际发送一个字符时发送了一个指向char的指针。
Try to visualise what this looks like in memory: char** argv
is a pointer to a pointer, both pointers happen to point to the beginning of an array. 尝试可视化内存中的内容:
char** argv
是指向指针的指针,两个指针恰好指向数组的开头。 The first array looks like [0][1]
where each item is a pointer to a char *
: 第一个数组看起来像
[0][1]
,其中每个项目都是一个指向char *
的指针:
[0] -> ["file_one"]
[1] -> ["file_two"]
Where ["file_one"]
is actually just a pointer to 'f'
in memory, so we have 'f', 'i', 'l', 'e', '_', 'o', 'n', 'e', '\\0'
next to each other in memory and the null byte '\\0'
tells us where the array ends. 其中
["file_one"]
实际上只是内存中指向'f'
的指针,所以我们有'f', 'i', 'l', 'e', '_', 'o', 'n', 'e', '\\0'
在内存中彼此相邻,空字节'\\0'
告诉我们数组在哪里结束。
So when you assign: 所以当你指定:
char * File_1 = argv[1];
Your File_1
now contains a pointer to that first f
and when we use printf
: 你的
File_1
现在包含一个指向第一个f
的指针,当我们使用printf
:
printf("%s %s\n", File_1, File_2);
It takes that char *
, assumes it is a null terminated string, and dereferences the pointer at consecutive memory locations until it hits the null byte in order to read in the contents of the string. 它需要
char *
,假设它是一个以空字符结尾的字符串,并在连续的内存位置取消引用指针,直到它到达空字节以便读入字符串的内容。
File_1
is a pointer to char
variable. File_1
是char
变量的指针。
while when you de-reference it using *File_1
, you refer to a char
not a char *
. 当你使用
*File_1
取消引用它时,你引用的是char
而不是char *
。
Since printf
uses %s
for strings ie char *
therefore, to print *File_1
you should use %c
. 由于
printf
使用%s
作为字符串,因此char *
因此要打印*File_1
您应该使用%c
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.