Как добавить числа в массив c
Перейти к содержимому

Как добавить числа в массив c

  • автор:

Добавить элемент в массив си

Здравствуйте, попался такой кусочек кода, объясните пожалуйста. Массив статический, как добавляется элемент?

Отслеживать
77.2k 6 6 золотых знаков 58 58 серебряных знаков 126 126 бронзовых знаков
задан 3 мар 2022 в 13:25
15 1 1 серебряный знак 8 8 бронзовых знаков
Создается новый массив на 1 элемент больше и в него переносятся элемента из старого массива
3 мар 2022 в 13:51

массив находиться в стеке рядом с другими переменными. при записывании данных за пределы выделенной памяти происходит порча данных и неопределённое поведение программы. Это происходит сразу j == 5 , A[j + 1] = A[j]; портит не свою память, прочитывая опять не свою память. Напоминаю, элементы в массиве находятся по индексам 0 .. 4 , а тут делается первое присваивание A[6] = A[5]; совсем не в тему.

3 мар 2022 в 15:21

Ну это понятно, но ведь работает. Не в каждом компиляторе правда, но работает. Вот мне и интересно — почему?

Как добавить числа в массив c

В языке Си массивы и указатели тесно связаны. С помощью указателей мы также легко можем манипулировать элементами массива, как и с помощью индексов.

Имя массива без индексов в Си является адресом его первого элемента. Соответственно через операцию разыменования мы можем получить значение по этому адресу:

#include int main(void) < int array[] = ; printf("array[0] = %d", *array); // array[0] = 1 return 0; >

Прибавляя определенное число к имени массива, мы можем получить указатель на соответствующий элемент массива:

#include int main(void) < int array[] = ; int second = *(array + 1); // получим второй элемент printf("array[1] = %d", second); // array[1] = 2 return 0; >

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

array[2]

компилятор рассмотривает эту запись как прибавление индекса к указателю на начальный элемент:

array+2

Поэтому мы даже можем написать 2[array] , что также будет валидным обращением к элементу массива:

#include int main(void) < int array[] = ; int third = 2[array]; printf("array[2] = %d", third); // array[2] = 3 return 0; >

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

#include int main(void) < int array[5] = ; for(int i = 0; i < 5; i++) < void* address = array + i; // получаем адрес i-го элемента массива int value = *(array + i); // получаем значение i-го элемента массива printf("array[%d]: address=%p \t value=%d \n", i, address, value); >return 0; >

То есть, например, адрес второго элемента будет представлять выражение a+1 , а его значение — *(a+1) .

Со сложением и вычитанием здесь действуют те же правила, что и в операциях с указателями. Добавление единицы означает прибавление к адресу значения, которое равно размеру типа массива. Так, в данном случае массив представляет тип int , размер которого, как правило, составляет 4 байта, поэтому прибавление единицы к адресу означает увеличение адреса на 4. Прибавляя к адресу 2, мы увеличиваем значение адреса на 4 * 2 =8. И так далее.

В итоге в моем случае я получу следующий результат работы программы:

array[0]: address=0060FE98 value=1 array[1]: address=0060FE9C value=2 array[2]: address=0060FEA0 value=3 array[3]: address=0060FEA4 value=4 array[4]: address=0060FEA8 value=5

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

int array[5] = ; array++; // так сделать нельзя int b = 8; array = &b; // так тоже сделать нельзя

Использование указателя для работы с массивом

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

#include int main(void) < int array[5] = ; int *ptr = array; // указатель ptr хранит адрес первого элемента массива array printf("value: %d \n", *ptr); // 1 return 0; >

Прибавляя (или вычитая) определенное число от адреса указателя, можно переходить по элементам массива. Например, перейдем к третьему элементу:

#include int main(void) < int array[5] = ; int *ptr = array; // указатель ptr хранит адрес первого элемента массива array ptr = ptr + 2; // перемезаем указатель на 2 элемента вперед printf("value: %d \n", *ptr); // value: 3 return 0; >

Здесь указатель ptr изначально указывает на первый элемент массива. Увеличив указатель на 2, мы пропустим 2 элемента в массиве и перейдем к элементу array[2] .

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

