В чем разница между 2D-строкой типа string [10] [20] и 2D-строкой типа * string [10] [20] в C? - PullRequest
1 голос
/ 15 апреля 2020

Я новичок в C и использую CodeBlocks для Windows.

Я узнал, что строка - это последовательность символов (символов), но мне нужна была последовательность строк.

В видео я видел, что если бы я использовал указатель в моей строке (это было char string[20][10], а теперь это char* string[20][10]), я мог бы печатать каждый "пробел" строки как строку, а не как char. (Под пробелом я имею в виду, например, string[0][0]). Но затем я попытался использовать strcpy() в двух местах этой строки, и программа не работала. Может кто-нибудь сказать мне, почему это произошло и что меняет указатель в строках такого типа?

edit: Вот код, который не работал:

#include <stdio.h>
#include <string.h>
int main()
{
    int i, j;
    char* array[3][10];
    for(i = 0; i != 3; i++)
    {
        for(j = 0; j != 10; j++)
        {
            if(i == 0)
            {
                array[i][j] = "ABC";
            }
            else if(i == 1)
            {
                array[i][j] = "DEF";
            }
            else if(i == 2)
            {
                array[i][j] = "GHI";
            }    
        }
    }
    for(i = 0; i != 3; i++)
    {
        for(j = 0; j != 10; j++)
        {
            printf("%s", array[i][j]);
        }
        printf("\n");
    }
    strcpy(array[2][0], array[1][0]);
    return 0;
}

(Это не ' Фактический код, который у меня есть вопрос, который здесь слишком сложно объяснить, но если после прочтения этого кода вам все еще не понятен этот вопрос, я постараюсь объяснить оригинальный).

Ответы [ 2 ]

1 голос
/ 15 апреля 2020

Я собираюсь ответить на ваш вопрос косвенно, потому что я думаю, что в root вам нужно понять разницу между массивом и указателем.

C может сбить с толку новичков, поскольку он использует тот же синтаксис для указателей и массивов. В массиве он определяет пространство для всех своих элементов, а a[n] возвращает элемент n. Если a является указателем, он определяет пространство только для указателя, а a[n] относится к n -ому местоположению, начинающемуся везде, где указывает a. Если a является массивом, вы все равно можете использовать синтаксис указателя *(a + n) для ссылки на a[n]. В этом отношении n[a] получает вам то же самое.

С опытом синтаксис удобен. Для студента, как я уже сказал, использование одинакового синтаксиса для двух понятий может сбивать с толку.

Обе концепции появляются в argv в вашей main процедуре:

int main( int argc, char *argv[] )

Что такое argv? А что такое argv[0]?

argv не является строкой. Это массив. Массив чего? Каждый элемент (включая первый, конечно) является char *, указателем на символ. До одного символа. Как это случается, за этим символом может следовать другой, и другой, в ... строке ... до символа NUL, обозначающего конец.

Каждый элемент в argv имеет фиксированный размер: sizeof(char*). Длина argv определяется как argc. Длина каждой строки, на которую указывает каждый элемент, неизвестна во время компиляции; это зависит от того, какие аргументы передаются вашей программе, когда она вызывается.

Имея в виду argv, вы поймете, что ваше определение, char* array[3][10], легче для понимания. Вы также объявили массив char *. То, что вы еще не сделали, - это то, что делает ОС, когда она вызывает main: определите что-то, на что они могут указать, и присвойте их адреса указателям.

При работе с указателями всегда спрашивайте, на что он указывает ? Где указателю было присвоено значение и как эта память была выделена (stati c, dynamici c или automati c)? Если вы не уверены, это лишь вопрос времени, когда система напомнит вам, что она тоже не знает.

0 голосов
/ 15 апреля 2020

welcome.

Ваш вопрос немного сбивает с толку.

В C строка - это последовательность символов или байтов с нулевым терминатором, например, последний - '\ 0' или NULL или 0. Таким образом:

char string ="ABCDEF"; char string[7]={'A', 'B', 'C', 'D', 'E', 'F', '\0'}; byte string[7]={'A', 'B', 'C', 'D', 'E', 'F', 0};

Более или менее одинаковы.

Вы можете иметь указатель на строку, например:

char *ptr = string;

, но не путайте это с

char* ptr[7], так как это массив указателей на char type

Теперь strcpy скопирует все элементы, пока он не обнаружит терминатор NULL, поэтому, если у вас есть:

char string[]= {'A', 'B', 'C', 'D', '\0','E', 'F' };

, он будет только копировать «ABCD», а затем игнорировать «EF».

Я не уверен, почему вы, кажется думать, что string[0][0] - это пробел в вашей строке.

Все это первый элемент в вашем 2-мерном массиве, который равен 20 на 10.

Вы можете пройти через oop данные по:

char *ptr;
for(int i=0; i<20; i++)
{
  ptr = string[i][0];
  //do something with ptr
}

Пожалуйста, объясните, что вы пытаетесь сделать.

...