Проблема указателя массива в C - массив содержит только последнее значение - PullRequest
1 голос
/ 21 марта 2019

Я пытаюсь добавить (ну, действительно, добавить) буквы в алфавите в пустой массив символов.Тем не менее, я, кажется, столкнулся с некоторой проблемой с указателем, которую я не понимаю, так как мой массив содержит только последний символ.Я попытался переместить букву char вне цикла for, но компилятору это не понравилось.Я также посмотрел здесь о том, как создать список всех буквенных символов, и одним из лучших ответов было набрать их все по одному за раз.Тем не менее, моя проблема означает, что я не до конца понимаю, что такое циклы и указатели в C, и я хочу это сделать.

#include <stdio.h>

int main(void) {

    char *empty_list[26];

    for (int i = 0; i < 26; i++){
        char letter = i + 65;
        empty_list[i] = &letter;
    }

    printf("%s", *empty_list);

    return 0;
}

Ответы [ 3 ]

3 голосов
/ 21 марта 2019

Основная проблема - ваша декларация:

char *empty_list[26];

определяет массив из 26 указателей на символы. В вашем текущем коде вы присваиваете каждому элементу массива адрес переменной буква. Так как это выходит за рамки, когда вы печатаете, повезло, что он печатает последний, он мог бы также вывести мусор или потерпеть крах, если код между ними был сложным. Он мог бы также распечатать дополнительный мусор после буквы с тем, что у вас уже есть, поскольку нет способа узнать, есть ли после буквы символ конца строки (\ 0). В вашем существующем коде printf("%s", *empty_list); печатает первый указатель из массива в виде строки с нулевым символом в конце, которая, если вы проигнорируете потерю области видимости и предположите, что содержимое памяти все еще вокруг, будет последним значением из цикла, так как все указатели в вашем массив указывает на память, в которой хранится буква, и эта память имеет последнее значение из цикла.

Если вы намеревались создать массив с буквами, тогда оно должно быть:

char empty_list[27];

Это должно быть 27, так как вам нужно оставить место для символа окончания строки в конце. Один из способов заполнить это - использовать:

empty_list[26] = '\0';

после окончания цикла for и перед печатью содержимого массива (не указывайте здесь звездочку - поскольку это массив, компилятор автоматически примет адрес первого элемента):

printf("%s", empty_list);

Как упомянуто в комментариях, когда вы присваиваете значение буквы элементу в массиве, оно должно быть без амперсанда:

empty_list[i] = letter;
2 голосов
/ 21 марта 2019

В вашем коде есть несколько ошибок:

Во-первых, тип empty_list в настоящее время представляет собой массив указателей на char, тогда как в действительности это должен быть массив char,поскольку ваше намерение состоит в том, чтобы распечатать его, как если бы он был последним в вызове printf после вашего цикла.char empty_list[26]; является правильным объявлением.

Во-вторых, в вашем цикле вы присваиваете &letter, когда все, что вам нужно, это letter.Черт, вам даже не нужна промежуточная переменная letter.Достаточно будет просто empty_list[i] = i + 'A';.

Наконец, вы передаете empty_list в printf для удовлетворения спецификатора формата %s, который ожидает строку с нулевым символом в конце.Что вам нужно сделать, это добавить еще один элемент в empty_list и установить его на ноль:

char empty_list[27];
// populated 0..25 with 'A'..'Z' in your code...

empty_list[26] = '\0';

printf("%s\n", empty_list);
// Output: ABC...Z
0 голосов
/ 21 марта 2019

С помощью вышеприведенной помощи (высоко ценится) мой рабочий код для создания массива букв в C ниже:

#include <stdio.h>

int main(void) {

    // create an array with 1 extra space for null terminator 
    char empty_list[27];

    // add null terminator so string knows when it's finished.
    empty_list[26] = '\0';

    for (int i = 0; i < 26; i++){
        // add 65 to get ASCII value for 'A'
        char letter = A + i;
        // insert each char into the array sequentially
        empty_list[i] = letter;
    }

    printf("%s", empty_list);

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...