在C语言中初始化一个二维字符数组

7

类似于这个问题: 在C语言中使用calloc申请二维数组

我需要帮助初始化一个2D字符数组,使其所有元素都被初始化为某个值(在这种情况下是'0')。我尝试了许多不同的方法,但都没有成功。请告诉我我哪里做错了。这段代码不起作用。谢谢!

char** init_array() {
        char newarray[5][10];
        int i, j;
        for (i = 0; i < 5; i++) {
                for (j = 0; j < 10; j++) {
                        newarray[i][j] = '0';
                }
        }
        return newarray;
}
char **array = init_array();

当我尝试编译时,gcc给出的错误信息:

test.c: In function ‘init_array’:
test.c:12:2: warning: return from incompatible pointer type [enabled by default]
  return newarray;
  ^
test.c:12:2: warning: function returns address of local variable [-Wreturn-local-addr]
test.c: At top level:
test.c:14:1: error: initializer element is not constant
 char **array = init_array();

应该是这样吗?

char newarray[5][10];
char** init_array() {
        int i, j;
        for (i = 0; i < 5; i++) {
                for (j = 0; j < 10; j++) {
                        newarray[i][j] = '0';
                }
        }
        return newarray;
}
char **array = init_array();

5
无法返回本地数组,需要使用 malloc 动态分配内存。 - Barmar
或者将指针作为参数传递,然后您可以在函数中对其进行操作(void类型行为),并返回一个值(char **行为)。 - David C. Rankin
1
新数组在函数返回后就会超出作用域。在init_array内部分配内存。 - helloV
6
char**char[][] 不是相同的类型。 - David C. Rankin
哦,好的谢谢!那我会做出改变的。 - mallux
显示剩余4条评论
3个回答

19
我认为图片有助于理解。这里是char newarray[5][10]。它是一个单一的内存块,由一个包含10个字符的数组和其中五个的数组构成。 您可以使用单个memset调用来清除它。 enter image description here 这里是char **array。它说array是一个指针。 它指向什么? 指向字符的指针。 enter image description here 请记住指针算术。 如果array是一个指向指针的指针, 那么(*array)等于array[0],并且那就是array指向的指针。 array[1]是什么? 它是array指向的数组中第二个指针。 array[0][0]是什么? 它是array指向的数组中第一个指针所指向的第一个字符。 array[i][j]是什么? 它是array指向的数组中第i个指针的第j个字符。
那么newarrayarray有什么关系?
简单。 newarray[i][j]newarray的第i个子数组中的第j个字符。
因此,在这个意义上,它就像array,但没有所有指针的装置。
有什么不同? 好吧,array的缺点是必须一步一步地构建它。 另一方面,优点是您可以在构建时将其任意扩大。它不必在事先已知的固定大小内运行。

清清楚楚明明白白?


谢谢你向我解释并让我了解memset()。我是C语言的新手... - mallux
3
当你声明一个静态数组时,你也可以直接将它的所有元素都赋值为零:char newarray[5][10] = {{0}}; - David C. Rankin
那不起作用。我刚试过了。我希望它能这么简单! - mallux
3
等一下,你需要使用#define定义尺寸而不是像创建变长数组一样提供它们。我会为您发布一个补充答案。 - David C. Rankin
2
@mullax char newarray[5][10] = { 0 }; - M.M
@MattMcNabb gcc 会发出警告并建议添加额外的花括号 :) warning: missing braces around initializer - David C. Rankin

3

根据我们在评论中的讨论,这里是一个快速示例,展示了在声明时将数组值清零的方法。请注意,这些值被定义为常量#defined

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXSTR 10
#define MAXLEN 1024

int main () {

    char myarray[MAXSTR][MAXLEN] = {{0}};  /* declare a static array of MAXSTR x MAXLEN */

    /* copy various strings to statically declared storage */
    strncpy (myarray[0],"  This is the first string", strlen("  This is the first string")+1);
    strncpy (myarray[1],"  This is the second string", strlen("  This is the second string")+1);
    strncpy (myarray[2],"  This is the third string", strlen("  This is the third string")+1);
    strncpy (myarray[3],"  This is the fourth string", strlen("  This is the fourth string")+1);
    strncpy (myarray[4],"  This is the fifth string", strlen("  This is the fifth string")+1);

    int i = 0;

    /* print the values */
    while (*myarray[i])
        printf ("  %s\n", myarray[i++]);

    return 0;
}

输出:

$ ./myar
    This is the first string
    This is the second string
    This is the third string
    This is the fourth string
    This is the fifth string

构建:

gcc -Wall -Wextra -o myar myarray.c

是的,你说得对。它确实将它们“清零”,但它并没有将它们设置为“0”。这就是我认为你的意思。 - mallux
当然,您是想要一个示例程序,例如将文件读入到动态分配的数组或结构体数组中吗? - David C. Rankin

2
为了避免使用全局变量(如上面粘贴的第二个示例代码)和避免使用malloc,您可以在函数外定义数组并将其传递进来,像这样。您不需要返回任何内容,因为数组数据本身正在被修改。请注意,在函数签名中定义数组的次要维度是必要的:
void init_array(char ary[][10]) {
    int i, j;
    for (i = 0; i < 5; i++) {
        for (j = 0; j < 10; j++) {
                ary[i][j] = '0';
        }
    }
}

int main(void)
{
    char newarray[5][10];
    init_array(newarray);
    printf("%c", newarray[1][1]); /* Testing the output */
    return 0;
}

这将返回'0'。

http://codepad.org/JbykYcyF


1
确保您传递(或 #define)大小,以便在函数中不硬编码值:void init_array(char ary[][10], int rows) - David C. Rankin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接