Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как это работает? 
:(
    Опции темы
LeonidPr
Дата 23.12.2014, 16:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 17.2.2012
Где: г. Чебоксары

Репутация: нет
Всего: 1



Добрый день. Разбираясь с ОСРВ RTX для микроконтроллеров наткнулся на некоторую для меня странность. Выделил её в такой вот код, который работает. но вот почему, я не до конца понимаю.
Код

#include <stdio.h>
#include <conio.h>

typedef unsigned long uint32_t;
typedef uint32_t ArrayType[4];

typedef struct {
    uint32_t field1;
    uint32_t field2;
    uint32_t field3;
    uint32_t field4;
} StructType, *p_StructType;

void func(void *Array) {
    static int i=0;
    p_StructType pStruct=(p_StructType)Array;

    pStruct->field1=i+1;
    pStruct->field2=i+2;
    pStruct->field3=i+3;
    pStruct->field4=i+4;
    i+=10;
};

int main() {
    ArrayType Array;

    func(Array);

    printf("%d\n",Array[0]);
    printf("%d\n",Array[1]);
    printf("%d\n",Array[2]);
    printf("%d\n",Array[3]);

    func(&Array);

    printf("%d\n",Array[0]);
    printf("%d\n",Array[1]);
    printf("%d\n",Array[2]);
    printf("%d\n",Array[3]);

    getch();
    return 0;
};

т.е. как возможно что функция отрабатывает успешно в обоих случаях?
Добавлю еще что код вызова функции одинаков в обоих случаях, ей передается указатель на указатель.

Это сообщение отредактировал(а) LeonidPr - 23.12.2014, 16:03
--------------------
pkunzip.zip
PM MAIL   Вверх
xvr
Дата 23.12.2014, 16:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Array - это массив. При передаче его через формальный параметр (строка 28) он преобразуется в указатель на первй элемент (по семантике маасивов в С). Т.е. то же самое, что делается вручную в строке 35

PM MAIL   Вверх
LeonidPr
Дата 23.12.2014, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 17.2.2012
Где: г. Чебоксары

Репутация: нет
Всего: 1



Цитата(xvr @  23.12.2014,  16:25 Найти цитируемый пост)
При передаче его через формальный параметр (строка 28) он преобразуется в указатель на первй элемент (по семантике маасивов в С).

Это-то понятно, я вот вот что не могу въехать...
переменная типа ArrayType - это константный указатель, когда я передаю аргумент в функцию таким образом
Код

func(&Array);

то я сначала получаю указатель на Array (который сам является указателем), получая указатель на указатель и полученное значение передается в функцию, т.е. по моей логике разыменовав его она должна была-бы достучаться не до Array[0], а до той ячейки, где лежит указатель на Array[0].
--------------------
pkunzip.zip
PM MAIL   Вверх
xvr
Дата 23.12.2014, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(LeonidPr @  23.12.2014,  16:41 Найти цитируемый пост)
то я сначала получаю указатель на Array (который сам является указателем),

Нет, не является. Массив есть своя собственная, отдельная сущность. Просто практически везде он автоматически преобразовывается в указатель на свой первый элемент. 
В данном случае автоматического преобразования не происходит, а явно берется указатель на массив (это одно из тех немногих мест в семантике С, где массив не пытается прикинуться указателем  smile ). 

PS. Второе место - оператор sizeof

PM MAIL   Вверх
LeonidPr
Дата 23.12.2014, 20:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 17.2.2012
Где: г. Чебоксары

Репутация: нет
Всего: 1



smile Вот как оказывается
Сейчас проверил еще раз, в первом сообщении я неправильно написал, действительно в обоих случаях передается указатель на первый элемент массива.
Но тогда возникает вопрос, что такое указатель на массив, чисто синтаксическое понятие?
т.к. сейчас провел такой эксперимент. Вот функция:
Код

void func2(uint32_t (*Param)[4]) {
        (*Param)[0]=1;
        (*Param)[1]=2;
        (*Param)[2]=3;
        (*Param)[3]=4;
};

Компилятор позволяет вызвать её только так:
Код

func2(&Array);

Хотя код генерирует, как будто я её вызывал так:
Код

func2(Array);


Добавлено через 4 минуты и 11 секунд
Мда, сначала задал вопрос, потом подумал. так же и получается как вы сказали, если массив это некое отдельное понятие, то все правильно, функция и получает указатель на этот именованный блок ячеек, суть указатель на первую... Спасибо за разъяснение, надо будет еще почитать по этой теме где-нибудь.
--------------------
pkunzip.zip
PM MAIL   Вверх
LeonidPr
Дата 24.12.2014, 10:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 17.2.2012
Где: г. Чебоксары

Репутация: нет
Всего: 1



м-м-м, забыл еще поинтересоваться, является ли эта особенность массивов implementation-defined, или это где-то описано в стандарте языка? сейчас ковыряю стандарт C++ 2003 , что-то пока не могу понять из чего следует такое поведение.
--------------------
pkunzip.zip
PM MAIL   Вверх
xvr
Дата 25.12.2014, 14:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 35
Всего: 223



Цитата(LeonidPr @  23.12.2014,  20:48 Найти цитируемый пост)
Но тогда возникает вопрос, что такое указатель на массив, чисто синтаксическое понятие?

Указатель на масив - это указатель на его первый элемент. Получить указатель на сам массив, как целое, нельзя - нет такого понятия. Но есть ссылка на массив:
Код

#include <stdio.h>

template<size_t I>
void func( int (&arr)[I])
{
 printf("Array size: %d\n",I);
}

int main()
{
 int a[10];

 func(a);
}

Вывод:
Цитата

Array size: 10


Цитата(LeonidPr @  24.12.2014,  10:24 Найти цитируемый пост)
или это где-то описано в стандарте языка?

Описанно конечно. С++ 11 (драфт), раздел 8.3.4: Arrays

PM MAIL   Вверх
LeonidPr
Дата 21.1.2015, 09:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 220
Регистрация: 17.2.2012
Где: г. Чебоксары

Репутация: нет
Всего: 1



Нашел интересную ссылку по теме, оказывается не у одного меня эта проблема возникла, даже в FAQ внесли.
Arrays and Pointers
--------------------
pkunzip.zip
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

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

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1079 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.