Arrays 如何打印C中字符**创建的字符串数组(数组)?

Arrays 如何打印C中字符**创建的字符串数组(数组)?,arrays,c,loops,for-loop,c-strings,Arrays,C,Loops,For Loop,C Strings,我是C新手,尝试使用char**创建数组,但在打印时遇到问题。有没有打印出来的方法,或者我不应该用这种方法来创建一个字符串数组 int main() { char **a = {"abc", "ddd", "ccc", "aaa"}; for (size_t i = 0; i < 4; i++){ printf("%s\n", a+i); // only

我是C新手,尝试使用char**创建数组,但在打印时遇到问题。有没有打印出来的方法,或者我不应该用这种方法来创建一个字符串数组

int main()
{
    char **a = {"abc", "ddd", "ccc", "aaa"};

    for (size_t i = 0; i < 4; i++){
        printf("%s\n", a+i);  // only print out "abc" correctly
//        printf("%s\n", *(a+i));  doesn't work
//        printf("%s\n", a[i]);  doesn't work
    }

    return 0;

}
本声明

char **a = {"abc", "ddd", "ccc", "aaa"};
这是不正确的。可以仅使用大括号中的单个表达式初始化标量类型

如果要声明指针数组,则应编写

char * a[] = {"abc", "ddd", "ccc", "aaa"};
要输出它,您可以编写

for (size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++){
    puts( a[i] );
}
它可以以如上所示的相同方式输出

for (size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++){
    puts( a[i] );
}
然后可以使用复合文字对其进行初始化

这是一个演示程序

#include <stdio.h>

int main(void) 
{
    enum {  N = 4 };
    char **a = ( char * [N] ){"abc", "ddd", "ccc", "aaa"};
    
    for ( size_t i = 0; i < N; i++ )
    {
        puts( a[i] );
    }
    
    return 0;
}
本声明

char **a = {"abc", "ddd", "ccc", "aaa"};
这是不正确的。可以仅使用大括号中的单个表达式初始化标量类型

如果要声明指针数组,则应编写

char * a[] = {"abc", "ddd", "ccc", "aaa"};
要输出它,您可以编写

for (size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++){
    puts( a[i] );
}
它可以以如上所示的相同方式输出

for (size_t i = 0; i < sizeof( a ) / sizeof( *a ); i++){
    puts( a[i] );
}
然后可以使用复合文字对其进行初始化

这是一个演示程序

#include <stdio.h>

int main(void) 
{
    enum {  N = 4 };
    char **a = ( char * [N] ){"abc", "ddd", "ccc", "aaa"};
    
    for ( size_t i = 0; i < N; i++ )
    {
        puts( a[i] );
    }
    
    return 0;
}

通过编译器运行发布的代码会导致:

gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:17: warning: initialization of ‘char **’ from incompatible pointer type ‘char *’ [-Wincompatible-pointer-types]
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                 ^~~~~
untitled1.c:8:17: note: (near initialization for ‘a’)
untitled1.c:8:24: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                        ^~~~~
untitled1.c:8:24: note: (near initialization for ‘a’)
untitled1.c:8:31: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                               ^~~~~
untitled1.c:8:31: note: (near initialization for ‘a’)
untitled1.c:8:38: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                                      ^~~~~
untitled1.c:8:38: note: (near initialization for ‘a’)
untitled1.c:11:18: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
   11 |         printf("%s\n", a+i);  // only print out "abc" correctly
      |                 ~^     ~~~
      |                  |      |
      |                  char * char **
Compilation finished successfully.
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:23: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                       ^~~~~
untitled1.c:8:23: note: (near initialization for ‘a’)
untitled1.c:8:30: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                              ^~~~~
untitled1.c:8:30: note: (near initialization for ‘a’)
untitled1.c:8:37: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                                     ^~~~~
untitled1.c:8:37: note: (near initialization for ‘a’)
Compilation finished successfully.
char *a[]
untitled1.c:17:22: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
编译时,不要忽略警告

编译器的最后一行:

 Compilation finished successfully
这仅仅意味着编译器对每个问题都使用了一些“变通方法”,而不是生成了正确的代码

如果我们进行更改,只使用单个指针,而不是指向指针的指针:

#include <stdio.h>




int main( void )
{
    char *a = {"abc", "ddd", "ccc", "aaa"};

    for (size_t i = 0; i < 4; i++){
        printf("%s\n", a+i);  // only print out "abc" correctly
//        printf("%s\n", *(a+i));  doesn't work
//        printf("%s\n", a[i]);  doesn't work
    }

    return 0;

}
哪一个更好,但仍然不对

修改[]的声明以使其正确声明和初始化会导致:

gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:17: warning: initialization of ‘char **’ from incompatible pointer type ‘char *’ [-Wincompatible-pointer-types]
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                 ^~~~~
untitled1.c:8:17: note: (near initialization for ‘a’)
untitled1.c:8:24: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                        ^~~~~
untitled1.c:8:24: note: (near initialization for ‘a’)
untitled1.c:8:31: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                               ^~~~~
untitled1.c:8:31: note: (near initialization for ‘a’)
untitled1.c:8:38: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                                      ^~~~~
untitled1.c:8:38: note: (near initialization for ‘a’)
untitled1.c:11:18: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
   11 |         printf("%s\n", a+i);  // only print out "abc" correctly
      |                 ~^     ~~~
      |                  |      |
      |                  char * char **
Compilation finished successfully.
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:23: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                       ^~~~~
untitled1.c:8:23: note: (near initialization for ‘a’)
untitled1.c:8:30: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                              ^~~~~
untitled1.c:8:30: note: (near initialization for ‘a’)
untitled1.c:8:37: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                                     ^~~~~
untitled1.c:8:37: note: (near initialization for ‘a’)
Compilation finished successfully.
char *a[]
untitled1.c:17:22: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
它读取为指向char的指针数组

下一个问题是:

printf("%s\n", a+i);  
其结果是:

gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:17: warning: initialization of ‘char **’ from incompatible pointer type ‘char *’ [-Wincompatible-pointer-types]
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                 ^~~~~
untitled1.c:8:17: note: (near initialization for ‘a’)
untitled1.c:8:24: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                        ^~~~~
untitled1.c:8:24: note: (near initialization for ‘a’)
untitled1.c:8:31: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                               ^~~~~
untitled1.c:8:31: note: (near initialization for ‘a’)
untitled1.c:8:38: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                                      ^~~~~
untitled1.c:8:38: note: (near initialization for ‘a’)
untitled1.c:11:18: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
   11 |         printf("%s\n", a+i);  // only print out "abc" correctly
      |                 ~^     ~~~
      |                  |      |
      |                  char * char **
Compilation finished successfully.
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:23: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                       ^~~~~
untitled1.c:8:23: note: (near initialization for ‘a’)
untitled1.c:8:30: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                              ^~~~~
untitled1.c:8:30: note: (near initialization for ‘a’)
untitled1.c:8:37: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                                     ^~~~~
untitled1.c:8:37: note: (near initialization for ‘a’)
Compilation finished successfully.
char *a[]
untitled1.c:17:22: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
修正如下:

printf("%s\n", *(a+i) );
因此,一个可以接受但不太好的代码版本如下所示:

#include <stdio.h>




int main( void )
{
    char *a[] =
    {
        "abc", 
        "ddd",
        "ccc", 
        "aaa"
    };

    for (size_t i = 0; i < 4; i++){
        printf("%s\n", *(a+i) );  // only print out "abc" correctly
//        printf("%s\n", *(a+i));  doesn't work
//        printf("%s\n", a[i]);  doesn't work
    }

    return 0;

}
最后的代码是:删除多余的空行

#include <stdio.h>

int main( void )
{
    char *a[] =
    {
        "abc", 
        "ddd",
        "ccc", 
        "aaa"
    };

    for (size_t i = 0; i < (sizeof( a ) / sizeof( *a )); i++)
    {
        printf("%s\n", *(a+i) );  
    }

    return 0;
}

通过编译器运行发布的代码会导致:

gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:17: warning: initialization of ‘char **’ from incompatible pointer type ‘char *’ [-Wincompatible-pointer-types]
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                 ^~~~~
untitled1.c:8:17: note: (near initialization for ‘a’)
untitled1.c:8:24: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                        ^~~~~
untitled1.c:8:24: note: (near initialization for ‘a’)
untitled1.c:8:31: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                               ^~~~~
untitled1.c:8:31: note: (near initialization for ‘a’)
untitled1.c:8:38: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                                      ^~~~~
untitled1.c:8:38: note: (near initialization for ‘a’)
untitled1.c:11:18: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
   11 |         printf("%s\n", a+i);  // only print out "abc" correctly
      |                 ~^     ~~~
      |                  |      |
      |                  char * char **
Compilation finished successfully.
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:23: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                       ^~~~~
untitled1.c:8:23: note: (near initialization for ‘a’)
untitled1.c:8:30: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                              ^~~~~
untitled1.c:8:30: note: (near initialization for ‘a’)
untitled1.c:8:37: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                                     ^~~~~
untitled1.c:8:37: note: (near initialization for ‘a’)
Compilation finished successfully.
char *a[]
untitled1.c:17:22: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
编译时,不要忽略警告

编译器的最后一行:

 Compilation finished successfully
这仅仅意味着编译器对每个问题都使用了一些“变通方法”,而不是生成了正确的代码

如果我们进行更改,只使用单个指针,而不是指向指针的指针:

#include <stdio.h>




int main( void )
{
    char *a = {"abc", "ddd", "ccc", "aaa"};

    for (size_t i = 0; i < 4; i++){
        printf("%s\n", a+i);  // only print out "abc" correctly
//        printf("%s\n", *(a+i));  doesn't work
//        printf("%s\n", a[i]);  doesn't work
    }

    return 0;

}
哪一个更好,但仍然不对

修改[]的声明以使其正确声明和初始化会导致:

gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:17: warning: initialization of ‘char **’ from incompatible pointer type ‘char *’ [-Wincompatible-pointer-types]
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                 ^~~~~
untitled1.c:8:17: note: (near initialization for ‘a’)
untitled1.c:8:24: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                        ^~~~~
untitled1.c:8:24: note: (near initialization for ‘a’)
untitled1.c:8:31: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                               ^~~~~
untitled1.c:8:31: note: (near initialization for ‘a’)
untitled1.c:8:38: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                                      ^~~~~
untitled1.c:8:38: note: (near initialization for ‘a’)
untitled1.c:11:18: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
   11 |         printf("%s\n", a+i);  // only print out "abc" correctly
      |                 ~^     ~~~
      |                  |      |
      |                  char * char **
Compilation finished successfully.
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:23: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                       ^~~~~
untitled1.c:8:23: note: (near initialization for ‘a’)
untitled1.c:8:30: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                              ^~~~~
untitled1.c:8:30: note: (near initialization for ‘a’)
untitled1.c:8:37: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                                     ^~~~~
untitled1.c:8:37: note: (near initialization for ‘a’)
Compilation finished successfully.
char *a[]
untitled1.c:17:22: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
它读取为指向char的指针数组

下一个问题是:

printf("%s\n", a+i);  
其结果是:

gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:17: warning: initialization of ‘char **’ from incompatible pointer type ‘char *’ [-Wincompatible-pointer-types]
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                 ^~~~~
untitled1.c:8:17: note: (near initialization for ‘a’)
untitled1.c:8:24: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                        ^~~~~
untitled1.c:8:24: note: (near initialization for ‘a’)
untitled1.c:8:31: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                               ^~~~~
untitled1.c:8:31: note: (near initialization for ‘a’)
untitled1.c:8:38: warning: excess elements in scalar initializer
    8 |     char **a = {"abc", "ddd", "ccc", "aaa"};
      |                                      ^~~~~
untitled1.c:8:38: note: (near initialization for ‘a’)
untitled1.c:11:18: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
   11 |         printf("%s\n", a+i);  // only print out "abc" correctly
      |                 ~^     ~~~
      |                  |      |
      |                  char * char **
Compilation finished successfully.
gcc -ggdb3 -Wall -Wextra -Wconversion -pedantic -std=gnu11 -c "untitled1.c" -o "untitled1.o" (in directory: /home/richard/Documents/forum)
untitled1.c: In function ‘main’:
untitled1.c:8:23: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                       ^~~~~
untitled1.c:8:23: note: (near initialization for ‘a’)
untitled1.c:8:30: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                              ^~~~~
untitled1.c:8:30: note: (near initialization for ‘a’)
untitled1.c:8:37: warning: excess elements in scalar initializer
    8 |     char *a = {"abc", "ddd", "ccc", "aaa"};
      |                                     ^~~~~
untitled1.c:8:37: note: (near initialization for ‘a’)
Compilation finished successfully.
char *a[]
untitled1.c:17:22: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
修正如下:

printf("%s\n", *(a+i) );
因此,一个可以接受但不太好的代码版本如下所示:

#include <stdio.h>




int main( void )
{
    char *a[] =
    {
        "abc", 
        "ddd",
        "ccc", 
        "aaa"
    };

    for (size_t i = 0; i < 4; i++){
        printf("%s\n", *(a+i) );  // only print out "abc" correctly
//        printf("%s\n", *(a+i));  doesn't work
//        printf("%s\n", a[i]);  doesn't work
    }

    return 0;

}
最后的代码是:删除多余的空行

#include <stdio.h>

int main( void )
{
    char *a[] =
    {
        "abc", 
        "ddd",
        "ccc", 
        "aaa"
    };

    for (size_t i = 0; i < (sizeof( a ) / sizeof( *a )); i++)
    {
        printf("%s\n", *(a+i) );  
    }

    return 0;
}

您想要的是指针数组而不是指向指针的指针:char**a={abc,ddd,ccc,aaa};->char*a[]={abc,ddd,ccc,aaa};如果您没有看到此代码的错误消息,请调整您的编译器设置,尝试运行此类代码只是浪费时间。使用哪种编译器?任何警告?您想要的是指针数组而不是指向指针的指针:char**a={abc,ddd,ccc,aaa};->char*a[]={abc,ddd,ccc,aaa};如果您没有看到此代码的错误消息,请调整您的编译器设置,尝试运行此类代码只是浪费时间。使用哪种编译器?有什么警告吗?