Перейти к содержанию

Вопрос по массиву


maksimdag0

Рекомендуемые сообщения

Все добрый вечер!
Я столкнулся с таким случаем: передаю массив в функцию test, через указатель (см. фото 1). В теле этой функции я передаю массив другой функции - big, но передаю по одному элементу таким образом - каждый элемент массива приравниваю к первому элементу и передаю его в функцию big, НО это не работает, почему? Почему нельзя записать в первый элемент массива его любой другой элемент?  (см. фото 2)
Я отслеживал под отладкой это процесс, и выявил что никакое значение не записывается в первый элемент массива, и даже больше - значение arr_2[i] не изменялось вообще, хотя переменная "i" изменялась. подскажите пожалуйста, что я не знаю, почему так происходит?

Screenshot_1.png

 

Screensot_2.png

Изменено пользователем maksimdag0
Ссылка на комментарий
Поделиться на другие сайты

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

11 минут назад, maksimdag0 сказал:

никакое значение не записывается в первый элемент массива, и даже больше значение arr[i]

Кто такой arr[]?

Инициализацию массивов перечитайте внимательно.

void test (int *arr_2)

arr_2 в данном случае указатель на число, а не на массив.

Улыбнись! Завтра будет ещё хуже...

@Borodach - мудератор.

Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

4 минуты назад, DedLogoped сказал:

Кто такой arr[]?

Инициализацию массивов перечитайте внимательно.

void test (int *arr_2)

arr_2 в данном случае указатель на число, а не на массив.

Ошибся, исправил тему, не arr[], а arr_2[i]

Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

3 минуты назад, maksimdag0 сказал:

Ошибся

в догонку

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

Улыбнись! Завтра будет ещё хуже...

@Borodach - мудератор.

Ссылка на комментарий
Поделиться на другие сайты

5 минут назад, DedLogoped сказал:

Кто такой arr[]?

Инициализацию массивов перечитайте внимательно.

void test (int *arr_2)

arr_2 в данном случае указатель на число, а не на массив.

ну да, указатель, таким образом я передаю массив в другую функцию 

Ссылка на комментарий
Поделиться на другие сайты

12 часов назад, maksimdag0 сказал:

ну да, указатель, таким образом я передаю массив в другую функцию 

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

Ссылка на комментарий
Поделиться на другие сайты

16 часов назад, maksimdag0 сказал:

каждый элемент массива приравниваю к первому элементу и передаю его в функцию big,

Что мешает сразу сделать

big(arr_2[i]);

В чем смысл переписывать его по 10 раз?

 

16 часов назад, maksimdag0 сказал:

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

Потому что можно. И код это прекрасно делает:

image.png.0dc0a6c0300d06b0c668fe23eeadb566.png

image.png.8174065c105c4f0e525bde8c901a18bb.png

Как видишь, в функцию big() были переданы все значения массива arr_1 и сохранены в массив rec_data.

Ссылка на комментарий
Поделиться на другие сайты

Это произошло совсем в другом редакторе - Keil. Этот пример я настрочил в подруку попавшемуся редакторе, здесь важен только один момент - не присваивается нулевому элементу массива значение его любого другого элемента.

Ссылка на комментарий
Поделиться на другие сайты

23 hours ago, maksimdag0 said:

не присваивается нулевому элементу массива значение его любого другого элемента.

Вы передаете указатель, компилятор даже не знает что под тем адресом, перемеменная или массив.

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

Просто вы путаетесь думая, что указатель указывает на массив, указатель указывает на адрес (в вашем случае на начало массива), но в указателе нет информации на что он указыват, на массив или на просто переменную.

Изменено пользователем codenamehawk
Ссылка на комментарий
Поделиться на другие сайты

3 часа назад, codenamehawk сказал:

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

Это вы плаваете в теме.
Если я передаю функции указатель на int - компилятору по барабану, массив там или одиночная переменная. И смещение на следующий элемент вычисляется автоматически.
Если у меня функция объявлена void foo(uint16_t *ptr)
то в теле функции я могу с этим указателем делать всякое:
ptr++ приведет к тому, что указатель будет указывать на следующее слово, а не следующий байт
ptr[10] - это я обращаюсь к 10 слову, а не к 10 байту - смещение в 10 слов высчитывается автоматически.

А вот если указать void foo(void *ptr) - вот тут уже интересно. Придется внутри функции определять размерность данных и при этом учитывать кучу всякого разного.

У ТСа какая-то другая проблема. Возможно он включил какую-нибудь оптимизацию и компилятор излишне умничает.
И еще, @maksimdag0 - прекращайте пользоваться фигнёй типа int/uint. Используйте однозначное указание разрядности - uint32_t int16_t и т.д.

Изменено пользователем LiVit
Ссылка на комментарий
Поделиться на другие сайты

3 часа назад, codenamehawk сказал:

Вы передаете указатель, компилятор даже не знает что под тем адресом, перемеменная или массив.

Я передаю уже значение элемента массива, находящийся по этому адресу - arr_2[i]. Если я бы передавал адрес то выражение выглядело бы так - arr_2+i

прихожу к мнению, что все таки компилятор в этом виновен 

 

Ссылка на комментарий
Поделиться на другие сайты

@maksimdag0  Я собрал в Keil ваши функции, всё работает как надо, записывается массив без проблем. Может выложите здесь весь файл целиком, а не его куски?

Ссылка на комментарий
Поделиться на другие сайты

6 hours ago, LiVit said:

И смещение на следующий элемент вычисляется автоматически.

И откуда он узнает какой у вас массив (типа  int16_t или int32_t)

 

6 hours ago, LiVit said:

Если у меня функция объявлена void foo(uint16_t *ptr)
то в теле функции я могу с этим указателем делать всякое:

Никто не запрещает.

6 hours ago, LiVit said:

ptr++ приведет к тому, что указатель будет указывать на следующее слово,

Для атмеги - да.

 

6 hours ago, LiVit said:

а не следующий байт

а надо, что бы указывал на следующий элемент массива, а это будет не всегда см. выше.

Изменено пользователем codenamehawk
Ссылка на комментарий
Поделиться на другие сайты

6 hours ago, maksimdag0 said:

Я передаю уже значение элемента массива, находящийся по этому адресу - arr_2[i].

От того, что вы его назвали arr_2 он не стал массивом.

Нету никакого массива arr_2, вы его нигде не обьявили, по аналогии с int arr_1[3]

В переменной arr_2 будет содержаться адрес равный адресу arr_1[0], т.е. первой ячейки.

(Обратите внимание, что это только адрес, а не содержимое первой ячейки)

Если надо вычислить адрес четвертой ячейки arr_1[3], при помощи переменной arr_2, можно посчитать так

arr_2 + ( 3 * sizeof(int)), если тип хранящихся данных будет нп. int32_t, то формула будет выглядеть arr_2 + ( 3 * sizeof(int32_t)) , где 3 это номер ячейки минус один( в С массив начинается с нуля)

(Обратите внимание, что это только адрес, а не содержимое этой ячейки).

И если не ошибаюсь, то указатель должен быть без знаковый, как у

6 hours ago, LiVit said:

void foo(uint16_t *ptr)

Поинтересуйтесь https://server.179.ru/tasks/cpp/total/094.html

Если уж очень надо передать через указатель

https://www.google.com/search?q=как+передать+массив+в+функцию+си+через+указатель&newwindow=1&client=firefox-b-d&sxsrf=ALiCzsa54wcgW0CoXBCSTt5dPgXC2NVEZw%3A1656264145631&ei=0ZW4Yvr8JYurxc8PgdSZ8Ao&oq=передать+массив+в+функцию+си&gs_lcp=Cgdnd3Mtd2l6EAEYBTIHCAAQRxCwAzIHCAAQRxCwAzIHCAAQRxCwAzIHCAAQRxCwAzIHCAAQRxCwAzIHCAAQRxCwAzIHCAAQRxCwAzIHCAAQRxCwA0oECEEYAEoECEYYAFAAWABgjUVoAXABeACAAQCIAQCSAQCYAQDIAQjAAQE&sclient=gws-wiz

Ссылка на комментарий
Поделиться на другие сайты

9 минут назад, codenamehawk сказал:

arr_2 + ( 3 * sizeof(int)), если тип хранящихся данных будет нп. int32_t, то формула будет выглядеть arr_2 + ( 3 * sizeof(int32_t)) , где 3 это номер ячейки минус один( в С массив начинается с нуля)

какой бред вы несете...
читайте учебник:
https://metanit.com/cpp/c/5.3.php

Ссылка на комментарий
Поделиться на другие сайты

14 minutes ago, IMXO said:

какой бред вы несете...

Вы правы, код рабочий, изменений делать не надо.

int arr_1[3] = {101,102,103};


void mus(int *arr_2)
{
  Serial.println(arr_2[0]);
  Serial.println(arr_2[1]);
  Serial.println(arr_2[2]);
  Serial.println();

  for(int i = 0; i < 3; i++)
  {
    arr_2[0] = arr_2[i];
    Serial.println(arr_2[0]);
  }

}

void setup()
{
  // put your setup code here, to run once:
  Serial.begin(115200);
  mus(arr_1);
}

void loop()
{
  // put your main code here, to run repeatedly:
}

Код для ардуино уно выдает

Untitled.png.e5a9b8f1ab95d12b4148ac72d585e6d5.png

Ссылка на комментарий
Поделиться на другие сайты

3 часа назад, codenamehawk сказал:

И откуда он узнает какой у вас массив 

Дорогой товарищ, ещё раз - вы не в теме. 

При объявлении функции указан тип переменной, на которую указывает указатель. Именно отсюда компилятор узнаёт размерность данных. 

Пишите больше программ, будете лучше понимать. 

2 часа назад, codenamehawk сказал:

Код для ардуино уно выдает

А! Вот оно что. Ардуинщик.... 

Вопросов больше не имею. 

Ссылка на комментарий
Поделиться на другие сайты

10 hours ago, LiVit said:

Дорогой товарищ, ещё раз - вы не в теме. 

И совсем вы не опоздали.

10 hours ago, LiVit said:

А! Вот оно что. Ардуинщик.... 

Грешен, а еще я и паскалем баловался.

Ссылка на комментарий
Поделиться на другие сайты

4 часа назад, codenamehawk сказал:

Грешен, а еще я и паскалем баловался.

И что этот каминг-аут должен обозначать?

Одно дело, когда вы не понимаете как работает, что-то там ковыряете и никому вреда не причиняете, а другое дело, когда вы с видом знатока вещаете на форуме, где начинающие могут прочесть и принять на веру ваши измышления. 
Как профи, я чувствую необходимость оградить неокрепшие умы от ереси. С приведением примеров в том числе. И как показывает практика, повторение - мать учения. Чем больше рассказываешь людям как оно на самом деле, тем больше пользы.

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу
×
×
  • Создать...