Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: в чем прелесть указателей ?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
Abakt
Растолкуйте популярно в чем польза от использования указателей. если возмжно то на примерах. Спасибо.
arttab
Попробуйте почитать и подумать...
А из примеров:
вместо передачи многобайтной переменной можно передать на нее указатель;
в функцию обработки структур или объединений можно передавать указатели на струк. или обьед. или на масивы того или другова....
компилятор при оптимизации переделывает к указателям.
если Вы передаете масив в функцию из, скажем, 300 однобыйтных элементов, то какой буфер потребуется? А Си расценивае как передачу указателя на масив.
mihask
Цитата(Abakt @ Jan 29 2007, 08:03) *
Растолкуйте популярно в чем польза от использования указателей. если возмжно то на примерах. Спасибо.


Могу назвать один минус в использовании указателей smile.gif , если с ними не аккуратно работать то
при обработке данных можно легко выйти за пределы обрабатываемого массива и записать данные
в область памяти в которую данная функция записывать данные не должна. Причем компилятор вам об
этом естествено не сообщит. Например вам необходимо записать число 0 в массив :

int array[5];

void FillZero(int* ptr_array, int size_array)
{
while (size_array !=0)
{

*ptr_array=0;
ptr_array++;
size_array--;
}
}

void main()
{
FillZero(array, 6);
}
В данном случае ошибка с размером массива передаваемого при вызове функции.
beer_warrior
В сущности без указателя не обойтись при использовании любого определенного пользователем типа данных.С внутренними типами компилятор знает как обращаться, для пользовательского нужен указатель. В противном случае любую операцию с таким типом придется проделывать поэлементно.
mihask
Ну да еще структуру целиком нельзя передать в качестве аргумента функции. Ее можно передать в
функцию только через указатель на структуру. Хотя структура помоему и используется в
основном для делания пользовательских типов данных. smile.gif
prottoss
Цитата(Abakt @ Jan 29 2007, 09:03) *
Растолкуйте популярно в чем польза от использования указателей. если возмжно то на примерах. Спасибо.
Фактически, указатель - это адрес переменной (или функции), и без его использования практически не возможно работать с памятью данных. Вот простой пример:

Код
int array[128];

....

for(int i = 0; i < 128; i++){

        array[i] = 0;}   /* адрес начала массива - array, смещение - i */


Так вот - переменная array - указатель на массив array[128]. Этот код можно записать и по другому, при этом работать он будет быстрее и размер его будет меньше

Код
int array[128];

int * pointer = array;

....

for(int i = 0; i < 128; i++){

        *pointer = 0; /* записать по адресу pointer 0 */

         pointer++} /* инкрементировать адрес */
Лучше, конечно, литературку соответствующую почитать. smile.gif С книжкой то понятнее. Что то типа начальный курс Си и Си++
mihask
Цитата(Abakt @ Jan 29 2007, 08:03) *
Растолкуйте популярно в чем польза от использования указателей. если возмжно то на примерах. Спасибо.


Вообще в Си например, без указателей, помоему довольно сложно программировать когда дело
касается работы со структурами. Да и быстродействие и размер кода в приложениях для
микроконтроллеров иногда имеет значение. А вот например современные языки программирования
java,С# наоборот отказались от указателей для того что бы повысить надежность программ
реализованных на этих языках.
Abakt
друзья, огромное спасибо. пошел тренироваться на "кошках" в смысле на сишках.
dxp
Цитата(mihask @ Jan 29 2007, 12:19) *
Ну да еще структуру целиком нельзя передать в качестве аргумента функции. Ее можно передать в
функцию только через указатель на структуру.

Как это нельзя?! Еще как можно. И передавать, и возвращать. Это массив нельзя передать в качестве аргумента по значению (только указатель - имя массива в этом контексте автоматически перобразовывается к указателю на его первый элемент), а структуру вполне можно.
prottoss
Цитата(dxp @ Jan 29 2007, 15:20) *
Цитата(mihask @ Jan 29 2007, 12:19) *

Ну да еще структуру целиком нельзя передать в качестве аргумента функции. Ее можно передать в
функцию только через указатель на структуру.

Как это нельзя?! Еще как можно. И передавать, и возвращать. Это массив нельзя передать в качестве аргумента по значению (только указатель - имя массива в этом контексте автоматически перобразовывается к указателю на его первый элемент), а структуру вполне можно.
И даже массив мона))) Ежели правильна приготовить smile.gif
mihask
Цитата(dxp @ Jan 29 2007, 14:20) *
Цитата(mihask @ Jan 29 2007, 12:19) *

Ну да еще структуру целиком нельзя передать в качестве аргумента функции. Ее можно передать в
функцию только через указатель на структуру.

Как это нельзя?! Еще как можно. И передавать, и возвращать. Это массив нельзя передать в качестве аргумента по значению (только указатель - имя массива в этом контексте автоматически перобразовывается к указателю на его первый элемент), а структуру вполне можно.


Ой звиняюсь обманул smile.gif, но это ограничение все таки было smile.gif правда в очень древних реализациях Си smile.gif
unichorn
Цитата(prottoss @ Jan 29 2007, 11:38) *
Цитата(dxp @ Jan 29 2007, 15:20) *
Цитата(mihask @ Jan 29 2007, 12:19) *

Ну да еще структуру целиком нельзя передать в качестве аргумента функции. Ее можно передать в
функцию только через указатель на структуру.

Как это нельзя?! Еще как можно. И передавать, и возвращать. Это массив нельзя передать в качестве аргумента по значению (только указатель - имя массива в этом контексте автоматически перобразовывается к указателю на его первый элемент), а структуру вполне можно.
И даже массив мона))) Ежели правильна приготовить smile.gif

А ежели правильно приготовить с указателями на функции, то можно получить и объект который сам
себя будет и обрабатывать. smile.gif
mihask
Цитата(unichorn @ Jan 29 2007, 15:10) *
Цитата(prottoss @ Jan 29 2007, 11:38) *

Цитата(dxp @ Jan 29 2007, 15:20) *
Цитата(mihask @ Jan 29 2007, 12:19) *

Ну да еще структуру целиком нельзя передать в качестве аргумента функции. Ее можно передать в
функцию только через указатель на структуру.

Как это нельзя?! Еще как можно. И передавать, и возвращать. Это массив нельзя передать в качестве аргумента по значению (только указатель - имя массива в этом контексте автоматически перобразовывается к указателю на его первый элемент), а структуру вполне можно.
И даже массив мона))) Ежели правильна приготовить smile.gif

А ежели правильно приготовить с указателями на функции, то можно получить и объект который сам
себя будет и обрабатывать. smile.gif


Звиняюсь - а здесь можно по подробней ? smile.gif Это ведь получается Объектно - Ориентированное программирование на Си ? Можно наглядный примерчик этой штуки ? smile.gif
dxp
Цитата(prottoss @ Jan 29 2007, 14:38) *
Цитата(dxp @ Jan 29 2007, 15:20) *
Цитата(mihask @ Jan 29 2007, 12:19) *

Ну да еще структуру целиком нельзя передать в качестве аргумента функции. Ее можно передать в
функцию только через указатель на структуру.

Как это нельзя?! Еще как можно. И передавать, и возвращать. Это массив нельзя передать в качестве аргумента по значению (только указатель - имя массива в этом контексте автоматически перобразовывается к указателю на его первый элемент), а структуру вполне можно.
И даже массив мона))) Ежели правильна приготовить smile.gif

Покажите как? Как передать массив по значению (в качестве аргумента) в функцию?
unichorn
Примерчик можно, сам проэкт сдох чёрт знает когда, поэтому коммерческой ценности непредставляет (и соответственно недаделан).
Правда он под семейство MCU51(Keil2), но для понятия сути вещей сгодится.


PS:
ногами сильно непинать, делалось всё на скорую руку, хотя по датам можно понять оч медленно (изначально было ясно что прект загнётся).
prottoss
Цитата(dxp @ Jan 29 2007, 16:57) *
Покажите как? Как передать массив по значению (в качестве аргумента) в функцию?


Код
typedef struct
{
   UCHAR array[100];

} array_as_param;

...

UCHAR array1[100];

...

void fun(array_as_param param)
{
   UCHAR *ptr = (UCHAR *)&param;
    for(UCHAR i = 0; i < 10; i++)
       *ptr++ = 0;
}

...

void main(void)
{
   fun(*(array_as_param *)array1);

....

}
mihask
Цитата(unichorn @ Jan 29 2007, 16:10) *
Примерчик можно, сам проэкт сдох чёрт знает когда, поэтому коммерческой ценности непредставляет (и соответственно недаделан).
Правда он под семейство MCU51(Keil2), но для понятия сути вещей сгодится.


PS:
ногами сильно непинать, делалось всё на скорую руку, хотя по датам можно понять оч медленно (изначально было ясно что прект загнётся).


Спасибо, обязательно посмотрю smile.gif
el34
2Abakt оч. рекомендую поглядеть
"Ted Jensen's Tutorial on Pointers and Arrays in C"
http://pw2.netcom.com/~tjensen/ptr/
dxp
Цитата(prottoss @ Jan 29 2007, 16:13) *
Цитата(dxp @ Jan 29 2007, 16:57) *
Покажите как? Как передать массив по значению (в качестве аргумента) в функцию?


Код
...

void main(void)
{
   fun(*(array_as_param *)array1);

....

}


Здесь передается не массив, а структура:

void fun(array_as_param param), где array_as_param - это структура (как видно выше)

А код этот некрасивый, как и почти любой другой код, где используется ручное преобразование типов. Гораздо лучше, прозрачнее, логичнее и безопаснее было бы написать:

aray_as_param s = array1; fun(s);

Вопрос стоял о том, как передать массив по значению в качестве аргумента. А не о том, как переправить значения массива в функцию. Т.ч., как говорилось, массив всегда в функцию передается через указатель.
prottoss
Цитата(dxp @ Jan 29 2007, 19:36) *
Цитата(prottoss @ Jan 29 2007, 16:13) *

Цитата(dxp @ Jan 29 2007, 16:57) *
Покажите как? Как передать массив по значению (в качестве аргумента) в функцию?

Код
...


Здесь передается не массив, а структура:
void fun(array_as_param param), где array_as_param - это структура (как видно выше)
Здесь в качестве параметра передается ИМЕННО МАССИВ smile.gif , НО выдаем мы его за структуру smile.gif
Цитата(dxp @ Jan 29 2007, 19:36) *
А код этот некрасивый, как и почти любой другой код, где используется ручное преобразование типов. Гораздо лучше, прозрачнее, логичнее и безопаснее было бы написать:
aray_as_param s = array1; fun(s);
Вы хоть сами то читаете и проверяете то что пишите??? Эта строчка никогда работать не будет. Ну а так, вообще, красиво написанно smile.gif Может быть Вы имели ввиду это
Код
aray_as_param *s = (aray_as_param *)array1; fun(*s);

Цитата(dxp @ Jan 29 2007, 19:36) *
Вопрос стоял о том, как передать массив по значению в качестве аргумента.
Ответ получен - МОЖНО
dxp
Цитата(dxp @ Jan 29 2007, 19:36) *
Здесь передается не массив, а структура:
void fun(array_as_param param), где array_as_param - это структура (как видно выше)


Цитата(prottoss @ Jan 29 2007, 19:02) *
Здесь в качестве параметра передается ИМЕННО МАССИВ smile.gif , НО выдаем мы его за структуру smile.gif

Еще раз. Функция: void fun(array_as_param param), array_as_param - это структура, значит в функцию передается структура. У Вас формируется временный объект (в стеке) типа структура, который инициализируется значениями из массива. И передается структура. И внутри функции мы видим и тоже структуру. То, что Вы "выломали руки" компилятору своими насильными преобразованиями типов, ситуации не меняет. Это все, кстати, очень bad style и чревато прекрасными глюками при выравнивании. Про переносимость я вообще молчу. Яркий пример как никогда не надо писать код. Уж извините, но это так.

Цитата(dxp @ Jan 29 2007, 19:36) *
А код этот некрасивый, как и почти любой другой код, где используется ручное преобразование типов. Гораздо лучше, прозрачнее, логичнее и безопаснее было бы написать:
aray_as_param s = array1; fun(s);

Цитата(prottoss @ Jan 29 2007, 19:02) *
Вы хоть сами то читаете и проверяете то что пишите??? Эта строчка никогда работать не будет. Ну а так, вообще, красиво написанно smile.gif Может быть Вы имели ввиду это
Код
aray_as_param *s = (aray_as_param *)array1; fun(*s);

Нет, я имел в виду вот что:
Код
const int C_Size = 100;
struct array_as_param
{
    array_as_param(const char* const a)
    {
        for(int i = 0; i < C_Size; i++) array[i] = a[i];
    }

    char array[C_Size];
};

array_as_param s = array1; fun(s);

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


Цитата(prottoss @ Jan 29 2007, 19:02) *
Цитата(dxp @ Jan 29 2007, 19:36) *
Вопрос стоял о том, как передать массив по значению в качестве аргумента.
Ответ получен - МОЖНО

По аргументу реально передан не массив, а структура, что и есть верный ответ. С тем же, что есть способ передать значения массива в функцию, никто не спорил изначально. И даже показано более читабельное и безопасное решение.
prottoss
Цитата(dxp @ Jan 29 2007, 16:57) *
Покажите как? Как передать массив по значению (в качестве аргумента) в функцию?
Я показал, КАК МОЖНО ПЕРЕДАТЬ МАССИВ ПО ЗНАЧЕНИЮ, то бишь, В КАЧЕСТВЕ АРГУМЕНТА. Я не говорю, что я так делаю, я лишь показал то, что Вы просили:

