Именно указатель, там звездочка перед идентификатором неспроста стоит. Это ведь C, а не насквозь объектный 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
Не указатель на указатель, а указатель на тип void. void - это не просто пустота, а тип данных. Если при возвращении считается, что void ничего не возвращает, то при аргументах - это неопределённый тип, имеющий свой размер.
Именно указатель, там звездочка перед идентификатором неспроста стоит.
Да, действительно. Походу объявляется тип, как указатель на функцию, не возвращающую ничего и имеющую 2 аргумента.
Твори бобро писал(а):Вот и хочется понять что-же это void*. С моими познаниями в Си - void это отсутствие аргументов, короче пустота. А тут указатель на нее, причем указатель на указатель пустоты.
void* - это указатель на некоторую область памяти, содержимое которой в момент компиляции неизвестно. Для работы с этими данными указатель void* следует привести к определенному типу, как, например, это сделано в
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
В данном случае void* - это указатель на "нечто"; а что из себя представляет это "нечто", будет объяснено позже через явное приведение типа указателя (без этого указатель void* можно только присваивать, разыменовывать его бессмысленно).
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Твори бобро писал(а):Вот и хочется понять что-же это void*. С моими познаниями в Си - void это отсутствие аргументов, короче пустота. А тут указатель на нее, причем указатель на указатель пустоты.
void* - это указатель на некоторую область памяти, содержимое которой в момент компиляции неизвестно. Для работы с этими данными указатель void* следует привести к определенному типу, как, например, это сделано в
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-а, и еще как-то указатель. Ну я ей и подсунул че придумал Оно-же требует, но само незнает что
Испортил меня паскаль и ассемблер. Пошел дальше читать учебник. Всем спасибо за попытку вбить в пустую голову.
Подскажите пожалуйста что делаю не правильно пишу в codevisionavr принимаю данные по Usart в формате : kxxxdxxxxxe
х-символы от 0 до 9 потом после вывода на дисплей вывожу обратно в Usart прога работает не так как мне хочется
в один массив записываю символы между k и d в другой между d и e
Здравствуйте.Выручайте пожалуйста.Такая проблема написал программу для контроллера ATtiny 2313 в программе "flowcode".Вкратце счетчик с динамической двухразрядной индикацией на семисегментник с общим катодом , все это дело работает но есть одно но , катодами индикаторов управляю p-n-p транзисторами т.е на их базы подаются "-" , необходимо же управлять катодами n-p-n транзисторами т.е инвертировать сигнал порта на "+".Что делать?Помогите.
Вот программа
- это выражение, значением которого является b. Поскольку присваивание правоассоциативно (вычисляется справа налево), из присваиваний можно строить длинные цепочки вроде
(присвоить очередную введенную литеру переменной c и выполнить некоторое действие, если эта литера ненулевая).
Любой дурак может писать код. Настоящий профессионал - это тот, кто способен постоянно создавать продукт высокого качества, укладываясь при этом в бюджет.
J. Ganssle
Начал изучать программирование AVR на языке Си в AVRGCC С.
Читаю книжку по Си и по МК AVR, но очень захотелось забежать на перед, и я начал играться светодиодами. И писал простенькие программы, мигание светодиодами, включения по нажатию кнопки, мигания по нажатию кнопки, и т. д.
Решил их все объединить в один микроконтроллер:
Написал программу :
И беда по отдельности все циклы выполняются, а вмести нет. Когда я раскоментирую все или 2 цикла то выполняется только первый.
Изменил программу и цикли внес в функции.
BGert писал(а):Подскажите что я сделал не так ? и как можно написать чтобы все выполнялось ?
Заранее большое Спасибо !
Не так вы сделали, когда не прочитали то, что вам написали что нужно сделать, чтобы все заработало.
Помнится вы даже не в той теме уже задавали этот вопрос
и я вам ответил
while(1)
{
PORTC ^= 0xFF; //я буду выполняться и постоянно дрыгать своими ногами
}
PORTВ ^= 0xFF; //а я никогда не выполнюсь(очень грустный смайлик)
//все потому что while(1) очень злая штучка и она не выпускает из себя если ее не попросить
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
unalex Спасибо за объяснение.
Теперь я понял что while(1) не дает следующему циклу начаться.
Значить нужно так написать чтобы каждый цикл заканчивался, и после него смог начаться следующей. Правильно я понял ?
BGert писал(а):Значить нужно так написать чтобы каждый цикл заканчивался, и после него смог начаться следующей. Правильно я понял ?
бесконечный цикл - это штучка, которая говорит контроллеру - работай постоянно, а не один раз
этот бесконечный цикл должен быть одним единственным в программе, а уже внутри него делаешь все что тебе надо(только не пиши внутри еще бесконечные циклы)
int main()
{
тут мы пишем то, что выполняется только один раз при старте контроллера
while(1)
{
//а это будет выполняться бесконечно
//и тут уже лепим всякие эксперименты, но уже без while(1) иначе при попадании в первый такой вайл, ничего другого делаться не будет
}
}
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Конечно, это дело вкуса, но меня до сих пор коробит это while (1), и я бы, если бы продолжил пис`ать на Си, употребил бы презрительно пинаемое всеми goto. И как видно из предыдущих постов, это магическое заклинание не так уж прозрачно для понимания новичками. Но это личное мнение моё и моего кота Мурзика
Не подскажите по чему такой алгоритм не работает... что я делаю не так? Извиняюсь за, наверняка, глупый вопрос но я не силен в программировании
Спойлер