#include int main(void) < int array[5] = ; int *ptr = array; // указатель ptr хранит адрес первого элемента массива array ptr = ptr + 2; // переходим к третьему элементу *ptr = 8; // меняем значение элемента, на который указывает указатель printf("array[2]: %d \n", array[2]); // array[2] : 8 return 0; >

Стоит отметить, что указатель также может использовать индексы, как и массивы:

#include int main(void) < int array[5] = ; int *ptr = array; // указатель ptr хранит адрес первого элемента массива array int value = ptr[2]; // используем индексы - получаем 3-й элемент (элемент с индексом 2) printf("value: %d \n", value); // value: 3 return 0; >

Строки и указатели

Ранее мы рассмотрели, что строка по сути является набором символов, окончанием которого служит нулевой символ ‘\0’. И фактически строку можно представить в виде массива:

char hello[] = "Hello METANIT.COM!";

Но в языке Си также для представления строк можно использовать указатели на тип char :

#include int main(void) < char *hello = "Hello METANIT.COM!"; // указатель на char - фактически строка printf("%s", hello); return 0; >

В данном случае оба определения строки — с помощью массива и указателя будут в равнозначны.

Перебор массива с помощью указателей

С помощью указателей легко перебрать массив:

int array[5] = ; for(int *ptr=array; ptr

Так как указатель хранит адрес, то мы можем продолжать цикл, пока адрес в указателе не станет равным адресу последнего элемента ( ptr

Аналогичным образом можно перебрать и многомерный массив:

#include int main(void) < int array[3][4] = < , , >; int n = sizeof(array)/sizeof(array[0]); // число строк int m = sizeof(array[0])/sizeof(array[0][0]); // число столбцов int *final = array[0] + n * m - 1; // указатель на самый последний элемент for(int *ptr=array[0], i = 1; ptr > return 0; >

Так как в данном случае мы имеем дело с двухмерным массивом, то адресом первого элемента будет выражение array[0] . Соответственно указатель указывает на этот элемент. С каждой итерацией указатель увеличивается на единицу, пока его значение не станет равным адресу последнего элемента, который хранится в указателе final.

Мы также могли бы обойтись и без указателя на последний элемент, проверяя значение счетчика, пока оно не станет равно общему количеству элементов (m * n):

for(int *ptr = array[0], i = 0; i < m*n;) < printf("%d \t", *ptr++); if(++i%m==0) < printf("\n"); >>

Но в любом случае программа вывела бы следующий результат:

1 2 3 4 5 6 7 8 9 10 11 12

String interning

Стоит отметить, что в языке Си для работы со строками применяется такой механизм как string interning или интернирование строк . В этом случае строки в виде строковых литералов сохраняются в приложении в секции .rodata (read-only data), которые предназначены для данных только для чтения, а строковые литералы рассматриваются как неизменяемые данные. Например, возьмем следующую программу:

#include char* str1 = «Hello»; char* str2 = «World»; int main(void)

Здесь определены две строки — str1 и str2, в функции main выводим адрес первого символа каждой из этих строк. Так, в моем случае я получу вывод:

str1 = 00007FF75E674000 str2 = 00007FF75E674006

По выводу видно, что первый символ второй строки расположен через 6 байтов начала первой строки. То есть строки расположены в памяти рядом друг с другом.

Но теперь сделаем строки одинаковыми:

#include char* str1 = «Hello World»; char* str2 = «Hello World»; int main(void)

Теперь вывод будет другим:

str1 = 00007FF75F674000 str2 = 00007FF75F674000

Оба адреса одинаковые, потому что обе переменных в реальности указывают на одну и ту же строку. Интернирование строк позволяет избежать дублирования строк, более эффективно использовать память. Причем здесь не важно, что переменные являются глобальными. Они также могут быть локальными, но все равно будут указывать на один и тот же адрес в .rodata .

#include int main(void)

Преобразовать целое число в массив

Это домашнее задание, но я укушу. Моя жена действительно не понимала этого, пока я не объяснил ей это.

Broam 07 дек. 2009, в 16:15
Что-то идет не так в вашем «. «. В массиве 7 членов, но только 6 десятичных цифр в числе.
Steve Jessop 07 дек. 2009, в 16:30
Показать ещё 1 комментарий
Поделиться:

11 ответов

Возможно, лучшим решением будет обратная работа:

123456 / 10 = 12345

12345 / 10 = 1234

Broam 07 дек. 2009, в 18:05
Поделиться

просто используйте модульную арифметику:

int array[6]; int number = 123456; for (int i = 5; i >= 0; i--) < array[i] = number % 10; number /= 10; >

user224003 07 дек. 2009, в 16:55
Поделиться
как насчет ответа, который на самом деле объясняет подход, чтобы ОП узнал что-то?
jalf 07 дек. 2009, в 16:21
Также это жестко закодировано, чтобы иметь дело с 6-значными числами
philsquared 07 дек. 2009, в 16:22
Это будет правильно работать только с 6-значными неотрицательными целыми числами.
Drew Dormann 07 дек. 2009, в 16:22

Я хотел, чтобы ОП подумал о том, как расширить его для обработки других чисел, не приводя только общий случай.

user224003 07 дек. 2009, в 16:24
Показать ещё 2 комментария

Вы можете извлечь последнюю цифру номера следующим образом:

int digit = number % 10; number /= 10; 

Обратите внимание, что вы также должны проверить, является ли number положительным. Другие значения требуют дополнительной обработки.

avakar 07 дек. 2009, в 16:36
Поделиться

Здесь, что я придумал, функция integerToArray возвращает вектор, который преобразуется из целочисленного значения. вы также можете проверить его с помощью основной функции:

#include #include using namespace std; vector integerToArray(int x) < vector resultArray; while (true) < resultArray.insert(resultArray.begin(), x%10); x /= 10; if(x == 0) return resultArray; >> int main() < vector temp = integerToArray(1234567); for (auto const &element : temp) cout //outputs 1 2 3 4 5 6 7 

Orhun Yeldan 09 авг. 2017, в 13:27
Поделиться

Возьмите log10 номера, чтобы получить количество цифр. Поместите это, скажем pos , затем, в цикле, возьмите по модулю 10 ( n % 10 ), поместите результат в массив в позиции pos . Decrement pos и разделите число на 10. Повторяйте до pos == 0

Что вы хотели сделать со знаком, если он отрицательный?

philsquared 07 дек. 2009, в 18:07
Поделиться

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

Скажем num = 123, мы можем это сделать:

string str; while (num > 0) < str = (num % 10) + str; //put last digit and put it into the beginning of the string num = num /10; //strip out the last digit >

Теперь вы можете использовать str как массив символов. Выполнение этого с помощью массива - это проблема, потому что для ввода вещей в начале массива требуется переместить все остальное. Мы можем сделать это, вместо того чтобы помещать каждую цифру в строку, мы можем поместить ее в стек. Он поставит его в обратном порядке следующим образом: 3 2 1. Затем мы можем вытащить верхний номер один за другим и поместить его в массив в правильном порядке. Ваш массив будет выглядеть так: 1 2 3. Я оставлю реализацию вам, поскольку это домашняя работа.

@Broam имеет хорошее решение, но, как он заявил, он работает в обратном направлении. Я думаю, что ОП или тот, кто придет в этот поток, захочет его вперед и почему я публикую это. Если у вас есть лучшее решение, ответьте, я также заинтересован.

Как добавить числа в массив ?

Author24 — интернет-сервис помощи студентам

Как добавить рандомные числа в массив?
Ребят, как добавить к последовательности из 10 нулей рандомные числа? (void add(int x) нужно.

Дан динамический массив.Нужно удалить из него все простые числа и добавить оставшееся в новый массив
Доброго времени суток,не могу понять, где моя ошибка, помогите пожалуйста. Полный текст.

В пустой массив добавить числа из другого массива
Люди добрые помогите нуба) у меня есть 2 массива у каждого есть цифры и есть третий пусстой.

Найти в массиве простые числа и добавить в новый массив
Помогите, не работает код Пользователь вводит элементы массива, нужно узнать, есть ли простные.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *