在不取消引用 C 中的指针的情况下获取值
Get value without dereferencing the pointer in C
我对 C 中的指针有点困惑。我的理解是,要从指针中获取值,我们需要在前面加上星号(解引用)。那么,为什么在下面的代码中我定义了两个指针,然后将 argvs 指向的内容分配给它们就可以正常工作了?
但是,如果我在 printf
中加上星号,它不起作用吗?
IE。如果我的参数是 file_one
和 file_two
输出将是 file_one file_two
谢谢
#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;
}
'argument vector' argv
是指向指针(类型char**
)的指针。代码中的赋值是将argv[1]
(也是char*
类型)赋值给File_1
(也是char*
类型)。总共,一个 char*
被复制到另一个 char*
。指针不再被取消引用,否则只会复制一个 char
,这是不希望的。在 C 中,字符串通常实现为 char*
,仅复制一个 char
会与这种语义相矛盾。
File_1
是指向 char
变量的指针。
而当您使用 *File_1
取消引用时,您引用的是 char
而不是 char *
。
由于 printf
使用 %s
作为字符串,即 char *
因此,要打印 *File_1
你应该使用 %c
.
char *p = argv[1];
agrv
是一个双指针,所以它可以容纳指针 argv[0]
argv[1]
等等。
现在argv[1]
是一个指针。所以这个指针的地址被分配给另一个相同类型char
的指针p
示例:
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]);
在二维中 space
int **p; /* Here p is double pointer */
*p is a single pointer.
正如另一个答案中已经指出的那样,%s
期望 char *
并且您只需传递 char 类型的指针并允许 printf()
完成取消引用的工作
PS: *p = p[0]
来自 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).
Characters from the array are written up to (but not including) a
terminating null byte ('[=18=]'); 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.
所以基本上 printf
是在其内部取消引用它。如果你做一个双重间接那么它可能会导致 UB,因为:
printf("%s %s\n", *File_1, *File_2);
上面发送了由 File_1
和 File_2
指向的第一个字符,然后 printf
会尝试在内部再次取消引用它,认为您实际上发送了一个 char 时发送了一个指向 char 的指针.
试着想象一下这在记忆中的样子:
char** argv
是一个指向指针的指针,两个指针恰好都指向一个数组的开头。第一个数组看起来像 [0][1]
,其中每个项目都是指向 char *
:
的指针
[0] -> ["file_one"]
[1] -> ["file_two"]
其中 ["file_one"]
实际上只是内存中指向 'f'
的指针,因此我们在内存中彼此相邻的 'f', 'i', 'l', 'e', '_', 'o', 'n', 'e', '[=18=]'
空字节 '[=19=]'
告诉我们数组结束的地方。
所以当你赋值时:
char * File_1 = argv[1];
您的 File_1
现在包含指向第一个 f
的指针,当我们使用 printf
时:
printf("%s %s\n", File_1, File_2);
它采用 char *
,假定它是一个以空字符结尾的字符串,并取消引用连续内存位置的指针,直到它命中空字节,以便读入字符串的内容。
我对 C 中的指针有点困惑。我的理解是,要从指针中获取值,我们需要在前面加上星号(解引用)。那么,为什么在下面的代码中我定义了两个指针,然后将 argvs 指向的内容分配给它们就可以正常工作了?
但是,如果我在 printf
中加上星号,它不起作用吗?
IE。如果我的参数是 file_one
和 file_two
输出将是 file_one file_two
谢谢
#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;
}
'argument vector' argv
是指向指针(类型char**
)的指针。代码中的赋值是将argv[1]
(也是char*
类型)赋值给File_1
(也是char*
类型)。总共,一个 char*
被复制到另一个 char*
。指针不再被取消引用,否则只会复制一个 char
,这是不希望的。在 C 中,字符串通常实现为 char*
,仅复制一个 char
会与这种语义相矛盾。
File_1
是指向 char
变量的指针。
而当您使用 *File_1
取消引用时,您引用的是 char
而不是 char *
。
由于 printf
使用 %s
作为字符串,即 char *
因此,要打印 *File_1
你应该使用 %c
.
char *p = argv[1];
agrv
是一个双指针,所以它可以容纳指针 argv[0]
argv[1]
等等。
现在argv[1]
是一个指针。所以这个指针的地址被分配给另一个相同类型char
p
示例:
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]);
在二维中 space
int **p; /* Here p is double pointer */
*p is a single pointer.
正如另一个答案中已经指出的那样,%s
期望 char *
并且您只需传递 char 类型的指针并允许 printf()
完成取消引用的工作
PS: *p = p[0]
来自 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). Characters from the array are written up to (but not including) a terminating null byte ('[=18=]'); 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.
所以基本上 printf
是在其内部取消引用它。如果你做一个双重间接那么它可能会导致 UB,因为:
printf("%s %s\n", *File_1, *File_2);
上面发送了由 File_1
和 File_2
指向的第一个字符,然后 printf
会尝试在内部再次取消引用它,认为您实际上发送了一个 char 时发送了一个指向 char 的指针.
试着想象一下这在记忆中的样子:
char** argv
是一个指向指针的指针,两个指针恰好都指向一个数组的开头。第一个数组看起来像 [0][1]
,其中每个项目都是指向 char *
:
[0] -> ["file_one"]
[1] -> ["file_two"]
其中 ["file_one"]
实际上只是内存中指向 'f'
的指针,因此我们在内存中彼此相邻的 'f', 'i', 'l', 'e', '_', 'o', 'n', 'e', '[=18=]'
空字节 '[=19=]'
告诉我们数组结束的地方。
所以当你赋值时:
char * File_1 = argv[1];
您的 File_1
现在包含指向第一个 f
的指针,当我们使用 printf
时:
printf("%s %s\n", File_1, File_2);
它采用 char *
,假定它是一个以空字符结尾的字符串,并取消引用连续内存位置的指针,直到它命中空字节,以便读入字符串的内容。