如果我使用char *s[]
,我可以执行以下操作:
char *s[] = {"foo", "bar", "foobar", "whatever", "john", "doe"};
与**s
有什么区别?在这种情况下,如何使用char **s
代替char *s[]
?
示例:int main (int argc, char **argv)
而不是*argv[]
答案 0 :(得分:7)
对于功能参数,没有区别。
否则:
char *s[];
是一个指向char的指针数组。和
char **s;
是指向char的指针。
如果需要指向char的指针数组,则使用前者;如果需要指向指向char的指针,则使用后者。
答案 1 :(得分:4)
作为功能参数,没有任何区别。它们是等价的。
void f(int** p);
void f(int* p[]);
void f(int* p[42]);
这三个声明是等效的。
作为对象,它们有不同的类型;
char *s[] = {"foo", "bar", "foobar", "whatever", "john, "doe"};
s
是指向6
char
sizeof(s) == 6*sizeof(void*)
指针数组
char **s;
s
是指向char
指针的指针。的 sizeof(s) == sizeof(void*)
强>
答案 2 :(得分:1)
他们创建相同的数据结构。唯一的区别是char * s []在初始化时自动为{"foo", "bar", "foobar", "whatever", "john, "doe"}
mallocates足够的内存。 char **只为指针分配一个字节,然后你自己手动为数组中的每个字符串分配内存。
答案 3 :(得分:1)
数组和指针是不同的东西。指针可用于访问数组中的元素。为了能够初始化数组,您需要声明一个数组,而不是指针。
要清楚地显示差异,请尝试以下方法:
int[] ia = {1, 2, 3, 4, 5, 6, 7, 8};
int* ip = ia;
printf("sizeof(ia): %zu, sizeof(ip): %zu", sizeof(ia), sizeof(ip));
第一个应该打印数组的大小,第二个应该是int指针的大小。
C的奇怪之处在于,当一个数组作为参数传递给一个函数时,它会衰减成一个指针。请参阅http://www.lysator.liu.se/c/c-faq/c-2.html第2.3节中的更多内容。主接受argv**
而不是argv*[]
的原因是argv*[]
在作为函数参数传递时会被argv**
衰减。
答案 4 :(得分:1)
不直接回答您的队列,但这可能有助于您了解更多:
#include <stdio.h>
#include <string.h>
int main() {
char *s[] = {"foo", "bar", "foobar", "whatever", "john", "doe"};
printf(" s[0]: %s \n", s[0]);
printf(" *s: %s \n", *s);
printf(" *s+1: %s \n", *s+1);
printf("*(s+1): %s \n", *(s+1));
return 0;
}
输出:
$ gcc -o chararr chararr.c
$ ./chararr
s[0]: foo
*s: foo
*s+1: oo
*(s+1): bar
答案 5 :(得分:0)
据我所知,** s是s的地址,其中* s []是数组的地址,我想你会在s中存储单个值,但在s []中你会存储数组,而数组本身就是一个指针。希望这有帮助!
答案 6 :(得分:0)
如果你定义
char **s[] = {"foo", "bar", "foobar", "whatever", "john, "doe"};
我认为它与定义三维数组(char s [10] [10] [10])相同,因为char * s []定义了一个二维数组。
答案 7 :(得分:0)
当你使用char *s[] = {"foo", "bar", "foobar", "whatever", "john, "doe"};
时,编译器已经知道数组的长度,即:在这种情况下,它知道它是一个指向6个字符数组指针的指针。
char**
缺少长度信息,这就是为什么main有两个参数{length, pointer to pointer to char} == {argc, arv}
答案 8 :(得分:0)
这取决于您的要求。如果您的程序以后不必修改这些字符串,则可以使用
char *s[] = {"foo", "bar", "foobar", "whatever", "john", "doe"};
这些在只读部分编译为字符串文字。
装配输出:
.file "test.c"
.section .rodata
.LC0:
.string "foo"
.LC1:
.string "bar"
.LC2:
.string "foobar"
.LC3:
.string "whatever"
.LC4:
.string "john"
.LC5:
.string "doe"
.text
如果您稍后尝试在程序中修改这些字符串,则会出现分段错误。在这种情况下,您必须使用char **s