char ** s与char * s [],何时以及如何使用每一个?

时间:2011-07-21 20:13:08

标签: c pointers char

如果我使用char *s[],我可以执行以下操作:

char *s[] = {"foo", "bar", "foobar", "whatever", "john", "doe"};

**s有什么区别?在这种情况下,如何使用char **s代替char *s[]

示例:int main (int argc, char **argv)而不是*argv[]

9 个答案:

答案 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