массив array1 был передан в функцию в качестве аргумента - так? Или не так? Не надо объяснять - скажите - да или нет smile.gif
Abakt
Цитата(el34 @ Jan 29 2007, 14:15) *
2Abakt оч. рекомендую поглядеть
"Ted Jensen's Tutorial on Pointers and Arrays in C"
http://pw2.netcom.com/~tjensen/ptr/


Огромное спасибо! Читаю.
el34
Abakt>Огромное спасибо! Читаю.
ну разумеется спасибо Ted !!!!
рад, мне он оч. помог... думаю в си - самое вкусное это
указатели....(IMHO)....
dryadae
Передавать структуры в функцию - неправильно; стек не резиновый. Хорошая практика - malloc + typecast + указатель. Или просто указатель, если речь идёт о статике.
prottoss
Цитата(dryadae @ Jan 30 2007, 02:54) *
Передавать структуры в функцию - неправильно; стек не резиновый. Хорошая практика - malloc + typecast + указатель. Или просто указатель, если речь идёт о статике.
Конечно НЕПРАВИЛЬНО. smile.gif НО - спросили КАК - я показал smile.gif
zltigo
Цитата(prottoss @ Jan 29 2007, 19:22) *
массив array1 был передан в функцию в качестве аргумента - так? Или не так? Не надо объяснять - скажите - да или нет smile.gif

Таки нет smile.gif. При передаче предмет передачи назывался структурой.
Если заниматься схоластикой, то я и простой int могу массивом битов назвать smile.gif, хотя он на самом деле
структура содержащая биты smile.gif smile.gif smile.gif
prottoss
Цитата(zltigo @ Jan 30 2007, 03:20) *
Цитата(prottoss @ Jan 29 2007, 19:22) *

массив array1 был передан в функцию в качестве аргумента - так? Или не так? Не надо объяснять - скажите - да или нет smile.gif
Таки нет smile.gif . При передаче предмет передачи назывался структурой.
На этот счет есть кароший русский поговорка, цитирую: "На заборе ХYZ написанно, а там дрова лежат" smile.gif . Была задача, передать массив в функцию, как аргумент - передали
defunct
Цитата
Была задача, передать массив в функцию, как аргумент - передали

То что вы засунули внутрь функции
void fun(array_as_param param).. ,
массивом назвать нельзя...
Проверить легко (обращение внутри функции):

param[0] = 0;
даст ошибку, а это значит, что не массив был передан в функцию.
prottoss
Цитата(defunct @ Jan 30 2007, 04:46) *
Цитата
Была задача, передать массив в функцию, как аргумент - передали

То что вы засунули внутрь функции
void fun(array_as_param param).. ,
массивом назвать нельзя...
Проверить легко (обращение внутри функции):
param[0] = 0;
даст ошибку, а это значит, что не массив был передан в функцию.
Это ровным счетом ничего не значит, потому что я могу сделать приведение к нужному мне типу. В конце концов, программу пишу я, и только я точно знаю что у меня внутри функции, а что с наружи. И если мне вздумалось передать массив как аргумент, то я из кожи вылезу но сделаю это smile.gif
SasaVitebsk
Чем прелестно программирование, что можно любую операцию сделать десятью способами. smile.gif Иногда создаётся впечатление, что у каждого есть свои излюбленные методы. Порой дико удивляешься (я говорю вообще а не о конкретном споре), что твой способ работы с данными соседом объявляется работой через ж... smile.gif Как?? Я же считал его самым правильным?! Возмущаешься ты. Да нет, - это самый неправильный из всех неправильных. biggrin.gif

Боюсь навлечь на себя критику, а также разборки моего текста (чего явно не желаю smile.gif ), но отмечу что мне кажется приведение типов не очень уж большая ошибка. Или так сказать непроффессиализм. Хотя бы для МК. Потому как иногда требуется прямое указание места размещения.

Например.
addr = ((uint8_t __flash *)symbol[tekfonts])+struct_fnt[tekfonts-2][Znak].sm;


Не претендую на истину. Но по умолчанию компилятор приводит к указателю на RAM.
prottoss
Цитата(defunct @ Jan 30 2007, 04:46) *
массивом назвать нельзя...
Проверить легко (обращение внутри функции):
param[0] = 0;
даст ошибку, а это значит, что не массив был передан в функцию.
Хорошо, вот Вам, уважаемый defunct простая задачка:

Есть структура, размером, ну так байт 64-256. И внутри некой функции, Вам необходимо, что бы все поля данной структуры были равны, допустим, нулю. Интересно, как Вы собираетесь решить данную проблему?
zltigo
Цитата(prottoss @ Jan 30 2007, 00:36) *
Цитата(defunct @ Jan 30 2007, 04:46) *
массивом назвать нельзя...
Проверить легко (обращение внутри функции):
param[0] = 0;
даст ошибку, а это значит, что не массив был передан в функцию.
Хорошо, вот Вам, уважаемый defunct простая задачка:

Есть структура, размером, ну так байт 64-256. И внутри некой функции, Вам необходимо, что бы все поля данной структуры были равны, допустим, нулю. Интересно, как Вы собираетесь решить данную проблему?

А, просите, какое отношение поставленая задачка имеет к непередаче массива в качестве параметра???
Ну как решается? Естественно sizeof() структуры и memset() ну и что?
prottoss
Цитата(zltigo @ Jan 30 2007, 06:26) *
А, просите, какое отношение поставленая задачка имеет к непередаче массива в качестве параметра??? Ну как решается? Естественно sizeof() структуры и memset() ну и что?
А самое непосредственное. Вы же, когда будете вызывать memset() передадите указатель на тип char? Не так ли? Хотя фактически это будет приведенный к указателю на char адрес Вашей структуры. Почему я в свою функцию не могу передать массив в качестве параметра, приведя его к типу своей структуры???
zltigo
Цитата(prottoss @ Jan 30 2007, 01:36) *
Вы же, когда будете вызывать memset() передадите указатель на тип char?

Передам указатель на область памяти и ее размер. Размер области памяти в общем случае даже не будет совпадать с размером полей структуры.
И совершенно не буду с упорством достойным лучшего применения утверждать, что передал указатель на структуру. Передал именно указатель на область памяти которая в качестве подмножества содержит наряду с мусором и кусочки памяти относящиеся к структуре. И работать memset() будет
с областью памяти обнулив и память относящуюся к тому что кото-то где-то считает относящуюся к структуре и всю прочую.
prottoss
Цитата(zltigo @ Jan 30 2007, 07:27) *
Передал именно указатель на область памяти которая в качестве подмножества содержит наряду с мусором и кусочки памяти относящиеся к структуре. И работать memset() будет
с областью памяти обнулив и память относящуюся к тому что кото-то где-то считает относящуюся к структуре и всю прочую.
Отлично. Тогда говоря Вашими терминами, я, в своем примере, в функцию, в качестве параметра, передал область памяти
dxp
Цитата(prottoss @ Jan 29 2007, 23:22) *
Цитата(dxp @ Jan 29 2007, 16:57) *
Покажите как? Как передать массив по значению (в качестве аргумента) в функцию?
Я показал, КАК МОЖНО ПЕРЕДАТЬ МАССИВ ПО ЗНАЧЕНИЮ, то бишь, В КАЧЕСТВЕ АРГУМЕНТА. Я не говорю, что я так делаю, я лишь показал то, что Вы просили:

массив array1 был передан в функцию в качестве аргумента - так? Или не так? Не надо объяснять - скажите - да или нет smile.gif

Нет!

У меня к Вам вопрос: можно ли в С/С++ передавать в функцию в качестве аргумента функцию?
SpiritDance
Цитата(prottoss @ Jan 30 2007, 01:15) *
И если мне вздумалось передать массив как аргумент, то я из кожи вылезу но сделаю это smile.gif

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

ЗЫ
Прямо какое-то обострение у контингента началось, везде дон кихоты от С с красными дипломами.
prottoss
Цитата(dxp @ Jan 30 2007, 12:09) *
Цитата(prottoss @ Jan 29 2007, 23:22) *

Цитата(dxp @ Jan 29 2007, 16:57) *
Покажите как? Как передать массив по значению (в качестве аргумента) в функцию?
Я показал, КАК МОЖНО ПЕРЕДАТЬ МАССИВ ПО ЗНАЧЕНИЮ, то бишь, В КАЧЕСТВЕ АРГУМЕНТА. Я не говорю, что я так делаю, я лишь показал то, что Вы просили:
массив array1 был передан в функцию в качестве аргумента - так? Или не так? Не надо объяснять - скажите - да или нет smile.gif
Нет!
А ЧТО тогда было переданно в функцию? smile.gif

Цитата(dxp @ Jan 30 2007, 12:09) *
У меня к Вам вопрос: можно ли в С/С++ передавать в функцию в качестве аргумента функцию?
Функцию нельзя, потому что на этапе компиляции не известен ее размер, адрес функции можно, потому что размер адреса известен
Сергей Борщ
Цитата(prottoss @ Jan 30 2007, 00:36) *
Есть структура, размером, ну так байт 64-256. И внутри некой функции, Вам необходимо, что бы все поля данной структуры были равны, допустим, нулю. Интересно, как Вы собираетесь решить данную проблему?
Код
typedef struct
{
  int fieldA;
  long fieldB[20];
}mystruct_t;

mystruct_t struct_to_be_cleared;
void main()
{
  {
    mystruct_t ZeroFilled = {0};
    struct_to_be_cleared = ZeroFilled;
  }

}
Какие указатели? "Какой такой павлин-мавлин?"(с)
prottoss
Цитата(SpiritDance @ Jan 30 2007, 15:42) *
Цитата(prottoss @ Jan 30 2007, 01:15) *
И если мне вздумалось передать массив как аргумент, то я из кожи вылезу но сделаю это smile.gif
Придется сильно попотеть smile.gif для того чтобы сделать так, как в используемом языке невозможно сделать. smile.gif
А потеть и не надо. Попробую еще раз объяснить. Есть определенный мною тип данных:

Код
typedef struct{

    UCHAR array[128];

} int128 /* к примеру */


Есть переменные, но они не приведены к данному типу:

Код
UCHAR a[128];

UCHAR b[128];


И есть функция, и не важно, что у нее внутри:

Код
void math128(int128 arg1, int128 arg2);


Я легко передаю в функцию два массива, приведя их к типу int128:

Код


.....

math128(*(int128 *)&a), *(int128 *)&b));

.....
Что я передал в функцию??? Два массива - a и b

Цитата(SpiritDance @ Jan 30 2007, 15:42) *
ЗЫ
Прямо какое-то обострение у контингента началось, везде дон кихоты от С с красными дипломами.
Не надо флудить и злорадно хихикать smile.gif Если у Вас есть что сказать по теме, говорите, если нет - тихо наблюдайте
prottoss
Цитата(Сергей Борщ @ Jan 30 2007, 16:13) *
Какие указатели? "Какой такой павлин-мавлин?"(с)
Вообще то говорилось, что структура попадает в функцию по значению, попробуйте присвоить ей { 0 }
dxp
Цитата(prottoss @ Jan 30 2007, 14:50) *
Цитата(dxp @ Jan 30 2007, 12:09) *
Цитата(prottoss @ Jan 29 2007, 23:22) *

Цитата(dxp @ Jan 29 2007, 16:57) *
Покажите как? Как передать массив по значению (в качестве аргумента) в функцию?
Я показал, КАК МОЖНО ПЕРЕДАТЬ МАССИВ ПО ЗНАЧЕНИЮ, то бишь, В КАЧЕСТВЕ АРГУМЕНТА. Я не говорю, что я так делаю, я лишь показал то, что Вы просили:
массив array1 был передан в функцию в качестве аргумента - так? Или не так? Не надо объяснять - скажите - да или нет smile.gif
Нет!
А ЧТО тогда было переданно в функцию? smile.gif

А Вы не знаете? СТРУКТУРА.

Цитата(prottoss @ Jan 30 2007, 14:50) *
Цитата(dxp @ Jan 30 2007, 12:09) *

У меня к Вам вопрос: можно ли в С/С++ передавать в функцию в качестве аргумента функцию?
Функцию нельзя, потому что на этапе компиляции не известен ее размер, адрес функции можно, потому что размер адреса известен

Да? А я Вам сейчас покажу вашим же способом, что можно:
Код
    void f(int);
    int g();
    ...
    f(g());

Ась? КаковО??! wink.gif И таким способом я могу что угодно передавать куда угодно. Просто волшебство!

Если серьезно, то советую хорошенько разобраться с порядком работы компилятора в этих местах - с тем, что такое временные объекты, время их жизни, когда они создаются, когда уничтожаются и т.д. Это веьсма важный вопрос, можно сказать, основы.
prottoss
Цитата(dxp @ Jan 30 2007, 16:51) *
Цитата(prottoss @ Jan 30 2007, 14:50) *

А ЧТО тогда было переданно в функцию? smile.gif

А Вы не знаете? СТРУКТУРА.
В функцию был передан массив по значению. Просто массив был приведен к типу обределенной мной структуры

Цитата(dxp @ Jan 30 2007, 16:51) *
Да? А я Вам сейчас покажу вашим же способом, что можно:
Код
    void f(int);
    int g();
    ...
    f(g());

Ась? КаковО??! wink.gif И таким способом я могу что угодно передавать куда угодно. Просто волшебство!
Вот что Ваш код делает: Вызывается функция g, и возвращаемое ею значение типа int передается функции f в качестве входного параметра. И что здесь волшебного? smile.gif . Ну если только это Ваши первые достижения в Си smile.gif

Цитата(dxp @ Jan 30 2007, 16:51) *
Если серьезно, то советую хорошенько разобраться с порядком работы компилятора в этих местах - с тем, что такое временные объекты, время их жизни, когда они создаются, когда уничтожаются и т.д. Это веьсма важный вопрос, можно сказать, основы.
дада и Вам того же smile.gif
dryadae
Цитата(prottoss @ Jan 30 2007, 02:36) *
Цитата(zltigo @ Jan 30 2007, 06:26) *
А, просите, какое отношение поставленая задачка имеет к непередаче массива в качестве параметра??? Ну как решается? Естественно sizeof() структуры и memset() ну и что?
А самое непосредственное. Вы же, когда будете вызывать memset() передадите указатель на тип char?

Неправда - void * smile.gif smile.gif smile.gif


Цитата(prottoss @ Jan 30 2007, 03:42) *
Цитата(zltigo @ Jan 30 2007, 07:27) *
Передал именно указатель на область памяти которая в качестве подмножества содержит наряду с мусором и кусочки памяти относящиеся к структуре. И работать memset() будет
с областью памяти обнулив и память относящуюся к тому что кото-то где-то считает относящуюся к структуре и всю прочую.
Отлично. Тогда говоря Вашими терминами, я, в своем примере, в функцию, в качестве параметра, передал область памяти

Вы передали то, что лежит в стеке. А в стеке лежит адрес (2 байта у near адресации, 4 у far/flat), и ничего больше excl.gif
"Передать" - значит затолкнуть в стек, а не засунуть в глобальную переменную, или куда-то там ещё...

push ebp
mov ebp, esp
start equ [ebp+4]
; вот где начинаются аргументы Вашей функции, порядок зависит от callspec
prottoss
Цитата(dryadae @ Jan 30 2007, 17:13) *
Цитата(prottoss @ Jan 30 2007, 02:36) *

Цитата(zltigo @ Jan 30 2007, 06:26) *
А, просите, какое отношение поставленая задачка имеет к непередаче массива в качестве параметра??? Ну как решается? Естественно sizeof() структуры и memset() ну и что?
А самое непосредственное. Вы же, когда будете вызывать memset() передадите указатель на тип char?

Неправда - void * smile.gif smile.gif smile.gif
Да здесь я ошибся, но спор шел о приведении типов

Цитата(dryadae @ Jan 30 2007, 17:13) *
Цитата(prottoss @ Jan 30 2007, 03:42) *

Цитата(zltigo @ Jan 30 2007, 07:27) *
Передал именно указатель на область памяти которая в качестве подмножества содержит наряду с мусором и кусочки памяти относящиеся к структуре. И работать memset() будет
с областью памяти обнулив и память относящуюся к тому что кото-то где-то считает относящуюся к структуре и всю прочую.
Отлично. Тогда говоря Вашими терминами, я, в своем примере, в функцию, в качестве параметра, передал область памяти

Вы передали то, что лежит в стеке. А в стеке лежит адрес (2 байта у near адресации, 4 у far/flat), и ничего больше excl.gif
"Передать" - значит затолкнуть в стек, а не засунуть в глобальную переменную, или куда-то там ещё...
А вот тут Вы не правы, в стек, или куда там еще, заталкивается ВЕСЬ массив, так как он передан по ЗНАЧЕНИЮ. Привожу листинг, скомпилированно IAR 4.10B:

Код
   71              fun(*(array_as_param *)array1);
   \   00000012   ....               LDI     R30, LOW(array1)
   \   00000014   ....               LDI     R31, (array1) >> 8
   \   00000016   E604               LDI     R16, 100
   \   00000018   E010               LDI     R17, 0
   \   0000001A   ........           CALL    ?LONG_FARG_16_L07 /* заталкивает куда то массив */
   \   0000001E   ....               RCALL   fun

............................................................................

Maximum stack usage in bytes:

     Function                       CSTACK RSTACK
     --------                       ------ ------
     fun                              100      2 /* стека данных используется как раз под наш МАССИВ */


PS: Если уж спорите, так держите под рукой компилятор, чтоб не голословить: + dxp
dryadae
Цитата(prottoss @ Jan 30 2007, 13:27) *
Цитата(dryadae @ Jan 30 2007, 17:13) *
Цитата(prottoss @ Jan 30 2007, 02:36) *

Цитата(zltigo @ Jan 30 2007, 06:26) *
А, просите, какое отношение поставленая задачка имеет к непередаче массива в качестве параметра??? Ну как решается? Естественно sizeof() структуры и memset() ну и что?
А самое непосредственное. Вы же, когда будете вызывать memset() передадите указатель на тип char?

Неправда - void * smile.gif smile.gif smile.gif
Да здесь я ошибся, но спор шел о приведении типов

Цитата(dryadae @ Jan 30 2007, 17:13) *
Цитата(prottoss @ Jan 30 2007, 03:42) *

Цитата(zltigo @ Jan 30 2007, 07:27) *
Передал именно указатель на область памяти которая в качестве подмножества содержит наряду с мусором и кусочки памяти относящиеся к структуре. И работать memset() будет
с областью памяти обнулив и память относящуюся к тому что кото-то где-то считает относящуюся к структуре и всю прочую.
Отлично. Тогда говоря Вашими терминами, я, в своем примере, в функцию, в качестве параметра, передал область памяти

Вы передали то, что лежит в стеке. А в стеке лежит адрес (2 байта у near адресации, 4 у far/flat), и ничего больше excl.gif
"Передать" - значит затолкнуть в стек, а не засунуть в глобальную переменную, или куда-то там ещё...
А вот тут Вы не правы, в стек, или куда там еще, заталкивается ВЕСЬ массив, так как он передан по ЗНАЧЕНИЮ. Привожу листинг, скомпилированно IAR 4.10B:

Кривой у вас компилятор blush.gif Писать с его помощью TSR и обработчики прерываний - смерти подобно.
И вообще, чтобы понять, надо не компилятором, а ручками. Тогда сразу станет ясна разница между Pascal и C, и то, что представляет из себя каждый тип.

Цитата
Код
   71              fun(*(array_as_param *)array1);
   \   00000012   ....               LDI     R30, LOW(array1)
   \   00000014   ....               LDI     R31, (array1) >> 8
   \   00000016   E604               LDI     R16, 100
   \   00000018   E010               LDI     R17, 0
   \   0000001A   ........           CALL    ?LONG_FARG_16_L07 /* заталкивает куда то массив */
   \   0000001E   ....               RCALL   fun

............................................................................

Maximum stack usage in bytes:

     Function                       CSTACK RSTACK
     --------                       ------ ------
     fun                              100      2 /* стека данных используется как раз под наш МАССИВ */


PS: Если уж спорите, так держите под рукой компилятор, чтоб не голословить: + dxp

Я не "голословлю", адрес тоже можно использовать как аргумент - например, в случае far-адресации для выяснения идентификатора процесса, который может равняться cs excl.gif

P.S. Кстати, команда call не заталкивает, а вызывает. По крайней мере, в 80x86 и Motorola 68K.
prottoss
Цитата(dryadae @ Jan 30 2007, 17:13) *
Вы передали то, что лежит в стеке. А в стеке лежит адрес (2 байта у near адресации, 4 у far/flat), и ничего больше excl.gif
"Передать" - значит затолкнуть в стек, а не засунуть в глобальную переменную, или куда-то там ещё...
push ebp
mov ebp, esp
start equ [ebp+4]
; вот где начинаются аргументы Вашей функции, порядок зависит от callspec
Аххха smile.gif Тихо переметнулись на х86. ОК smile.gif , вот мой код для х86



Код
22:       fun(*(array_as_param *)array1);
0040B548   sub         esp,64h /* итит ехо на лево, это что со стеком вытворяють!!! */
0040B54B   mov         ecx,19h
0040B550   mov         esi,offset array1 (0042281c)
0040B555   mov         edi,esp
0040B557   rep movs    dword ptr [edi],dword ptr [esi]
0040B559   call        @ILT+5(fun) (0040100a)
0040B55E   add         esp,64h  /* о, опять, надо Билу Гею пожаловаться!!! */




Цитата(dryadae @ Jan 30 2007, 17:49) *
P.S. Кстати, команда call не заталкивает, а вызывает. По крайней мере, в 80x86 и Motorola 68K.
нюню, а это чьи слова?

Цитата
"Передать" - значит затолкнуть в стек ©
Так вот, строчка

Код
0000001A   ........           CALL    ?LONG_FARG_16_L07


Как раз заталкивает (Вашими словами) в стек ВЕСЬ МАССИВ
prottoss
Цитата(dxp @ Jan 29 2007, 16:57) *
Цитата(prottoss @ Jan 29 2007, 14:38) *
И даже массив мона))) Ежели правильна приготовить smile.gif

Покажите как? Как передать массив по значению (в качестве аргумента) в функцию?


2 dxp:
так в итоге - Ваш вердикт: Возможно ли массив передать в функцию как аргумент функции?
SpiritDance
Цитата(prottoss @ Jan 30 2007, 12:15) *
Не надо флудить и злорадно хихикать smile.gif Если у Вас есть что сказать по теме, говорите, если нет - тихо наблюдайте

Вот что точно не надо так это говорить другим что им делать.
А теперь по теме. Рискну ответиь за dxp.

В С всегда можно предать пременную по значению, что вы и продемонстрировали. Но вы никогда не заставите компилятор предать в функцию массив пременных.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.