|
|
  |
в чем прелесть указателей ? |
|
|
|
Jan 29 2007, 05:03
|
Участник

Группа: Новичок
Сообщений: 73
Регистрация: 10-01-07
Пользователь №: 24 292

|
Растолкуйте популярно в чем польза от использования указателей. если возмжно то на примерах. Спасибо.
|
|
|
|
|
Jan 29 2007, 06:48
|
Частый гость
 
Группа: Validating
Сообщений: 80
Регистрация: 7-12-05
Пользователь №: 11 905

|
Цитата(Abakt @ Jan 29 2007, 08:03)  Растолкуйте популярно в чем польза от использования указателей. если возмжно то на примерах. Спасибо. Могу назвать один минус в использовании указателей  , если с ними не аккуратно работать то при обработке данных можно легко выйти за пределы обрабатываемого массива и записать данные в область памяти в которую данная функция записывать данные не должна. Причем компилятор вам об этом естествено не сообщит. Например вам необходимо записать число 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); } В данном случае ошибка с размером массива передаваемого при вызове функции.
|
|
|
|
|
Jan 29 2007, 09:19
|
Частый гость
 
Группа: Validating
Сообщений: 80
Регистрация: 7-12-05
Пользователь №: 11 905

|
Ну да еще структуру целиком нельзя передать в качестве аргумента функции. Ее можно передать в функцию только через указатель на структуру. Хотя структура помоему и используется в основном для делания пользовательских типов данных.
Сообщение отредактировал mihask - Jan 29 2007, 09:20
|
|
|
|
|
Jan 29 2007, 09:50
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(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++} /* инкрементировать адрес */ Лучше, конечно, литературку соответствующую почитать.  С книжкой то понятнее. Что то типа начальный курс Си и Си++
--------------------
|
|
|
|
|
Jan 29 2007, 10:07
|
Частый гость
 
Группа: Validating
Сообщений: 80
Регистрация: 7-12-05
Пользователь №: 11 905

|
Цитата(Abakt @ Jan 29 2007, 08:03)  Растолкуйте популярно в чем польза от использования указателей. если возмжно то на примерах. Спасибо. Вообще в Си например, без указателей, помоему довольно сложно программировать когда дело касается работы со структурами. Да и быстродействие и размер кода в приложениях для микроконтроллеров иногда имеет значение. А вот например современные языки программирования java,С# наоборот отказались от указателей для того что бы повысить надежность программ реализованных на этих языках.
|
|
|
|
|
Jan 29 2007, 10:39
|
Участник

Группа: Новичок
Сообщений: 73
Регистрация: 10-01-07
Пользователь №: 24 292

|
друзья, огромное спасибо. пошел тренироваться на "кошках" в смысле на сишках.
|
|
|
|
|
Jan 29 2007, 11:45
|
Частый гость
 
Группа: Validating
Сообщений: 80
Регистрация: 7-12-05
Пользователь №: 11 905

|
Цитата(dxp @ Jan 29 2007, 14:20)  Цитата(mihask @ Jan 29 2007, 12:19)  Ну да еще структуру целиком нельзя передать в качестве аргумента функции. Ее можно передать в функцию только через указатель на структуру.
Как это нельзя?! Еще как можно. И передавать, и возвращать. Это массив нельзя передать в качестве аргумента по значению (только указатель - имя массива в этом контексте автоматически перобразовывается к указателю на его первый элемент), а структуру вполне можно. Ой звиняюсь обманул  , но это ограничение все таки было  правда в очень древних реализациях Си
Сообщение отредактировал mihask - Jan 29 2007, 11:50
|
|
|
|
|
Jan 29 2007, 12:10
|
Частый гость
 
Группа: Участник
Сообщений: 96
Регистрация: 24-09-05
Пользователь №: 8 901

|
Цитата(prottoss @ Jan 29 2007, 11:38)  Цитата(dxp @ Jan 29 2007, 15:20)  Цитата(mihask @ Jan 29 2007, 12:19)  Ну да еще структуру целиком нельзя передать в качестве аргумента функции. Ее можно передать в функцию только через указатель на структуру.
Как это нельзя?! Еще как можно. И передавать, и возвращать. Это массив нельзя передать в качестве аргумента по значению (только указатель - имя массива в этом контексте автоматически перобразовывается к указателю на его первый элемент), а структуру вполне можно. И даже массив мона))) Ежели правильна приготовить  А ежели правильно приготовить с указателями на функции, то можно получить и объект который сам себя будет и обрабатывать.
Сообщение отредактировал unichorn - Jan 29 2007, 12:10
|
|
|
|
|
Jan 29 2007, 12:29
|
Частый гость
 
Группа: Validating
Сообщений: 80
Регистрация: 7-12-05
Пользователь №: 11 905

|
Цитата(unichorn @ Jan 29 2007, 15:10)  Цитата(prottoss @ Jan 29 2007, 11:38)  Цитата(dxp @ Jan 29 2007, 15:20)  Цитата(mihask @ Jan 29 2007, 12:19)  Ну да еще структуру целиком нельзя передать в качестве аргумента функции. Ее можно передать в функцию только через указатель на структуру.
Как это нельзя?! Еще как можно. И передавать, и возвращать. Это массив нельзя передать в качестве аргумента по значению (только указатель - имя массива в этом контексте автоматически перобразовывается к указателю на его первый элемент), а структуру вполне можно. И даже массив мона))) Ежели правильна приготовить  А ежели правильно приготовить с указателями на функции, то можно получить и объект который сам себя будет и обрабатывать.  Звиняюсь - а здесь можно по подробней ?  Это ведь получается Объектно - Ориентированное программирование на Си ? Можно наглядный примерчик этой штуки ?
|
|
|
|
|
Jan 29 2007, 13:10
|
Частый гость
 
Группа: Участник
Сообщений: 96
Регистрация: 24-09-05
Пользователь №: 8 901

|
Примерчик можно, сам проэкт сдох чёрт знает когда, поэтому коммерческой ценности непредставляет (и соответственно недаделан). Правда он под семейство MCU51(Keil2), но для понятия сути вещей сгодится. PS: ногами сильно непинать, делалось всё на скорую руку, хотя по датам можно понять оч медленно (изначально было ясно что прект загнётся).
Сообщение отредактировал unichorn - Jan 29 2007, 13:22
Прикрепленные файлы
Device.rar ( 364.23 килобайт )
Кол-во скачиваний: 73
|
|
|
|
|
Jan 29 2007, 13:46
|
Частый гость
 
Группа: Validating
Сообщений: 80
Регистрация: 7-12-05
Пользователь №: 11 905

|
Цитата(unichorn @ Jan 29 2007, 16:10)  Примерчик можно, сам проэкт сдох чёрт знает когда, поэтому коммерческой ценности непредставляет (и соответственно недаделан). Правда он под семейство MCU51(Keil2), но для понятия сути вещей сгодится.
PS: ногами сильно непинать, делалось всё на скорую руку, хотя по датам можно понять оч медленно (изначально было ясно что прект загнётся). Спасибо, обязательно посмотрю
|
|
|
|
|
Jan 29 2007, 15:36
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(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); Вопрос стоял о том, как передать массив по значению в качестве аргумента. А не о том, как переправить значения массива в функцию. Т.ч., как говорилось, массив всегда в функцию передается через указатель.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jan 29 2007, 16:02
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

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

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(dxp @ Jan 29 2007, 19:36)  Здесь передается не массив, а структура: void fun(array_as_param param), где array_as_param - это структура (как видно выше) Цитата(prottoss @ Jan 29 2007, 19:02)  Здесь в качестве параметра передается ИМЕННО МАССИВ  , НО выдаем мы его за структуру  Еще раз. Функция: 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)  Вы хоть сами то читаете и проверяете то что пишите??? Эта строчка никогда работать не будет. Ну а так, вообще, красиво написанно  Может быть Вы имели ввиду это Код 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)  Вопрос стоял о том, как передать массив по значению в качестве аргумента. Ответ получен - МОЖНО По аргументу реально передан не массив, а структура, что и есть верный ответ. С тем же, что есть способ передать значения массива в функцию, никто не спорил изначально. И даже показано более читабельное и безопасное решение.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jan 29 2007, 22:27
|
Участник

Группа: Новичок
Сообщений: 73
Регистрация: 10-01-07
Пользователь №: 24 292

|
Цитата(el34 @ Jan 29 2007, 14:15)  2Abakt оч. рекомендую поглядеть "Ted Jensen's Tutorial on Pointers and Arrays in C" http://pw2.netcom.com/~tjensen/ptr/ Огромное спасибо! Читаю.
|
|
|
|
|
Jan 30 2007, 00:46
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата Была задача, передать массив в функцию, как аргумент - передали То что вы засунули внутрь функции void fun(array_as_param param).. , массивом назвать нельзя... Проверить легко (обращение внутри функции): param[0] = 0; даст ошибку, а это значит, что не массив был передан в функцию.
|
|
|
|
|
Jan 30 2007, 01:15
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(defunct @ Jan 30 2007, 04:46)  Цитата Была задача, передать массив в функцию, как аргумент - передали То что вы засунули внутрь функции void fun(array_as_param param).. , массивом назвать нельзя... Проверить легко (обращение внутри функции): param[0] = 0; даст ошибку, а это значит, что не массив был передан в функцию. Это ровным счетом ничего не значит, потому что я могу сделать приведение к нужному мне типу. В конце концов, программу пишу я, и только я точно знаю что у меня внутри функции, а что с наружи. И если мне вздумалось передать массив как аргумент, то я из кожи вылезу но сделаю это
--------------------
|
|
|
|
|
Jan 30 2007, 01:26
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Чем прелестно программирование, что можно любую операцию сделать десятью способами.  Иногда создаётся впечатление, что у каждого есть свои излюбленные методы. Порой дико удивляешься (я говорю вообще а не о конкретном споре), что твой способ работы с данными соседом объявляется работой через ж...  Как?? Я же считал его самым правильным?! Возмущаешься ты. Да нет, - это самый неправильный из всех неправильных. Боюсь навлечь на себя критику, а также разборки моего текста (чего явно не желаю  ), но отмечу что мне кажется приведение типов не очень уж большая ошибка. Или так сказать непроффессиализм. Хотя бы для МК. Потому как иногда требуется прямое указание места размещения. Например. addr = ((uint8_t __flash *)symbol[tekfonts])+struct_fnt[tekfonts-2][Znak].sm; Не претендую на истину. Но по умолчанию компилятор приводит к указателю на RAM.
|
|
|
|
|
Jan 30 2007, 01:36
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

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

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

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

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
Цитата(prottoss @ Jan 30 2007, 01:36)  Вы же, когда будете вызывать memset() передадите указатель на тип char? Передам указатель на область памяти и ее размер. Размер области памяти в общем случае даже не будет совпадать с размером полей структуры. И совершенно не буду с упорством достойным лучшего применения утверждать, что передал указатель на структуру. Передал именно указатель на область памяти которая в качестве подмножества содержит наряду с мусором и кусочки памяти относящиеся к структуре. И работать memset() будет с областью памяти обнулив и память относящуюся к тому что кото-то где-то считает относящуюся к структуре и всю прочую.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 30 2007, 08:09
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

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

Дух погибшего транзистора
   
Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288

|
Цитата(prottoss @ Jan 30 2007, 01:15)  И если мне вздумалось передать массив как аргумент, то я из кожи вылезу но сделаю это  Придется сильно попотеть  для того чтобы сделать так, как в используемом языке невозможно сделать. ЗЫ Прямо какое-то обострение у контингента началось, везде дон кихоты от С с красными дипломами.
--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
|
|
|
|
|
Jan 30 2007, 11:50
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

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

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(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; }
} Какие указатели? "Какой такой павлин-мавлин?"(с)
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 30 2007, 12:15
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(SpiritDance @ Jan 30 2007, 15:42)  Цитата(prottoss @ Jan 30 2007, 01:15)  И если мне вздумалось передать массив как аргумент, то я из кожи вылезу но сделаю это  Придется сильно попотеть  для того чтобы сделать так, как в используемом языке невозможно сделать. А потеть и не надо. Попробую еще раз объяснить. Есть определенный мною тип данных: Код 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)  ЗЫ Прямо какое-то обострение у контингента началось, везде дон кихоты от С с красными дипломами. Не надо флудить и злорадно хихикать  Если у Вас есть что сказать по теме, говорите, если нет - тихо наблюдайте
--------------------
|
|
|
|
|
Jan 30 2007, 12:51
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(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 был передан в функцию в качестве аргумента - так? Или не так? Не надо объяснять - скажите - да или нет Нет! А ЧТО тогда было переданно в функцию? А Вы не знаете? СТРУКТУРА. Цитата(prottoss @ Jan 30 2007, 14:50)  Цитата(dxp @ Jan 30 2007, 12:09)  У меня к Вам вопрос: можно ли в С/С++ передавать в функцию в качестве аргумента функцию?
Функцию нельзя, потому что на этапе компиляции не известен ее размер, адрес функции можно, потому что размер адреса известен Да? А я Вам сейчас покажу вашим же способом, что можно: Код void f(int); int g(); ... f(g()); Ась? КаковО??!  И таким способом я могу что угодно передавать куда угодно. Просто волшебство! Если серьезно, то советую хорошенько разобраться с порядком работы компилятора в этих местах - с тем, что такое временные объекты, время их жизни, когда они создаются, когда уничтожаются и т.д. Это веьсма важный вопрос, можно сказать, основы.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jan 30 2007, 13:03
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(dxp @ Jan 30 2007, 16:51)  Цитата(prottoss @ Jan 30 2007, 14:50)  А ЧТО тогда было переданно в функцию?  А Вы не знаете? СТРУКТУРА. В функцию был передан массив по значению. Просто массив был приведен к типу обределенной мной структуры Цитата(dxp @ Jan 30 2007, 16:51)  Да? А я Вам сейчас покажу вашим же способом, что можно: Код void f(int); int g(); ... f(g()); Ась? КаковО??!  И таким способом я могу что угодно передавать куда угодно. Просто волшебство! Вот что Ваш код делает: Вызывается функция g, и возвращаемое ею значение типа int передается функции f в качестве входного параметра. И что здесь волшебного?  . Ну если только это Ваши первые достижения в Си Цитата(dxp @ Jan 30 2007, 16:51)  Если серьезно, то советую хорошенько разобраться с порядком работы компилятора в этих местах - с тем, что такое временные объекты, время их жизни, когда они создаются, когда уничтожаются и т.д. Это веьсма важный вопрос, можно сказать, основы. дада и Вам того же
--------------------
|
|
|
|
|
Jan 30 2007, 13:13
|
Частый гость
 
Группа: Новичок
Сообщений: 154
Регистрация: 7-03-06
Пользователь №: 15 051

|
Цитата(prottoss @ Jan 30 2007, 02:36)  Цитата(zltigo @ Jan 30 2007, 06:26)  А, просите, какое отношение поставленая задачка имеет к непередаче массива в качестве параметра??? Ну как решается? Естественно sizeof() структуры и memset() ну и что? А самое непосредственное. Вы же, когда будете вызывать memset() передадите указатель на тип char? Неправда - void * Цитата(prottoss @ Jan 30 2007, 03:42)  Цитата(zltigo @ Jan 30 2007, 07:27)  Передал именно указатель на область памяти которая в качестве подмножества содержит наряду с мусором и кусочки памяти относящиеся к структуре. И работать memset() будет с областью памяти обнулив и память относящуюся к тому что кото-то где-то считает относящуюся к структуре и всю прочую. Отлично. Тогда говоря Вашими терминами, я, в своем примере, в функцию, в качестве параметра, передал область памятиВы передали то, что лежит в стеке. А в стеке лежит адрес (2 байта у near адресации, 4 у far/ flat), и ничего больше  "Передать" - значит затолкнуть в стек, а не засунуть в глобальную переменную, или куда-то там ещё... push ebp mov ebp, esp start equ [ebp+4] ; вот где начинаются аргументы Вашей функции, порядок зависит от callspec
Сообщение отредактировал dryadae - Jan 30 2007, 13:24
|
|
|
|
|
Jan 30 2007, 13:27
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(dryadae @ Jan 30 2007, 17:13)  Цитата(prottoss @ Jan 30 2007, 02:36)  Цитата(zltigo @ Jan 30 2007, 06:26)  А, просите, какое отношение поставленая задачка имеет к непередаче массива в качестве параметра??? Ну как решается? Естественно sizeof() структуры и memset() ну и что? А самое непосредственное. Вы же, когда будете вызывать memset() передадите указатель на тип char? Неправда - void * Да здесь я ошибся, но спор шел о приведении типов Цитата(dryadae @ Jan 30 2007, 17:13)  Цитата(prottoss @ Jan 30 2007, 03:42)  Цитата(zltigo @ Jan 30 2007, 07:27)  Передал именно указатель на область памяти которая в качестве подмножества содержит наряду с мусором и кусочки памяти относящиеся к структуре. И работать memset() будет с областью памяти обнулив и память относящуюся к тому что кото-то где-то считает относящуюся к структуре и всю прочую. Отлично. Тогда говоря Вашими терминами, я, в своем примере, в функцию, в качестве параметра, передал область памятиВы передали то, что лежит в стеке. А в стеке лежит адрес (2 байта у near адресации, 4 у far/ flat), и ничего больше "Передать" - значит затолкнуть в стек, а не засунуть в глобальную переменную, или куда-то там ещё... А вот тут Вы не правы, в стек, или куда там еще, заталкивается ВЕСЬ массив, так как он передан по ЗНАЧЕНИЮ. Привожу листинг, скомпилированно 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
--------------------
|
|
|
|
|
Jan 30 2007, 13:49
|
Частый гость
 
Группа: Новичок
Сообщений: 154
Регистрация: 7-03-06
Пользователь №: 15 051

|
Цитата(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 * Да здесь я ошибся, но спор шел о приведении типов Цитата(dryadae @ Jan 30 2007, 17:13)  Цитата(prottoss @ Jan 30 2007, 03:42)  Цитата(zltigo @ Jan 30 2007, 07:27)  Передал именно указатель на область памяти которая в качестве подмножества содержит наряду с мусором и кусочки памяти относящиеся к структуре. И работать memset() будет с областью памяти обнулив и память относящуюся к тому что кото-то где-то считает относящуюся к структуре и всю прочую. Отлично. Тогда говоря Вашими терминами, я, в своем примере, в функцию, в качестве параметра, передал область памятиВы передали то, что лежит в стеке. А в стеке лежит адрес (2 байта у near адресации, 4 у far/ flat), и ничего больше "Передать" - значит затолкнуть в стек, а не засунуть в глобальную переменную, или куда-то там ещё... А вот тут Вы не правы, в стек, или куда там еще, заталкивается ВЕСЬ массив, так как он передан по ЗНАЧЕНИЮ. Привожу листинг, скомпилированно IAR 4.10B: Кривой у вас компилятор  Писать с его помощью 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 P.S. Кстати, команда call не заталкивает, а вызывает. По крайней мере, в 80x86 и Motorola 68K.
Сообщение отредактировал dryadae - Jan 30 2007, 13:55
|
|
|
|
|
Jan 30 2007, 14:12
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(dryadae @ Jan 30 2007, 17:13)  Вы передали то, что лежит в стеке. А в стеке лежит адрес (2 байта у near адресации, 4 у far/ flat), и ничего больше "Передать" - значит затолкнуть в стек, а не засунуть в глобальную переменную, или куда-то там ещё... push ebp mov ebp, esp start equ [ebp+4] ; вот где начинаются аргументы Вашей функции, порядок зависит от callspec Аххха  Тихо переметнулись на х86. ОК  , вот мой код для х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 Как раз заталкивает (Вашими словами) в стек ВЕСЬ МАССИВ
--------------------
|
|
|
|
|
Jan 30 2007, 14:40
|

Дух погибшего транзистора
   
Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288

|
Цитата(prottoss @ Jan 30 2007, 12:15)  Не надо флудить и злорадно хихикать  Если у Вас есть что сказать по теме, говорите, если нет - тихо наблюдайте Вот что точно не надо так это говорить другим что им делать. А теперь по теме. Рискну ответиь за dxp. В С всегда можно предать пременную по значению, что вы и продемонстрировали. Но вы никогда не заставите компилятор предать в функцию массив пременных.
--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
|
|
|
|
|
Jan 30 2007, 14:43
|
Частый гость
 
Группа: Новичок
Сообщений: 154
Регистрация: 7-03-06
Пользователь №: 15 051

|
Цитата Цитата(dryadae @ Jan 30 2007, 17:49)  P.S. Кстати, команда call не заталкивает, а вызывает. По крайней мере, в 80x86 и Motorola 68K. нюню, а это чьи слова? Цитата "Передать" - значит затолкнуть в стек © Так вот, строчка Код 0000001A ........ CALL ?LONG_FARG_16_L07 Как раз заталкивает (Вашими словами) в стек ВЕСЬ МАССИВ Странный Вы человек. Сами написали в комменте напротив CALL'а "заталкивает", и теперь ставите знак равенства между вашей нетночностью и моими словами
Сообщение отредактировал dryadae - Jan 30 2007, 14:48
|
|
|
|
|
Jan 30 2007, 14:47
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(SpiritDance @ Jan 30 2007, 18:40)  Цитата(prottoss @ Jan 30 2007, 12:15)  Не надо флудить и злорадно хихикать  Если у Вас есть что сказать по теме, говорите, если нет - тихо наблюдайте Вот что точно не надо так это говорить другим что им делать. А теперь по теме. Рискну ответиь за dxp. В С всегда можно предать пременную по значению, что вы и продемонстрировали. Но вы никогда не заставите компилятор предать в функцию массив пременных. А я уже заставил - два раза показывал. Объявил массив array1 и передал его в качестве параметра функции fun. И не надо мне говорить - правильно это или не правильно и как я это сделал. Примите просто как факт - ЭТО СДЕЛАННО.
--------------------
|
|
|
|
|
Jan 30 2007, 15:05
|
Частый гость
 
Группа: Новичок
Сообщений: 154
Регистрация: 7-03-06
Пользователь №: 15 051

|
Цитата(prottoss @ Jan 30 2007, 15:01)  Цитата(dryadae @ Jan 30 2007, 18:50)  Да Бог с вами. Только накушаетесь вы со стеком, помяните моё слово. Да кто Вам сказал, что я ТАК делаю. Я лишь неосторожно сказал, что МОЖНО передать массив в качестве аргумента, и добавил - ежели правильно приготовить массив. Это не Си, это компайлер такой. Цитата(prottoss @ Jan 30 2007, 15:01)  Бугага  Си, и тем паче с плюсиками, предоставляет очень много возможностей использовать тривиальные вещи не тривиально. О да. С весьма сомнительной совместимостью. Вспомнить хотя бы те же DDVT - понту было много, а толку? Где сейчас BC, и иже с ним?
Сообщение отредактировал dryadae - Jan 30 2007, 15:05
|
|
|
|
|
Jan 30 2007, 15:24
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(SpiritDance @ Jan 30 2007, 19:12)  Цитата(prottoss @ Jan 30 2007, 14:47)  Примите просто как факт - ЭТО СДЕЛАННО.
Суть в том что Вы сами до конца не понимаете что сделали с точки зрения семантики языка. Функция fun ну или math128 принимают в качестве значений не массивы, а пременные, определенного вами типа. Ну да Бог с Вами. Да нет, я все прекрасно понимаю. А суть в том, что Вы просто выбрали позицию большинсва, хотя все, кто учавствует в споре, я надеюсь, прекрасно понимают о чем говорят и что я имею ввиду. Ну да и Бог с нами со всеми
--------------------
|
|
|
|
|
Jan 30 2007, 16:15
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(prottoss @ Jan 30 2007, 16:03)  Цитата(dxp @ Jan 30 2007, 16:51)  Цитата(prottoss @ Jan 30 2007, 14:50)  А ЧТО тогда было переданно в функцию?  А Вы не знаете? СТРУКТУРА. В функцию был передан массив по значению. Просто массив был приведен к типу обределенной мной структуры В функцию были переданы значения массива путем помещения их (значений) в структуру, но не массив. Массив в С/С++ нельзя передать по значению.Цитата(prottoss @ Jan 30 2007, 16:03)  Цитата(dxp @ Jan 30 2007, 16:51)  Да? А я Вам сейчас покажу вашим же способом, что можно: Код void f(int); int g(); ... f(g()); Ась? КаковО??!  И таким способом я могу что угодно передавать куда угодно. Просто волшебство! Вот что Ваш код делает: Вызывается функция g, и возвращаемое ею значение типа int передается функции f в качестве входного параметра. О! Уже неплохо! Теперь экстаполируем этот пример на массивы и структуры: там сначала формируется временный объект типа структура (в стеке) и затем этот временный объект типа структура передается в функцию. Т.е. в функцию передается структура, а не массив. Цитата(prottoss @ Jan 30 2007, 16:03)  И что здесь волшебного?  . Ну если только это Ваши первые достижения в Си  Послушайте, уважаемый, у меня было уже ...дцать поводов перейти на оценку Вашего скилла в обсуждаемом вопросе, но я от этого воздержался и в конце концов доброжелательно посоветовал Вам восполнить пробелы в знаниях по языку. Вы же вместо этого просто начали хамить. Что ж, если угодно оставаться в воинствующем неведении, это дело хозяйское, я как мог старался помочь и старался быть корректным. С меня достаточно, жизнь Вас лучше научит (когда придете устраиваться на работу и будете отвечать на эти вопросы на продемонстрированном уровне). Всего Вам.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jan 30 2007, 16:43
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(dxp @ Jan 30 2007, 20:15)  Послушайте, уважаемый, у меня было уже ...дцать поводов перейти на оценку Вашего скилла в обсуждаемом вопросе, но я от этого воздержался и в конце концов доброжелательно посоветовал Вам восполнить пробелы в знаниях по языку. Вы же вместо этого просто начали хамить. Что ж, если угодно оставаться в воинствующем неведении, это дело хозяйское, я как мог старался помочь и старался быть корректным. С меня достаточно, жизнь Вас лучше научит (когда придете устраиваться на работу и будете отвечать на эти вопросы на продемонстрированном уровне). Всего Вам. Извиняюсь, если я обидел Вас своими репликами Цитата(dxp @ Jan 30 2007, 16:51)  В функцию были переданы значения массива путем помещения их (значений) в структуру, но не массив. Массив в С/С++ нельзя передать по значению. Масло масленное. Правильно, массив нельзя, структуру можно. Теперь, если мы адрес массива приведем к типу структуры мы, фактически, передаем массив в функцию, точнее его копию. И, если и с наружи и внутри функции все знают, что под оберткой передаваемой переменой, то все хлопают в ладоши - массив передан по значению. Еще раз повторюсь. Функция принимает по значению структуру, но мы подсунули ей массив, под видом структуры. И еще раз повторю начало нашего никчемного спора: prottoss: И даже массив мона))) Ежели правильна приготовить dxp: Покажите как? Как передать массив по значению (в качестве аргумента) в функцию? prottoss: ...показываю... dxp: Здесь передается не массив, а структура... Функция принимает в качестве аргумента структуру, но я, правильно его приготовив, скормил его функции, всего то
--------------------
|
|
|
|
|
Jan 30 2007, 16:55
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(prottoss @ Jan 30 2007, 11:29)  Цитата(Сергей Борщ @ Jan 30 2007, 16:13)  Какие указатели? "Какой такой павлин-мавлин?"(с) Вообще то говорилось, что структура попадает в функцию по значению, попробуйте присвоить ей { 0 } Читайте по губам что спрашивалось, и на что был дан ответ: Цитата(prottoss @ Jan 30 2007, 00:36)  Вам необходимо, что бы все поля данной структуры были равны, допустим, нулю.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 30 2007, 17:13
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(Сергей Борщ @ Jan 30 2007, 20:55)  Цитата(prottoss @ Jan 30 2007, 11:29)  Цитата(Сергей Борщ @ Jan 30 2007, 16:13)  Какие указатели? "Какой такой павлин-мавлин?"(с) Вообще то говорилось, что структура попадает в функцию по значению, попробуйте присвоить ей { 0 } Читайте по губам что спрашивалось, и на что был дан ответ: Цитата(prottoss @ Jan 30 2007, 00:36)  Вам необходимо, что бы все поля данной структуры были равны, допустим, нулю. Здесь подразумевалось, что структура передается в функцию, а не объявляется внутри функции
--------------------
|
|
|
|
|
Jan 30 2007, 18:12
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
Цитата(defunct @ Jan 30 2007, 22:06)  protossЦитата прекрасно понимают о чем говорят и что я имею ввиду. Тогда, что с вашей точки зрения передается здесь: Код void fun(U8 *param, U16 size) { ... работаем с массивом param вместо sizeof используем переданный size }
U8 array1[100];
fun( array1, sizeof(array1) ); Здесь передается указатель, и его размер (указателя) в байтах
--------------------
|
|
|
|
|
Jan 30 2007, 18:20
|
Частый гость
 
Группа: Новичок
Сообщений: 154
Регистрация: 7-03-06
Пользователь №: 15 051

|
Цитата(prottoss @ Jan 30 2007, 18:12)  Цитата(defunct @ Jan 30 2007, 22:06)  protossЦитата прекрасно понимают о чем говорят и что я имею ввиду. Тогда, что с вашей точки зрения передается здесь: Код void fun(U8 *param, U16 size) { ... работаем с массивом param вместо sizeof используем переданный size }
U8 array1[100];
fun( array1, sizeof(array1) ); Здесь передается указатель, и его размер (указателя) в байтах Размер указателя всегда один На 32-битной архитектуре он равен 4-м байтам, на 16-битной - двум. Без вариантов  Кроме случая far. P.S. Размер указателя на указатель - тоже
|
|
|
|
|
Jan 31 2007, 02:17
|

кекс
     
Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326

|
Цитата(prottoss @ Jan 30 2007, 18:01)  Цитата(prottoss @ Jan 30 2007, 22:12)  Здесь передается указатель, и его размер (указателя) в байтах Сорри  размер массива  Верно. Указатель и размер. Указатель в C это есть безразмерный массив (за исключением указателя на void) Относительно моего примера. Массив мы передали в функцию - нет он остался где-то снаружи. Работать внутри функции с этим массивом можем - да. Как с массивом - да. В чем же отличие от передачи структуры - в том, что структура передается через стек и будет локальной переменной внутри функции, т.е. все ее поля будут продублированы и при изменении ее полей внутри функции оригинал не изменится. После выхода из функции эта структура автоматически уничтожится (Вы уже в курсе, даже продемонстрировали asm листинги). Массив при передаче в функцию через указатель никуда не копируется и работаем мы сразу с оригиналом. При передаче через указатель неудобство лишь одно - нельзя узнать размер массива, поэтому его (размер массива) требуется передавать отдельно.
|
|
|
|
|
  |
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0
|
|
|