简体   繁体   English

C - 制作一维数组二维

[英]C - Make 1D array 2D

I'd like to make a 1D array 2D.我想制作一个二维数组。

Right now I can only transfer 1 item in this array, like so:现在我只能传输此数组中的 1 个项目,如下所示:

patches[0] = "This is item 1";
patches[1] = "This is item 2";

What I want to be able to do:我希望能够做什么:

patches[0][0] = "Version 1.01";
patches[0][1] = "Size 1GB";
patches[0][2] = "Is compatible";

patches[1][0] = "Version 4.01";
patches[1][1] = "Size 4GB";
patches[1][2] = "Is compatible";

This is what I currently have:这就是我目前拥有的:

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

int test() {
     char** patches = NULL;
     
     int size = 10;
     
    patches = (char**)malloc(size * sizeof(*patches));
    if (!patches) {
        printf("No memory.\n");
        return 1;
    }
    memset(patches, 0, size * sizeof(*patches));
    
    for (int i = 0; i < size; ++i) {
         patches[i] = "Test";
    }
    
    printf("%s\n", patches[0]);
    
    return 0;
}

int main()
{
    test();

    return 0;
}

How can I achieve this?我怎样才能做到这一点?

"...How can I achieve this?" “……我怎样才能做到这一点?”

Probably not using arrays .可能不 使用 arrays

Arrays in C are rigidly defined contiguous sets of memory locations, created on the stack . C 中的C是在堆栈上创建的严格定义的 memory 位置的连续集合。 This type of array is generally recommended over dynamically allocated variations when size, shape of the array are known at compile-time.当数组的大小、形状在编译时已知时,通常建议使用这种类型的数组而不是动态分配的变体。 Once created, the size and shape of the array created with this method is not changeable.使用此方法创建的数组一旦创建,其大小和形状就不可更改。 Arrays can be created for a single type variables, as well as for struct type data, allowing variations of type to exist within each array element. Arrays 可以为单一type变量创建,也可以为struct类型数据创建,允许每个数组元素内存在类型的变体。

When run-time flexibility is needed there are other methods to consider, such as the following:当需要运行时灵活性时,可以考虑其他方法,例如:

  • Dynamically allocated arrays. Although commonly referred to as arrays, are actually blocks of addressable (and depending on how implemented , may be contiguous) memory created on the heap .动态分配 arrays。虽然通常称为 arrays,但实际上是在堆上创建的可寻址块(并且取决于实现方式,可能是连续的)memory。 These are created in any number of dimensions, and like arrays, elements are accessible via indexing, eg array[i][j][k] .这些是在任意数量的维度中创建的,并且像 arrays 一样,可以通过索引访问元素,例如array[i][j][k] This type of dynamic array is recommended over a normal C array only when the size or shape of the array is not known until run-time.只有在运行时才知道数组的大小或形状时,才建议使用这种类型的动态数组而不是普通的C array Once created its dimensions can be changed, but not easily.创建后,可以更改其尺寸,但并不容易。 ie Requiring freeing of pointers, and reallocation of new memory in the shape of new dimensions.即需要释放指针,并以新维度的形式重新分配新的 memory。
  • Linked List.链表。 This method is similar to the previous method in that it uses dynamically allocated memory during its creation, but vastly different in terms of its flexibility.这个方法和前面的方法类似,都是在创建的时候使用动态分配的memory,但是在灵活性上有很大的不同。 Linked Lists use a struct based architecture, with each instance of struct (or node) containing members of data related in some way, analogous to the fields contained within a database record .链表使用基于struct的架构,结构(或节点)的每个实例都包含以某种方式相关的数据成员,类似于数据库记录中包含的字段 Linked List nodes can be inserted , deleted , searched and sorted .链表节点可以插入删除查找排序

Given the explicit stated requirement: "I'd like to make a 1D array 2D"鉴于明确规定的要求: “我想制作一个二维数组”
And the implied shape of your data:以及数据的隐含形状:

patches[0][0] = "Version 1.01";
patches[0][1] = "Size 1GB";
patches[0][2] = "Is compatible";

patches[1][0] = "Version 4.01";
patches[1][1] = "Size 4GB";
patches[1][2] = "Is compatible";

Linked List stands out as the best suited option.链接列表脱颖而出,成为最合适的选择。 Following is an example that could be used as the struct (or node ) design for a flexibly sized and searchable list that would support what you are doing:以下是一个示例,可用作大小灵活且可搜索的列表的struct (或node )设计,以支持您正在做的事情:

typedef struct patch {
     int item;
     char ver[80];
     long sz;
     char cmpat[80];
     struct patch *next;
}NODE;

Following is a brief example of inserting a node:以下是插入节点的简要示例:

In main()main()

...
NODE *head = malloc(sizeof(*head));
if(head)
{
   insertNode(NODE **head, 1001, "Version 1.01", 1e9, "Is compatible");
   insertNode(NODE **head, 1002, "Version 4.01", 4e9, "Is compatible");
}
...

Where insertNode is defined as:其中insertNode定义为:

void insertNode(NODE **head, int item, char *ver, long sz, char *cmpat)
{
    //allocate new node
    NODE *new_node = malloc(sizeof(NODE));;

    new_node->item = val;
    strcpy (new_node->data, ver);
    new_node->sz = 4e9;
    strcpy(new_node->cmpat, cmpat);
    (*head) = new_node;
}

Note that being a 3 star programmer is usually a bad thing in C. Even an array of struct patch_s { const char *version; const char *size; const char *is_compatible; };请注意,在 C 中,成为 3 星程序员通常是一件坏事。即使是struct patch_s { const char *version; const char *size; const char *is_compatible; }; struct patch_s { const char *version; const char *size; const char *is_compatible; }; would be way more readable here (it just suggest by itself to make it struct patch_s { unsigned long version; unsigned long long size; bool is_compatible; } ).在这里会更具可读性(它只是建议自己使其成为struct patch_s { unsigned long version; unsigned long long size; bool is_compatible; } )。

Anyway, sure - just allocate an array of pointers and assign them.无论如何,当然 - 只需分配一个指针数组并分配它们。 Remember that string literals are immutable in C, so use const char* pointers.请记住,字符串文字在 C 中是不可变的,因此请使用const char*指针。

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

int main() {
    const char ***patches;
    patches = malloc(sizeof(*patches) * 2);
    if (patches == NULL) abort();
    for (int i = 0; i < 2; ++i) {
        patches[i] = malloc(sizeof(*patches[i]) * 3);
        if (patches[i] == NULL) abort();
    }

    /* -- snip --- */
    patches[0][0] = "Version 1.01";
    patches[0][1] = "Size 1GB";
    patches[0][2] = "Is compatible";

    patches[1][0] = "Version 4.01";
    patches[1][1] = "Size 4GB";
    patches[1][2] = "Is compatible";
    /* -- snip --- */

    const int k = 1;
    printf("%s - %s - %s\n", patches[k][0], patches[k][1], patches[k][2]);

    for (int i = 0; i < 2; ++i) {
        free(patches[i]);
    }
    free(patches);
}

Tested on godbolt .在 godbolt 上测试

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM