реклама на сайте
подробности

 
 
> Keil Оптимизатор
vlad_new
сообщение Jan 16 2012, 16:45
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Как использовать переменные типа volatile и одновременно пользоваться стандартными библиотеками, где все сплошником char*.
Приходится везде вписыать что то типа:
volatile char Buf1[100], Buf2[100];
.....
memcopy((char*)Buf1,(char*)Buf2,20);
.....
Если же Buf не будут volatile, то оптимизатор выбрасывает строки типа: Buf1[0]=7;
Может как то можно переопределить в билиотеках char на volatile char, ну или еще как то справится с этими неудобствами?

Сообщение отредактировал vlad_new - Jan 16 2012, 16:49
Go to the top of the page
 
+Quote Post
3 страниц V   1 2 3 >  
Start new topic
Ответов (1 - 33)
scifi
сообщение Jan 16 2012, 18:08
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(vlad_new @ Jan 16 2012, 20:45) *
Если же Buf не будут volatile, то оптимизатор выбрасывает строки типа: Buf1[0]=7;

А почему это проблема? Если выбрасывает, значит они не нужны.
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jan 16 2012, 18:43
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Цитата(scifi @ Jan 16 2012, 22:08) *
А почему это проблема? Если выбрасывает, значит они не нужны.


Вот пример кода.
Заполняем массив Buf_RS485 и отправляем его в UART. Первый байт в массиве определяет его длинну.
Первые 2 строки после case00: копируют некие данные известной длинны. Поэтому в следующей строке эта длинна и записывается.
Далее, если есть Cnt_sob, то туда еще кучка всего вписывается и другая длинна перезаписывается.
Таким образом отправляется либо короткий, либо более длинный пакет.
Так вот 3 строку оптимизатор игнорирует и пакет отправляется с неверной длинной!

Код
vu8  Buf_RS485[256];  // Глобальная

void sw_get(void)
{
u32 i, j, k, u;

switch(GetSet)
  {

  case 0x00: Pool=1; RX_RS485=1;                                
             memcpy((char*)Buf_RS485+1,Mac_mas_bcd,4);  
             memcpy((char*)Buf_RS485+5,Mac_sl_bcd,4); u=9;
             Buf_RS485[0]=u-1;                                  

             if(Cnt_sob)                
               {
               j=EE_rd_byte(UK_WRS);      
               if(j>=Cnt_sob) k=j-Cnt_sob;
               else k=KOL_BUF-(Cnt_sob-j);
               k=k*LEN_SOB+BAZA_S; i=0;
               EE_rd_nbyte(k,Buf_tmp,64); Buf_tmp[64]=0;  
               k=strlen((char*)Buf_tmp); k=k-6; Buf_RS485[u++]=k|0x40;
               for(i=0; i<12; i=i+2,u++)
                 Buf_RS485[u]=((Buf_tmp[i]-0x30)<<4)|((Buf_tmp[i+1]-0x30)&0xF);
               for(i=0; i<(k-6); i++) Buf_RS485[u++]=Buf_tmp[i+12];
               Buf_RS485[0]=u-1;                                
               }

             SEND_RS485; return;
.........
   }


Сообщение отредактировал IgorKossak - Jan 17 2012, 08:12
Причина редактирования: [code]
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Jan 16 2012, 18:57
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Несовсем понятно о какой строчке идёт речь. Можекте пометить её в исходнике?

Сообщение отредактировал Genadi Zawidowski - Jan 16 2012, 18:57
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jan 16 2012, 19:07
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Цитата(Genadi Zawidowski @ Jan 16 2012, 22:57) *
Несовсем понятно о какой строчке идёт речь. Можекте пометить её в исходнике?

Угу. Пометил. Вот эта имелась ввиду:
Buf_RS485[0]=u-1;

Сообщение отредактировал vlad_new - Jan 16 2012, 19:09
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 16 2012, 19:34
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Этот код какой-то кривой. Например, переменная 'char Buf_RS485;' используется как массив. Что это? Неточно запостили? Будьте любезны постить реальный код. Кто знает, что Вы там ещё переиначили? И лучше с отступами, а также обрамлять тегами (code)(/code).
Вы подозреваете баг в компиляторе, а я подозреваю баг в программе. Чаще бывает второе.
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jan 16 2012, 19:51
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Цитата(scifi @ Jan 16 2012, 23:34) *
Этот код какой-то кривой. Например, переменная 'char Buf_RS485;' используется как массив. Что это? Неточно запостили? Будьте любезны постить реальный код. Кто знает, что Вы там ещё переиначили? И лучше с отступами, а также обрамлять тегами (code)(/code).
Вы подозреваете баг в компиляторе, а я подозреваю баг в программе. Чаще бывает второе.

Уже подправил. Реальный код слишком длинный. К тому же похожие проблеммы с оптимизатором не редки. И как правило когда индекс =0, или он const.
Иногда помагало обозвать переменную индекса массива как static. Но вот в этом куске бубны с танцами не помогли.

Сообщение отредактировал vlad_new - Jan 16 2012, 19:52
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 16 2012, 20:03
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(vlad_new @ Jan 16 2012, 23:51) *
Уже подправил. Реальный код слишком длинный. К тому же похожие проблеммы с оптимизатором не редки. И как правило когда индекс =0, или он const.
Иногда помагало обозвать переменную индекса массива как static. Но вот в этом куске бубны с танцами не помогли.

Это глюки в программе с вероятностью 99%.
Поскольку реальный код видеть нет возможности, то больше сказать нечего. Даже если бы был реальный код, было бы слишком трудно в нём разобраться, так как написан он (если судить по показанному отрывку) не самым лучшим образом, мягко говоря.

Update:
Забыл добавить. О глюках судят по результатам выполнения программы. Например, если содержимое пакета данных на проводе отличается от ожидаемого. Если Вы смотрите на содержимое переменных в отладчике и видите неожиданные значения - не факт, что это глюк. На высоких уровнях оптимизации бывает так, что данные отладчика весьма слабо коррелируют с исходным кодом. И вообще отлаживать удобнее на самом низком уровне оптимизации.
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jan 16 2012, 20:12
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Цитата(scifi @ Jan 17 2012, 00:03) *
Это глюки в программе с вероятностью 99%.
Поскольку реальный код видеть нет возможности, то больше сказать нечего. Даже если бы был реальный код, было бы слишком трудно в нём разобраться, так как написан он (если судить по показанному отрывку) не самым лучшим образом, мягко говоря.

Да отступы почему то здесь не выходят, хотя в режиме редактирования я их вижу. А на счет глюков в программе: ну так она же работает если без оптимизатора или
Buf_RS485 описать как vu8 ( volatile unsigned char ), но тогда в сотнях местах приходится вписывать явное преобразование типов. memcopy((char*)Buf_RS485,.... )

Updete: Да я в таких случиях смотрю код ассемблера. А о веревке: Так и есть другое устройство принимает пакет с ошибочной длинной.


Сообщение отредактировал vlad_new - Jan 16 2012, 20:18
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 16 2012, 20:13
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(vlad_new @ Jan 16 2012, 23:51) *
Реальный код слишком длинный. К тому же похожие проблеммы с оптимизатором не редки.

Если проблемы не редки, то почти наверняка оптимизатор ни при чем. Вам в любом случае надо локализовать проблему, и оформить её в виде изолированного фрагмента - или чтобы аргументированно обвинить оптимизатор, или чтобы разобраться с изъянами своего кода. И уж точно не стоит "лечить" программу, добавляя разнообразные квалификаторы там, где они объективно не нужны.
Go to the top of the page
 
+Quote Post
Allregia
сообщение Jan 16 2012, 20:17
Сообщение #11


Профессионал
*****

Группа: Свой
Сообщений: 1 047
Регистрация: 28-06-07
Из: Israel
Пользователь №: 28 763



Цитата(vlad_new @ Jan 16 2012, 22:12) *
Да отступы почему то здесь не выходят, хотя в режиме редактирования я их вижу.


Потому что Вы не оформили свой код в теги [сode] [/сode]

Если бы оформили - все бы отсупало:
Код
с начала
      с отступом 8 пробелов
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 16 2012, 20:20
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(vlad_new @ Jan 17 2012, 00:12) *
А на счет глюков в программе: ну так она же работает если без оптимизатора или Buf_RS485 описать как vu8 ( volatile unsigned char ), но тогда в сотнях местах приходится вписывать явное преобразование типов. memcopy((char*)Buf_RS485,.... )

В сотнях мест?!! О ужас! Вероятность глюка в программе приблизилась к 99,9%.
Зачем вообще включаете оптимизацию? Если работает - не трогайте. Не открывайте ящик Пандоры. Есть большой класс ошибок, чувствительных к уровню оптимизации. Они Вам нужны?
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jan 16 2012, 20:20
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Цитата(Allregia @ Jan 17 2012, 00:17) *
Потому что Вы не оформили свой код в теги [сode] [/сode]

Если бы оформили - все бы отсупало:
Код
с начала
      с отступом 8 пробелов

Не знал что так надо. Век живи век учись. Ща попробую.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 16 2012, 20:24
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(vlad_new @ Jan 17 2012, 00:12) *
А на счет глюков в программе: ну так она же работает если без оптимизатора или
Buf_RS485 описать как vu8 ( volatile unsigned char ), но тогда в сотнях местах приходится вписывать явное преобразование типов. memcopy((char*)Buf_RS485,.... )

Подобные симптомы свидетельствуют отнюдь не в пользу версии о правильности программы, а совсем даже наоборот.

Цитата(scifi @ Jan 17 2012, 00:20) *
Зачем вообще включаете оптимизацию? Если работает - не трогайте. Не открывайте ящик Пандоры. Есть большой класс ошибок, чувствительных к уровню оптимизации. Они Вам нужны?

Странный совет. Правильнее было бы не выключать оптимизацию, дабы по мере написания программы выгребать содержимое ящика.
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jan 16 2012, 20:30
Сообщение #15


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Цитата(aaarrr @ Jan 17 2012, 00:20) *
Подобные симптомы свидетельствуют отнюдь не в пользу версии о правильности программы, а совсем даже наоборот.

Естественно. Внешний массив и обязан быть volatile, тем более что он используется в прерываниях. Ну так я и спрашивал как бы
сделать так, чтоб в стандартные библиотеки передовать тип volatile без явного преобразования типа повсеместно.
Может через какой нибудь typedef переопределить типы параметров в библиотеке. А может еще какие то другие есть решения.

Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 16 2012, 20:31
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(aaarrr @ Jan 17 2012, 00:24) *
Странный совет. Правильнее было бы не выключать оптимизацию, дабы по мере написания программы выгребать содержимое ящика.

Подозреваю, что автор - очень начинающий программист на Си. Зачем лишние грабли на дороге?
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jan 16 2012, 20:32
Сообщение #17


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Цитата(aaarrr @ Jan 17 2012, 00:24) *
Подобные симптомы свидетельствуют отнюдь не в пользу версии о правильности программы, а совсем даже наоборот.


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


В KEIL-е без оптимизатора на код смотреть противно. Да и скорость почти 2 раза ниже.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 16 2012, 20:35
Сообщение #18


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(vlad_new @ Jan 17 2012, 00:30) *
Внешний массив и обязан быть volatile, тем более что он используется в прерываниях.

Нет, не обязан.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 16 2012, 20:36
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(vlad_new @ Jan 17 2012, 00:30) *
Естественно. Внешний массив и обязан быть volatile, тем более что он используется в прерываниях. Ну так я и спрашивал как бы
сделать так, чтоб в стандартные библиотеки передовать тип volatile без явного преобразования типа повсеместно.
Может через какой нибудь typedef переопределить типы параметров в библиотеке. А может еще какие то другие есть решения.

Можно тупо объявить указатель на этот массив и использовать его в вызовах библиотечных функций:
Код
char* const nv_Buf_RS485 = (char*)Buf_RS485;

Но вообще такие проблемы не возникают, если изначально построить программу вменяемым образом.

Цитата(vlad_new @ Jan 17 2012, 00:32) *
В KEIL-е без оптимизатора на код смотреть противно. Да и скорость почти 2 раза ниже.

Лучше не начинайте. А то я начну рассказывать, какие эмоции вызывает Ваш код :-)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 16 2012, 20:37
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(scifi @ Jan 17 2012, 00:31) *
Зачем лишние грабли на дороге?

Чтобы научиться по этой дороге ходить, разве нет?
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jan 16 2012, 20:51
Сообщение #21


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Цитата(scifi @ Jan 17 2012, 00:36) *
Можно тупо объявить указатель на этот массив и использовать его в вызовах библиотечных функций:
Код
char* const nv_Buf_RS485 = (char*)Buf_RS485;

Но вообще такие проблемы не возникают, если изначально построить программу вменяемым образом.


Лучше не начинайте. А то я начну рассказывать, какие эмоции вызывает Ваш код :-)

Думал я про указатель. Иногда так и делаю. Код нормальный с точки зрения 8 битных процессоров, где указатель является очень
сложной конструкцией и работает через библиотеки жутко медленно. ARM-наоборот. Ему только указатели и подавай.
Да я собственно и не претендовал на программиста. На перелопачивание СРМа и MS-DOSа меня в свое время хватало, а Андроид писать и не собираюсь.
Но в любом случае, как я Вас понял, пороблемма снимается изменением стиля работы с буферами. Типа заводим буфер и сразу на него указатель. А про
индексы на всегда збываем. sm.gif
PS: Подредактировано.


Сообщение отредактировал vlad_new - Jan 16 2012, 21:09
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 16 2012, 21:05
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Да, забыл. Можно просто макрос. Ну и я переврал немного с указателем: не нужно его делать const, иначе он ничем не лучше volatile - требует приведения типа.
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jan 16 2012, 21:08
Сообщение #23


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Цитата(scifi @ Jan 17 2012, 01:05) *
Да, забыл. Можно просто макрос. Ну и я переврал немного с указателем: не нужно его делать const, иначе он ничем не лучше volatile - требует приведения типа.

Вот только хотел спросить про const sm.gif Я подредактировал предыдущее сообщение.
Сенкю.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 16 2012, 21:23
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(vlad_new @ Jan 17 2012, 00:51) *
Но в любом случае, как я Вас понял, пороблемма снимается изменением стиля работы с буферами. Типа заводим буфер и сразу на него указатель. А про
индексы на всегда збываем. sm.gif

Позволите позанудствовать немного?

Если преобразование типов действительно необходимо, то лучше выполнить его в момент вызова, а не заводить левый указатель.
Если таких преобразований требуются сотни, значит программу надо переписать.
С указателем можно тоже работать с использованием индекса.
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jan 16 2012, 21:35
Сообщение #25


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Цитата(aaarrr @ Jan 17 2012, 01:23) *
Позволите позанудствовать немного?

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

Хороший совет тем, кто перелез с 8 битников на ARMы, а таких сейчас очень много.
К стате почему эту строчку оптемизатор отбрасывает - понятно. Поскольку Buf_RS485[0] нигде далее не используется, она, типа, и не нужна! А то что
это нужно прерыванию компелятор в упор не видит. А зря. Вот и приходится либо где нибудь влепить холостую дурь типа k=Buf_RS485[0];
либо терять скорость на куче volatile.
Но вопрос то стоял не почему оптимизатор в Keil-е дурной sm.gif , а как в библиотеке подмену на volatile сделать. Хотя может это и не возможно, поскольку
библиотека уже оптимизирована на регистровые операции и заставить библиотечные ф-ции сбрасывать регистровые переменные в ОЗУ вряд ли возможно.
А может я и ошибаюсь. Собственно я это и хотел выяснить.

Сообщение отредактировал vlad_new - Jan 16 2012, 23:38
Go to the top of the page
 
+Quote Post
scifi
сообщение Jan 17 2012, 06:16
Сообщение #26


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Опять всё по кругу...

Цитата(vlad_new @ Jan 17 2012, 01:35) *
К стате почему эту строчку оптемизатор отбрасывает - понятно. Поскольку Buf_RS485[0] нигде далее не используется, она, типа, и не нужна!

Абсолютно верно.

Цитата(vlad_new @ Jan 17 2012, 01:35) *
А то что это нужно прерыванию компелятор в упор не видит. А зря.

Компилятор вообще много чего не видит и не должен видеть. Вы как будто пытаетесь ему приписать роль этакого телепата-волшебника, угадывающего намерения программиста. А программист на что?

Цитата(vlad_new @ Jan 17 2012, 01:35) *
Вот и приходится либо где нибудь влепить холостую дурь типа k=Buf_RS485[0];
либо терять скорость на куче volatile.

Лепить холостую дурь не надо.
А вот одно из применений volatile - для переменных, используемых как в основном потоке, так и в прерывании. Действительно, каждый доступ к volatile потенциально замедляет программу. Поэтому число таких доступов уменьшают до минимального необходимого уровня. Есть как минимум несколько способов это сделать.

Цитата(vlad_new @ Jan 17 2012, 01:35) *
Но вопрос то стоял не почему оптимизатор в Keil-е дурной sm.gif , а как в библиотеке подмену на volatile сделать. Хотя может это и не возможно, поскольку
библиотека уже оптимизирована на регистровые операции и заставить библиотечные ф-ции сбрасывать регистровые переменные в ОЗУ вряд ли возможно.

Вопрос ставится некорректно. Стандартная библиотека описана в стандарте языка Си. То, что Вы предлагаете, по сути меняет семантику библиотечных функций, то есть это будет уже не стандартная библиотека. Ну и флаг Вам в руки: напишите свою библиотеку и используйте её.

Цитата(vlad_new @ Jan 17 2012, 01:35) *
А может я и ошибаюсь. Собственно я это и хотел выяснить.

Вы ошибаетесь :-)
Налицо все признаки ужасно структурированной программы. Отсюда и лезут все эти косяки. По неопытности бывает, конечно. У меня в начале тоже программы были не фонтан.
Go to the top of the page
 
+Quote Post
_Ivana
сообщение Jan 17 2012, 17:07
Сообщение #27


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710



Продолжу от лица неопытных новичков rolleyes.gif
Можно было бы конечно продублировать все библиотечные функции своими аналогами, внутри которых заводятся локальные переменные нужных типов, им присваиваются значения параметров и с ними вызываются библиотечные функции. Но мне кажется, это несколько коряво, хотя как лучше - не знаю.
Простейший пример из практики - преобразование числа в строку. Мне было проще написать эту функцию самому, чем копаться в библиотеках. Она принимает аргумент типа int. А мне надо вызывать её и с int и с char. Два решения лежат на поверхности:
1 - написать дубль этой же функции, но принимающий char
2 - заводить лишнюю переменную int куда присваивать нужный char, и с ним вызывать функцию
Оба решения мне не нравятся. Но как сделать красивее - не придумал. Использование указателя не только не помогло, но и таит ошибку при исполнении.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 17 2012, 17:14
Сообщение #28


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(_Ivana @ Jan 17 2012, 21:07) *
Два решения лежат на поверхности

А почему бы не передавать ей char без лишних телодвижений?
Go to the top of the page
 
+Quote Post
_Ivana
сообщение Jan 17 2012, 17:22
Сообщение #29


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710



Хороший вопрос! sm.gif
Я сначала написал, а потом начал что-то вспоминать про "неявное преобразование типов" и т.п. Будете смеяться, но не помню, почему я был вынужден так изголяться... Или там передавался наоборот указатель на int...

ЗЫ щас попробую найти код и посмотреть sm.gif
Точно, принимаю указатель sm.gif Чтобы переменная изменялась а не передалась по значению и все.

Код
//-----------------------------------------------------------------------------------------------

char count_of_order(unsigned int *n, unsigned int order)
{
    char res = 0;

    while (*n >= order)
    {
        *n = *n - order;
        res++;
    }

    return res;
}
//-----------------------------------------------------------------------------------------------


char *int_to_string(char *s, unsigned int n)
{    
    char *begin = s;
    char digit;

    if((digit = count_of_order(&n, 10000))    || s!=begin) *s++ = '0' + digit;
    if((digit = count_of_order(&n, 1000))    || s!=begin) *s++ = '0' + digit;
    if((digit = count_of_order(&n, 100))     || s!=begin) *s++ = '0' + digit;
    if((digit = count_of_order(&n, 10))     || s!=begin) *s++ = '0' + digit;

    *s++ = '0' + n;

    return s;
}
//-----------------------------------------------------------------------------------------------


а в другом месте нужен вызов с указателем на char

Код
//-----------------------------------------------------------------------------------------------


char *GPS_end_of_string(char *begin, char *end)
{    
    char *d;
    char chek_summ = 0;
    unsigned int int_chek_summ;

    for(d=begin+1; d<end; d++) chek_summ = chek_summ^*d;
    int_chek_summ = chek_summ;

    *d++ = GPS_char_multiply;
    *d++ = '0' + count_of_order(&int_chek_summ, 16);
    *d++ = '0' + int_chek_summ;
    *d++ = GPS_char_enter;
    *d++ = GPS_char_return;
    *d++ = 0;

    return d;
}
//-----------------------------------------------------------------------------------------------


ЗЫ вышеприведенный код содержит ошибку - это не финальная редакция, я её потом исправил - тут неправильно пишутся буквы 16-ричной строки числа, поскольку A, B и т.д. идут не сразу после "9" в таблице символов sm.gif Но на принципиальном вопросе это не отражается, а его напомню кратко - нам надо передавать не числовое значение переменной в функцию, а указатель на неё, чтобы функция в процессе своего выполнения изменяла этот параметр. А при передаче указателя на char в указатель на int он обрастет ещё соседним байтом и будет ошибка.

Сообщение отредактировал _Ivana - Jan 17 2012, 17:43
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 17 2012, 18:13
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Зачем, нет ЗАЧЕМ делить на 16 последовательным вычитанием? Можно просто написать n >> 4.

С указателями - да, никакой автоматики не предусмотрено.
Go to the top of the page
 
+Quote Post
_Ivana
сообщение Jan 17 2012, 18:25
Сообщение #31


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710



Цитата
Зачем, нет ЗАЧЕМ делить на 16 последовательным вычитанием? Можно просто написать n >> 4.

rolleyes.gif Точно! Спасибо за науку. Буду задавать больше глупых вопросов - подозреваю, что узнаю и не такое. Например, если длина кольцевого буфера равна степени 2, то инкремент его индексов делается тоже как-то проще, без прямой проверки на превышение. Но стоит поиграться размером буфера в дефайнах - и всё поломается rolleyes.gif

Цитата
С указателями - да, никакой автоматики не предусмотрено.

Вот и я пока думаю, что либо передача переменных по значению, зато с преобразованием типов, либо по ссылке - но без преобразования...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jan 17 2012, 18:34
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(_Ivana @ Jan 17 2012, 22:25) *
Например, если длина кольцевого буфера равна степени 2, то инкремент его индексов делается тоже как-то проще, без прямой проверки на превышение. Но стоит поиграться размером буфера в дефайнах - и всё поломается rolleyes.gif

Можно записать в дефайне размер как (1 << N). Но лучше, конечно, делать нормальную проверку - не тот случай, когда стоит экономить две копейки.
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Jan 19 2012, 01:04
Сообщение #33


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



Я тут попробывал интерсный тип указателя к библиотекам подставлять. (void*) - свободный тип называется. Тогда все автоматом преобразуется как
надо. И все нормально работает. Посмотрел код на ассемблере - все впорядке. Ничего лишнего не добавляется. А что нельзя было сразу в библиотеках такой интересный тип использовать? Бит он и в африке бит, как его не переобзави.

Сообщение отредактировал vlad_new - Jan 19 2012, 01:11
Go to the top of the page
 
+Quote Post
XVR
сообщение Jan 19 2012, 09:26
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(vlad_new @ Jan 19 2012, 05:04) *
Я тут попробывал интерсный тип указателя к библиотекам подставлять. (void*) - свободный тип называется. Тогда все автоматом преобразуется как надо.
А как надо? volatile он не отменит - все равно преобразовывать придется
Цитата
А что нельзя было сразу в библиотеках такой интересный тип использовать?
Где надо там используется. В memcpy например
Цитата
Бит он и в африке бит, как его не переобзави.
void - это не бит! void* вообще разименовать нельзя, не преобразовав сначала во что то осмысленное
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 18:05
Рейтинг@Mail.ru


Страница сгенерированна за 0.01722 секунд с 7
ELECTRONIX ©2004-2016