Вт июн 04, 2019 12:21:18
uint8_t a;
uint8_t ukazatel_na_massiv; // Создаем указатель на массив
/* ------ */
func (ukazatel_na_massiv); // Передаем указатель на массив в функцию, которая вернет нам указатель на реально существующий массив
a = ukazatel_na_massiv[19]; // Забираем последнее значение из массива по указателю на массив, который вернула функция
uint8_t massiv[20]; // Статический массив из 20 элементов
/* ------ */
// Функция возвращает указатель на массив
void func (uint8_t uk){
uk = massiv;
}
Вт июн 04, 2019 12:27:19
Вт июн 04, 2019 13:02:55
Вт июн 04, 2019 13:14:00
первая строка не связана со второй: передавать в функцию указатель можно всегда любой хоть на что. другое дело, что возвращать функция может только один указатель, а если требуется больше - то только через параметры (ну или возвращать структуру с указателями, что, имхо, какой-то изврат).Солнцеворот писал(а):Функция должна быть void, а указатели передаваться в скобках, в качестве параметров функции.
Тогда можно принимать от нее ссылки на несколько массивов, переменные и т.п.
Вт июн 04, 2019 13:28:12
Вт июн 04, 2019 13:34:20
Вт июн 04, 2019 13:41:09
интересно. и как это выглядит синтаксически? как это вписывается в стандарт Си?jcxz писал(а):Это не всегда так. В IAR for ARM например можно с помощью return вернуть из функции два указателя.
бред какой-то. если вы хотите иметь указатели на массивы, что вам мешает просто пользоваться их идентификаторами?! если хотите открыть доступ к static-массиву при помощи функции, зачем его прятать?! ведь этим самым вы перечеркиваете "сокрытие" на 100%...Солнцеворот писал(а):После выполнения функции у меня из main есть указатели, которые указывают на массивы с данными, которые меня интересуют. И я могу из main этими данными пользоваться, считывать, анализировать и т.д.
Вт июн 04, 2019 13:47:57
Вт июн 04, 2019 13:50:02
Солнцеворот писал(а):Передаю указатель, как аргумент функции, после выполнения функции по этому указателю читаю данные. Коллега, как?
void func(int **ptr); // ptr - указатель на указатель
Вт июн 04, 2019 13:53:16
интересно. и как это выглядит синтаксически? как это вписывается в стандарт Си?jcxz писал(а):Это не всегда так. В IAR for ARM например можно с помощью return вернуть из функции два указателя.
u64 func()
{
void *ptr1, *ptr2;
...
return (u32)ptr1 | (u64)(u32)ptr2 << 32;
}
вызов:
u64 q = func();
void *ptr_1 = (void *)(u32)q;
void *ptr_2 = (void *)(u32)(q >> 32);
Вт июн 04, 2019 13:59:21
вообще говоря, это совсем не то, что вы сказали: это возврат ОДНОГО значения. так ведь и я могу заявить, что командой return (u8)data я возвращаю аж 8 значений booljcxz писал(а):Я очень часто пользуюсь таким способом. Очень удобно.
Вт июн 04, 2019 14:27:08
Солнцеворот писал(а):Передаю указатель, как аргумент функции, после выполнения функции по этому указателю читаю данные. Коллега, как?
void func(int **ptr); // ptr - указатель на указатель
uint8_t **result; // Указатель на указатель
func(result); // Вызываю функцию, передаю указатель на указатель
uint8_t r1, r2; // Контрольные переменные
r1 = result[0]; // Считываю в первую переменную нулевое значение массива
r2 = result[1]; // Считываю во вторую переменную первое значение массива
uint8_t arr[] = {1,2,3,4,5,6,7,8}; // Указатель на этот массив надо передать
void func (uint8_t **ptr){
ptr = arr; // Присваиваем указателю на указатель указатель ?
}
Вт июн 04, 2019 14:29:33
uint8_t arr[20];
void Func(uint8_t *ptr)
{
ptr = arr;
}
int main(void)
{
uint8_t *arrPtr;
Func(arrPtr);
uint8_t a = arrPtr[19];
}
Вт июн 04, 2019 14:40:34
книги не пробовали читать?Солнцеворот писал(а):Я с этим синтаксисом с ума сойду
// библиотека
static int arr[100];
void func(int num, int* *ptr){
*ptr = &arr[num];
}
// не-библиотека
void func(int num, int* *ptr);
int main(void){
int *pointer;
func(10, &pointer);
// в pointer адрес 10-го элемента массива
(*pointer)++; // здесь изменяется 10-й элемент "библиотечного" массива
// вопрос: зачем его прятать в библиотеку, если потом МОЖНО изменить?!
}
не успел увидеть, как было, но теперь не правильноMyp3ik писал(а):Исправил
Вт июн 04, 2019 15:06:06
uint8_t *result; // Указатель на массив с результатом выполнения функции
func(&result); // Вызываем функцию, передаем адрес указателя *result
uint8_t r1, r2, r7; // Контрольные переменные
r1 = *(result); // Считываем в переменную нулевой элемент массива (число 11)
r2 = *(result+1); // Считываем в переменную первый элемент массива (инкрементируем значение указателя и получаем его значение функцией *) (число 22)
r7 = *(result+6); // Считываем в переменную шестой элемент массива (инкрементируем значение указателя и получаем его значение функцией *) (число 77)
uint8_t arr[] = {11,22,33,44,55,66,77,88}; // Указатель на этот массив надо передать
void func (uint8_t* *ptr){ // Две звездочки - указатель на указатель
*ptr = &arr[0]; // Берем адрес нулевого элемента массива и присваиваем указателю *ptr
}
Вт июн 04, 2019 15:26:55
в таком случае надо всего-навсего так:Солнцеворот писал(а):void func (uint8_t* *ptr){ // Две звездочки - указатель на указатель
*ptr = &arr[0]; // Берем адрес нулевого элемента массива и присваиваем указателю *ptr
}
void func (uint8_t* *ptr){ // Две звездочки - указатель на указатель
*ptr = arr; // Берем адрес массива и присваиваем указателю *ptr
}
Вт июн 04, 2019 15:29:54
Вт июн 04, 2019 15:52:49
Pair<void*> func()
{
void *ptr1 = ...
void *ptr2 = ...
return { ptr1, ptr2 };
}
auto [ptr1, ptr2] = func();
Вт июн 04, 2019 16:00:36
uint8_t arr[] = { 11, 22, 33, 44, 55, 66, 77, 88 };
void Func(uint8_t **ptr)
{
*ptr = arr;
}
uint8_t *arrPtr;
Func(&arrPtr);
uint8_t r1 = arrPtr[0];
uint8_t r2 = arrPtr[1];
uint8_t r7 = arrPtr[6];
Вт июн 04, 2019 16:40:46
typedef struct pointers_pair_st {
uint8_t *pair[2];
} pointers_pair_t;
static uint8_t arr1[] = {11,22,33,44,55,66,77,88};
static uint8_t arr2[] = {1,2,3,4,5,6,7,8};
pointers_pair_t func(void){
pointers_pair_t return_value = {arr1, arr2};
return(return_value);
}
void main(void)
{
pointers_pair_t my_pair;
my_pair=func();
}