По идее это возможно, но сложно, и я запутался. Помогите, если кто знает, как такую задачу решить.
Синтаксис неправильный!
main.c :
Код:
uint8_t a; uint8_t ukazatel_na_massiv; // Создаем указатель на массив /* ------ */ func (ukazatel_na_massiv); // Передаем указатель на массив в функцию, которая вернет нам указатель на реально существующий массив
a = ukazatel_na_massiv[19]; // Забираем последнее значение из массива по указателю на массив, который вернула функция
library.c :
Код:
uint8_t massiv[20]; // Статический массив из 20 элементов
/* ------ */
// Функция возвращает указатель на массив void func (uint8_t uk){ uk = massiv; }
Пишу библиотеку. Библиотека создает статический массив, в котором хранит данные. Хочу иметь возможность вызвать функцию этой библиотеки, которая что-то сделает с данными в массиве, а потом запишет в указатель, который я ей передал, указатель на массив. Ну и заодно количество элементов в массиве (но это понятно как сделать).
Хочу иметь возможность вызвать функцию этой библиотеки, которая что-то сделает с данными в массиве, а потом запишет в указатель, который я ей передал, указатель на массив. Ну и заодно количество элементов в массиве (но это понятно как сделать).
Спасибо за скорый ответ. Это работает, но не так, как мне надо. Функция должна быть void, а указатели передаваться в скобках, в качестве параметров функции. Тогда можно принимать от нее ссылки на несколько массивов, переменные и т.п. Более того, функция может лишь инициировать выполнение какой-то работы, а результаты нужно считывать по прерыванию или флагу.
PS. Под статическим я понимаю следующее: он один раз создан и существует на протяжении работы программы, данные в нем могут меняться. Это правильное определение статического?
Функция должна быть void, а указатели передаваться в скобках, в качестве параметров функции. Тогда можно принимать от нее ссылки на несколько массивов, переменные и т.п.
первая строка не связана со второй: передавать в функцию указатель можно всегда любой хоть на что. другое дело, что возвращать функция может только один указатель, а если требуется больше - то только через параметры (ну или возвращать структуру с указателями, что, имхо, какой-то изврат).
лично для меня ваша формулировка задачи остается непонятной - что вы хотите и зачем
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
лично для меня ваша формулировка задачи остается непонятной - что вы хотите и зачем
Хочу развязать библиотеку и main.c
В main создаю несколько указателей и передаю их функции библиотеки в виде параметров. Функция выполняет свою работу и изменяет переданные ей указатели на указатели на массивы, которые определены в файле библиотеки. После выполнения функции у меня из main есть указатели, которые указывают на массивы с данными, которые меня интересуют. И я могу из main этими данными пользоваться, считывать, анализировать и т.д.
В первом сообщении написал код, где намеренно убрал все звездочки и амперсанды, т.к. не знаю, как их правильно расставить в этом случае.
Тогда можно принимать от нее ссылки на несколько массивов, переменные и т.п.
Из этой фразы могу предположить что Вы недопонимаете принципов передачи аргументов в функцию и возврата результатов. В общем случае: если нужно вернуть из функции некий набор параметров, то можно использовать возврат структуры из функции. Либо как сказано выше: в точке вызова передать внутрь функции указатель на такую структуру, в которую и записать результат.
PS. Под статическим я понимаю следующее: он один раз создан и существует на протяжении работы программы, данные в нем могут меняться. Это правильное определение статического?
Да, примерно так. Кроме того хорошим стилем является: ключевым словом static ограничивать область видимости переменных/функций областью видимости файла.
другое дело, что возвращать функция может только один указатель, а если требуется больше - то только через параметры (ну или возвращать структуру с указателями, что, имхо, какой-то изврат).
Это не всегда так. В IAR for ARM например можно с помощью return вернуть из функции два указателя. Да и некоторые другие компиляторы это позволяют.
Это не всегда так. В IAR for ARM например можно с помощью return вернуть из функции два указателя.
интересно. и как это выглядит синтаксически? как это вписывается в стандарт Си?
Солнцеворот писал(а):
После выполнения функции у меня из main есть указатели, которые указывают на массивы с данными, которые меня интересуют. И я могу из main этими данными пользоваться, считывать, анализировать и т.д.
бред какой-то. если вы хотите иметь указатели на массивы, что вам мешает просто пользоваться их идентификаторами?! если хотите открыть доступ к static-массиву при помощи функции, зачем его прятать?! ведь этим самым вы перечеркиваете "сокрытие" на 100%...
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
Указатели вернутся в двух разных регистрах: R0:R1, так что тех операций, что ниже вызова func() в откомпилированном коде не будет.
Я очень часто пользуюсь таким способом. Очень удобно.
Вообще где-то в мануалах на какой-то компилятор (IAR for ARM?) встречал утверждение, что если вернуть из функции структуру, размерностью == {int x, y;} (два int-а), то такая структура будет возвращена не через стек (как по дефолту), а в паре регистров R0:R1 уже автоматом. Но моя версия IAR 7.80.4 так не делает почему-то. Может каких-то ключей не хватает....
Я очень часто пользуюсь таким способом. Очень удобно.
вообще говоря, это совсем не то, что вы сказали: это возврат ОДНОГО значения. так ведь и я могу заявить, что командой return (u8)data я возвращаю аж 8 значений bool да и решение основано на свойствах оптимизатора. думаю, в любом компиляторе можно найти подходящий аналог, но я бы так делать не стал.
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
int main(void){ int *pointer; func(10, &pointer); // в pointer адрес 10-го элемента массива (*pointer)++; // здесь изменяется 10-й элемент "библиотечного" массива // вопрос: зачем его прятать в библиотеку, если потом МОЖНО изменить?! }
Добавлено after 2 minutes 55 seconds: Re: Передать в функцию указатель, а получить указатель на массив
Myp3ik писал(а):
Исправил
не успел увидеть, как было, но теперь не правильно
_________________ если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе при взгляде на многих сверху ничего не меняется...
ARV, в main мне не нужно изменять данные. Мне их нужно получить. Спасибо, большое человеческое, работает. Книги читать пробовал. Я просто недостаточно сообразителен для указателей.
Выкладываю рабочий код для тех, кто будет читать эту тему:
main.c :
Код:
uint8_t *result; // Указатель на массив с результатом выполнения функции
func(&result); // Вызываем функцию, передаем адрес указателя *result
uint8_t r1, r2, r7; // Контрольные переменные
r1 = *(result); // Считываем в переменную нулевой элемент массива (число 11) r2 = *(result+1); // Считываем в переменную первый элемент массива (инкрементируем значение указателя и получаем его значение функцией *) (число 22) r7 = *(result+6); // Считываем в переменную шестой элемент массива (инкрементируем значение указателя и получаем его значение функцией *) (число 77)
lib.c:
Код:
uint8_t arr[] = {11,22,33,44,55,66,77,88}; // Указатель на этот массив надо передать
void func (uint8_t* *ptr){ // Две звездочки - указатель на указатель *ptr = &arr[0]; // Берем адрес нулевого элемента массива и присваиваем указателю *ptr }
вообще говоря, это совсем не то, что вы сказали: это возврат ОДНОГО значения. так ведь и я могу заявить, что командой return (u8)data я возвращаю аж 8 значений bool да и решение основано на свойствах оптимизатора. думаю, в любом компиляторе можно найти подходящий аналог, но я бы так делать не стал.
Это не свойство оптимизатора. Это так работает компилятор. Всегда. Даже когда оптимизация выключена. И причём думаю, что так должен работать любой компилятор на ARM. Потому что это основано на соглашениях вызова. А эти соглашения они общие для всех компиляторов. Другими словами: если это было бы не так, то obj-файлы (и библиотеки) скомпилённые разными компиляторами были бы несовместимы. А они совместимы если соответствуют этому соглашению. И "8 bool" - это совсем не то. Вы внимательнее прочитайте, что я написал. И почитайте про соглашения вызова. По соглашениям вызова для ARM, функция может использовать не более двух регистров R0:R1 для возврата значения. 8 разных значений в двух регистрах не вернуть. Если не говорить об упаковке. но упаковка - это уже не то. Так что такой возврат - вполне себе штатный способ.
PS: Вобщем - читайте, что такое AEABI. Конкретно раздел "AEABI compliance" мануала на компилятор. Тогда узнаете, что такой способ возврата - стандарт для многих компиляторов.
Это не свойство оптимизатора. Это так работает компилятор. Всегда. Даже когда оптимизация выключена. И причём думаю, что так должен работать любой компилятор на ARM.
Заголовок сообщения: Re: Передать в функцию указатель, а получить указатель на ма
Добавлено: Вт июн 04, 2019 16:40:46
Собутыльник Кота
Карма: 38
Рейтинг сообщений: 268
Зарегистрирован: Пт сен 07, 2018 20:20:02 Сообщений: 2723 Откуда: деревня в Тульской губернии
Рейтинг сообщения:0 Медали: 1
Reflector, , исходя из того, что функция в C может возвращать структуру (не указатель на структуру, а именно структуру), то вернуть она может таким образом произвольное количество данных, причем даже различного типа. В данном случае, использование структуры тоже упростило бы код. Для GCC структуры размером до N байт (N*8 бита) могут возвращаться в регистрах. N - максимальная длина в байтах целого числа, поддерживаемого на целевой платформе. Может быть 4, 8, 16.
Добавлено after 16 minutes 58 seconds: Re: Передать в функцию указатель, а получить указатель на массив
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 9
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения