Вопросы по С/С++ (СИ)

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Goldsmith »

Именно указатель, там звездочка перед идентификатором неспроста стоит. Это ведь C, а не насквозь объектный C# с его делегатами. Переменной-указателю на функцию можно присвоить адрес, на который потом будет косвенный переход, а что присвоить переменной-функции? (Впрочем, обычно компиляторы неявно преобразовывают к указателю на функцию без диагностики ошибки).

Аналогичный пример из букваря с хорошей репутацией Ted Jensen, "Tutorial on Pointers and Arrays in C" (веб-версия):
Pointers to functions must match the functions pointed to in the number and types of the parameters and the type of the return value. In our case, we declare our function pointer as:
int (*fptr)(const void *p1, const void *p2);
(выделение мое).
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

причем указатель на указатель пустоты
Не указатель на указатель, а указатель на тип void. void - это не просто пустота, а тип данных. Если при возвращении считается, что void ничего не возвращает, то при аргументах - это неопределённый тип, имеющий свой размер.

Именно указатель, там звездочка перед идентификатором неспроста стоит.
Да, действительно. Походу объявляется тип, как указатель на функцию, не возвращающую ничего и имеющую 2 аргумента.

PS: Нельзя задавать такие вопросы в такой день :)))
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Goldsmith »

Твори бобро писал(а):Вот и хочется понять что-же это void*. С моими познаниями в Си - void это отсутствие аргументов, короче пустота. А тут указатель на нее, причем указатель на указатель пустоты.
void* - это указатель на некоторую область памяти, содержимое которой в момент компиляции неизвестно. Для работы с этими данными указатель void* следует привести к определенному типу, как, например, это сделано в

Код: Выделить всё

io_interface=(_ext_Interface)datum;
Большие подозрения вызывает фрагмент:

Код: Выделить всё

void main(void)
{
char *psomedata(nullptr);
//psomedata = new char[1024*1024*3];
 _device_Interface(FDP_INIT,psomedata);
Здесь ожидается, что psomedata - указатель на функцию от двух аргументов, возвращающую нетипизированный указатель. А вместо него передается указатель на массив литер. Процессор пытается выполнить косвенный переход по указателю и интерпретирует эти данные как команду, отсюда и крах программы. Не знаю, как это раньше работало, но ошибка вполне закономерна.
Последний раз редактировалось Goldsmith Сб фев 23, 2013 22:17:49, всего редактировалось 1 раз.
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Goldsmith »

Аlex писал(а):Да, действительно. Походу объявляется тип, как указатель на функцию, не возвращающую ничего и имеющую 2 аргумента.
Функция, не возвращающая ничего, описывается как

Код: Выделить всё

void func(typ1 arg1, ...);
В данном случае void* - это указатель на "нечто"; а что из себя представляет это "нечто", будет объяснено позже через явное приведение типа указателя (без этого указатель void* можно только присваивать, разыменовывать его бессмысленно).
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Аватара пользователя
Твори бобро
Родился
Сообщения: 18
Зарегистрирован: Чт дек 27, 2012 05:24:10

Re: Вопросы по С/С++ (СИ)

Сообщение Твори бобро »

Goldsmith писал(а):
Твори бобро писал(а):Вот и хочется понять что-же это void*. С моими познаниями в Си - void это отсутствие аргументов, короче пустота. А тут указатель на нее, причем указатель на указатель пустоты.
void* - это указатель на некоторую область памяти, содержимое которой в момент компиляции неизвестно. Для работы с этими данными указатель void* следует привести к определенному типу, как, например, это сделано в

Код: Выделить всё

io_interface=(_ext_Interface)datum;
Большие подозрения вызывает фрагмент:

Код: Выделить всё

void main(void)
{
char *psomedata(nullptr);
//psomedata = new char[1024*1024*3];
 _device_Interface(FDP_INIT,psomedata);
Здесь ожидается, что psomedata - указатель на функцию от двух аргументов, возвращающую нетипизированный указатель. А вместо него передается указатель на массив литер. Процессор пытается выполнить косвенный переход по указателю и интерпретирует эти данные как команду, отсюда и крах программы. Не знаю, как это раньше работало, но ошибка вполне закономерна.


Конечно, это-же мое словоблудие. Посмотрел на ф-цию, посмотрел на switch - ага видимо FDP_INIT это инициализация всей фигни(так оно наверное и есть). Смотрю дальше, ф-ция _device_Interface требует аргумент типа int для switch-а, и еще как-то указатель. Ну я ей и подсунул че придумал :))) Оно-же требует, но само незнает что :)))

Испортил меня паскаль и ассемблер. Пошел дальше читать учебник. Всем спасибо за попытку вбить в пустую голову.
dimka86
Первый раз сказал Мяу!
Сообщения: 32
Зарегистрирован: Вт фев 21, 2012 15:05:12

Re: Вопросы по С/С++ (СИ)

Сообщение dimka86 »

Подскажите пожалуйста что делаю не правильно пишу в codevisionavr принимаю данные по Usart в формате : kxxxdxxxxxe
х-символы от 0 до 9 потом после вывода на дисплей вывожу обратно в Usart прога работает не так как мне хочется
в один массив записываю символы между k и d в другой между d и e

Код: Выделить всё

while (1)
      {                  i=0;
                         j=0;
                       
                         tmp=getchar(); 
                         if (tmp=='k')
                                {
                                    while((tmp=getchar())!='d')
                                    {//начало while
                                   
                                    com_str[i]=tmp; //считываем символ комманды
                                    i++;
                                    }//конец 
                                   
                                 }
                         
                         if (tmp=='d')
                                {
                                    while((tmp=getchar())!='e')
                                    {//начало while
                                    dan_str[j]=tmp; //считываем символ даных
                                    j++;
                                    }//конец 
                                     
                                }

        lcd_clear();
        lcd_gotoxy(0,0);
        lcd_putsf("Kom");
        sprintf(buf, "=%s", com_str);
        lcd_gotoxy(4,0);
        lcd_puts(buf);
        puts(com_str);
        putchar(0x0d);
        lcd_gotoxy(0,1);
        lcd_putsf("Dan");
        sprintf(bufe, "=%s", dan_str);
        lcd_gotoxy(4,1);
        lcd_puts(bufe);
        puts(dan_str);
        putchar(0x0d);   
       
        com=atoi(com_str);
        dan=atoi(dan_str);
       
         ltoa(com,new_com_str);
         putchar('k');
         puts(new_com_str);
         putchar(0x0d);
         
         ltoa(dan,new_dan_str);
         putchar('d');
         puts(new_dan_str);
         putchar(0x0d);
                             
      };
                           
Вложения
проб.rar
(116.88 КБ) 159 скачиваний
igorka
Грызет канифоль
Сообщения: 260
Зарегистрирован: Вс ноя 13, 2011 11:21:23
Откуда: Горловка.

Re: Вопросы по С/С++ (СИ)

Сообщение igorka »

Здравствуйте.Выручайте пожалуйста.Такая проблема написал программу для контроллера ATtiny 2313 в программе "flowcode".Вкратце счетчик с динамической двухразрядной индикацией на семисегментник с общим катодом , все это дело работает но есть одно но , катодами индикаторов управляю p-n-p транзисторами т.е на их базы подаются "-" , необходимо же управлять катодами n-p-n транзисторами т.е инвертировать сигнал порта на "+".Что делать?Помогите.
Вот программа
Do_12poly- final.c
(12.75 КБ) 262 скачивания

Вот макрос семисегментника с программы "flowcode"
AVR_7seg.c
(5.38 КБ) 296 скачиваний
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

Что делать?
Взять нормальный инструмент и не париться...
Аватара пользователя
Твори бобро
Родился
Сообщения: 18
Зарегистрирован: Чт дек 27, 2012 05:24:10

Re: Вопросы по С/С++ (СИ)

Сообщение Твори бобро »

помогите разжевать данное выражение:

Код: Выделить всё

b=a=a-(c<<2);


как так b=a=a? остальное мне понятно.

могу предположить b = (a = (a - (c shl 2))) т.е. b просто присваивает a.
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

Re: Вопросы по С/С++ (СИ)

Сообщение HHIMERA »

Код: Выделить всё

b=a=a-(c<<2);

равносильно

Код: Выделить всё

a=a-(c<<2);
b=a;
"Я не даю готовых решений, я заставляю думать!"(С)
Аватара пользователя
Goldsmith
Опытный кот
Сообщения: 736
Зарегистрирован: Пн янв 10, 2011 03:06:36
Откуда: Ростов-на-Дону
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Goldsmith »

В языке C оператор присваивания - это выражение, значением которого является значение выражения справа от знака присваивания. Проще говоря,
- это выражение, значением которого является b. Поскольку присваивание правоассоциативно (вычисляется справа налево), из присваиваний можно строить длинные цепочки вроде

Код: Выделить всё

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

Код: Выделить всё

if ((с = getchar()) != 0) { ...
(присвоить очередную введенную литеру переменной c и выполнить некоторое действие, если эта литера ненулевая).
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
BGert
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Вс ноя 25, 2012 13:57:12

Re: Вопросы по С/С++ (СИ)

Сообщение BGert »

Начал изучать программирование AVR на языке Си в AVRGCC С.
Читаю книжку по Си и по МК AVR, но очень захотелось забежать на перед, и я начал играться светодиодами. И писал простенькие программы, мигание светодиодами, включения по нажатию кнопки, мигания по нажатию кнопки, и т. д.
Решил их все объединить в один микроконтроллер:
Написал программу :
LED.c
(2.12 КБ) 274 скачивания

И беда по отдельности все циклы выполняются, а вмести нет. Когда я раскоментирую все или 2 цикла то выполняется только первый.
Изменил программу и цикли внес в функции.
LED2.c
(2.31 КБ) 286 скачиваний

Но ситуация не поменялась (((
Подскажите что я сделал не так ? и как можно написать чтобы все выполнялось ?
Заранее большое Спасибо !
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

по отдельности все циклы выполняются, а вмести нет
Интересно, а как они могут выполнятся вместе, если они бесконечные и из них нет выхода ?
Аватара пользователя
vitalik_1984
Поставщик валерьянки для Кота
Сообщения: 2482
Зарегистрирован: Пт авг 27, 2010 05:57:06
Откуда: Тюмень
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение vitalik_1984 »

BGert писал(а):Подскажите что я сделал не так ? и как можно написать чтобы все выполнялось ?
Заранее большое Спасибо !

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

А теперь совет RTFM!!!!
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

Re: Вопросы по С/С++ (СИ)

Сообщение unalex »

Код: Выделить всё

while(1)
{
   PORTC ^= 0xFF; //я буду выполняться и постоянно дрыгать своими ногами
}

PORTВ ^= 0xFF;   //а я никогда не выполнюсь(очень грустный смайлик)
//все потому что while(1) очень злая штучка и она не выпускает из себя если ее не попросить
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
BGert
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Вс ноя 25, 2012 13:57:12

Re: Вопросы по С/С++ (СИ)

Сообщение BGert »

unalex Спасибо за объяснение.
Теперь я понял что while(1) не дает следующему циклу начаться.
Значить нужно так написать чтобы каждый цикл заканчивался, и после него смог начаться следующей. Правильно я понял ?
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

Re: Вопросы по С/С++ (СИ)

Сообщение unalex »

BGert писал(а):Значить нужно так написать чтобы каждый цикл заканчивался, и после него смог начаться следующей. Правильно я понял ?


бесконечный цикл - это штучка, которая говорит контроллеру - работай постоянно, а не один раз

этот бесконечный цикл должен быть одним единственным в программе, а уже внутри него делаешь все что тебе надо(только не пиши внутри еще бесконечные циклы)

Код: Выделить всё

int main()
{
тут мы пишем то, что выполняется только один раз при старте контроллера
while(1)
{
//а это будет выполняться бесконечно
//и тут уже лепим всякие эксперименты, но уже без while(1) иначе при попадании в первый такой вайл, ничего другого делаться не будет
}
}

Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Аватара пользователя
Jack_A
Друг Кота
Сообщения: 6307
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Re: Вопросы по С/С++ (СИ)

Сообщение Jack_A »

Конечно, это дело вкуса, но меня до сих пор коробит это while (1), и я бы, если бы продолжил пис`ать на Си, употребил бы презрительно пинаемое всеми goto. И как видно из предыдущих постов, это магическое заклинание не так уж прозрачно для понимания новичками. Но это личное мнение моё и моего кота Мурзика :)
Аватара пользователя
Valek3306
Встал на лапы
Сообщения: 95
Зарегистрирован: Вт авг 03, 2010 22:51:57
Откуда: Санкт-Петербург
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Valek3306 »

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

Код: Выделить всё

while (1)
      {
      // Place your code here
      int r = 254;          // Step 2   255   000   000                   
      int g = 0;
      int b = 0;
      int t = 2;
       
      if((r = 255) & (g < 255) & (b = 0))           // Step 2   255   255   000
      {
      OCR0=g;
      g++;
      delay_ms(t);
      };
       
      if((r > 0) & (g = 255) & (b = 0))          //Step 3   000   255   000
      {
      OCR1AH=0;
      OCR1AL=r;
      r--;
      delay_ms(t);     
      };
       
      if((r = 0) & (g = 255) & (b < 255))          //Step 4   000   255   255
      {
      OCR2=b;
      b++;
      delay_ms(t);     
      };
       
      if((r = 0) & (g > 0) & (b = 255))          //Step 5   000   000   255
      {
      OCR0=g;
      g--;
      delay_ms(t);
      };
             
      if((r < 255) & (g = 0) & (b = 255))          //Step 6   255   000   255
      {
      OCR1AH=0;
      OCR1AL=r;
      r++;
      delay_ms(t);     
      };
       
      if((r = 255) & (g = 0) & (b > 0))          //Step 7   255   000   000
      {
      OCR2=b;
      b--;
      delay_ms(t);     
      };
                     
      }
Маленький хакер в подстанцию влез
Перенаправил поток он с АЭС
Клевая мощность два мегаватта,
Быстро горит материнская плата!
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

Re: Вопросы по С/С++ (СИ)

Сообщение Аlex »

по чему такой алгоритм не работает...
А мы все должны догадываться что это изначально должно было быть ? :)
Ответить

Вернуться в «Разные вопросы по МК»