我对C中的指针有点困惑。我的理解是,要从指针获取值,我们需要在前面添加星号(解除引用)。那么为什么下面的代码我定义了两个指针,然后分配给他们什么argvs指向工作就好了?
但是,如果我在printf
中添加星号,它就不起作用了吗?
即如果我的论点是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;
}
答案 0 :(得分:5)
&#39;参数向量&#39; argv
是指针的指针(类型char**
)。代码中的赋值将argv[1]
(类型为char*
)分配给File_1
(其类型为char*
)。总共会将char*
复制到另一个char*
。指针不会被进一步解除引用,否则只会复制一个char
,这是不希望的。在C中,字符串通常实现为char*
,只复制一个char
会与此语义相矛盾。
答案 1 :(得分:3)
char *p = argv[1];
agrv
是一个双指针,因此它可以保存指针argv[0]
argv[1]
等等。
现在argv[1]
是一个指针。因此,该指针的地址被分配给相同类型p
char
示例:
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]);
在2D空间
int **p; /* Here p is double pointer */
*p is a single pointer.
正如在另一个答案%s
中已经指出的那样char *
并且您只需传递char类型的指针并允许printf()
执行解除引用的工作
PS :* p = p [0]
答案 2 :(得分:3)
从printf(3)
开始,这里是s
转换说明符的文档(即%s
):
如果不存在l修饰符:预期 const char * 参数 是指向字符类型数组(指向字符串的指针)的指针。 数组中的字符被写入(但不包括)a 终止空字节(&#39; \ 0&#39;);如果指定了精度,则不再 比指定的数字写的。如果给出精度,则不 需要存在空字节;如果没有指定精度,或者是 大于数组的大小,数组必须包含一个 终止空字节。
所以基本上printf
在其内部取消引用它。如果你进行双重间接,那么它可能会导致UB,因为:
printf("%s %s\n", *File_1, *File_2);
上面发送File_1
和File_2
指向的第一个字符,然后printf
会尝试再次取消引用它,以为您在实际发送char时发送了一个指向char的指针。< / p>
答案 3 :(得分:0)
尝试可视化内存中的内容:
char** argv
是指向指针的指针,两个指针恰好指向数组的开头。第一个数组看起来像[0][1]
,其中每个项目都是char *
的指针:
[0] -> ["file_one"]
[1] -> ["file_two"]
其中["file_one"]
实际上只是内存中指向'f'
的指针,因此我们在内存中彼此相邻'f', 'i', 'l', 'e', '_', 'o', 'n', 'e', '\0'
,而空字节'\0'
告诉我们数组结束。
所以当你指定:
char * File_1 = argv[1];
您的File_1
现在包含指向第一个f
的指针以及我们何时使用printf
:
printf("%s %s\n", File_1, File_2);
需要char *
,假设它是一个以空字符结尾的字符串,并在连续的内存位置取消引用指针,直到它到达空字节,以便读入字符串的内容。
答案 4 :(得分:-1)
File_1
是指向char
变量的指针。
当您使用*File_1
取消引用时,请引用char
而不是char *
。
由于printf
使用%s
表示字符串char *
,因此要打印*File_1
,您应使用%c
。