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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
ut1wpr
Вымогатель припоя
Сообщения: 581
Зарегистрирован: Ср янв 05, 2011 10:03:18

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

Сообщение ut1wpr »

HHIMERA писал(а):И пофигу, что тебе надо... И микрочиповский пример (ведь это всего лишь пример, никто никого не обязывает его к применению) тоже пофигу... :))
И Микрочип с Атмэлом - пофигу...
Российская команда пофигистов победила на очных соревнованиях. Она просто не приехала, так как ей эти соревнования были пофигу! :)
С уважением,
Виктор.
Реклама
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

HHIMERA писал(а):Были ответы
http://radiokot.ru/forum/viewtopic.php? ... 0#p1435790
Повторите, пожалуйста, ещё раз, что код по этой Вашей ссылке -- правильный, профессиональный и без ошибок.
Ведь всем известно, что всё, повторенное трижды — правда.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Реклама
спящий
Потрогал лапой паяльник
Сообщения: 303
Зарегистрирован: Сб янв 08, 2011 13:48:41

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

Сообщение спящий »

подскажите как ввести определенное значение символов с строки допустим 8?
printf() , и есть какаянить маска ,для неизвестных символов?допустим я хочу найти слово ,зная начало и конец lol??????.wave


const char *p = array; //
const char *pstr = "lol??????.wave";
int step = strlen(pstr);

while ( (p = strstr(p,pstr)) != 0 ) {
nachalo = p - array;
i++
p += step; // }
Аватара пользователя
Кислый
Поставщик валерьянки для Кота
Сообщения: 2095
Зарегистрирован: Чт апр 08, 2010 18:50:01
Откуда: Краснодар
Контактная информация:

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

Сообщение Кислый »

черт. есть ли какая-нибудь возможность проверить скомпиленный бинарник на множественные включения заголовков ?
RETI ;рети-рети интеррапт, через шины данных тракт, через память, через порт, возвращайся в главный код
@hobbyelectronics
Реклама
Эиком - электронные компоненты и радиодетали
illarionovsp
Прорезались зубы
Сообщения: 234
Зарегистрирован: Ср апр 29, 2009 22:22:13
Откуда: СПб

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

Сообщение illarionovsp »

avreal, Вы пишете:
Б) Иметь внутри себя статический буфер, который и возвращать.

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

char *ftos(float val)
{
    static char buf[20];
    // преобразовываем
    return buf;
} 
Спасибо за объяснение. Как я сразу не догадался, что нельзя передать то, чего не существует. Так у меня под никнеймом и написано: Не кот я. Кошонок пока.
Только я так и сделал, а он (компил) опять за своё:
cannot assign array type objects
и ещё две строки ерроров. Чего опять ему надо? :cry:
Реклама
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Странно. Написано именно так?
Если именно так, то, возможно, это какая-то заморочка конкретного С-компилятора с его отклонениями от стандарта с целью каких-то упрощений.
Так как имя массива практически во всех местах автоматически приводится к указателю на первый элемент, для some_type array[len]; запись array везде, кроме sizeof(array) и &array, экивалентна &array[0]. В return array нет присваивания массивов.
Приведите больший участок кода и текст сообщений об ошибках.

И попробуйте так:

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

return & buf[0]; 
и/или вынесите static char buf[20] за пределы функции.
А вообще удобно код проверять на PC:

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

#include <stdio.h>
#include <string.h>

char *return_static_buffer()
{
    static char buf[20];
    strcpy(buf, "344.9876");
    return buf;
}

int main()
{
    printf("%s\n", return_static_buffer());
} 
Во всех использовавшихся мной компиляторах, начиная от порта SVr2-шного С под RT-11, этот код компилировался бы и работал бы.

p.s. Кстати, там в strcpy дважды производится такое автоматическое преобразование объекта типа "массив" в указатель на первый элемент.
И для первого параметра (buf), и для второго "344.9876", который имеет тип «array of char».
Для строкового литерала автоматическое приведение к указателю на первый элемент не производится кроме указанных выше двух случаев ещё и при инициализации массива

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

char random_float_value[] = "344.9876"; // This is a random number obtained by interviewing a random person   
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Реклама
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

спящий писал(а):подскажите как ввести определенное значение символов с строки допустим 8?х
В цикле, используя индекс.
Иметь внутри себя статический буфер, который и возвращать.
С низкоуровневой точки зрения, подобный финт должен прокатить, но возвращать из функции объект, область которого - предел этой функции, не поддаётся ни какой логике. Возможно, по этому компилятор и "матерится".
Правильнее будет посылать в функцию указатель на изменяемую этой функцией строку/массив.
Аватара пользователя
urry
Сверлит текстолит когтями
Сообщения: 1262
Зарегистрирован: Пн дек 08, 2008 10:58:48
Откуда: Винница
Контактная информация:

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

Сообщение urry »

Алекс, ошибки как раз нет - статик - эта глобальная переменная с ограниченной областью видимости - да, снаружи функции буфер виден не будет, но возвращается указатель на него. Т.е для выдачи - перебирай, инкрементируя, пока 0 не встретится.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Аlex писал(а):
Иметь внутри себя статический буфер, который и возвращать.
С низкоуровневой точки зрения, подобный финт должен прокатить, но возвращать из функции объект, область которого - предел этой функции, не поддаётся ни какой логике.
Что значит «область действия»?
Если «время жизни» -- время, в течении которого объект «действует», то тут оно равно времени работы программы, на то там и static. Без него действительно «не поддаётся никакой логике», так как в момент возврата объект будет разрушен и наружу будет отдан указатель на несуществующий объект (автор вопроса уже понял это). Тогда компилятор справедливо должен выругаться.

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

ftos.c: In function ‘ftos’:
ftos.c:9: warning: function returns address of local variable
Если имеется ввиду «область определения» («область видимости»), то при чём тут это? Важно время жизни объекта.
Если написать так:

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

// какой-то файл
// тут в нём куча всего
// раньше никаких forward declaration для buf[]
static char buf[20];
char *ftos(float val)
{
    strcpy(buf, "344.9876");
    return buf;
}
// Всё, файл закончился   
то де-юре область определения переменной buf - файл, а де факто факто её видит только функция ftos. Время жизни при этом тоже одинаковое -- static storage duration.
А вот так

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

void foo()
{
    char buf[30];
    sprintf(buf, "%f", 344.9876);
    lcd_putstr(buf);    
} 
Мы дважды отдаём наружу адрес объекта, обе характеристики которого -- область определения и время жизни -- «предел этой функции». Но всё нормально, так как sprintf и lcd_putstr работают в течении времени жизни.
В случае возврата адреса внутреннего буфера со статическим временем жизни все остальные будут с ним работать тоже в течении его времени жизни. Всё в рамках логики языка С.
Аlex писал(а):Возможно, по этому компилятор и "матерится".
«Всю Дерибасовскую устраивает, а его, видите ли, не устраивает».
Borland C, MSVC, gcc (так в течении времени жизни одной WinNT/XP/W7 DLL-ки менялись компиляторы) прекрасно компилируют этот код и молчат при всех включенных предупреждениях:
Спойлер

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

const char *format(const char *fmt, ...)
{
    enum { maxlen = 1024 };
    static char buf[maxlen + 1];
    std::va_list vl;

    va_start(vl, fmt);
    std::vsnprintf(buf, maxlen, fmt, vl);
    va_end(vl);
    return buf;
}


// get description of WINAPI GetLastError() error code to internal static buffer
// remove all trailing '\n', '\r'
// return pointer to the buffer
const char *last_win_error_str(void)
{
    enum { maxlen = 1024 };
    static char buf[maxlen + 1];

    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
              MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),    // Default language
              buf, maxlen, NULL);

    char *p = buf + strlen(buf) - 1;
    while (p >= buf && (*p == '\r' || *p == '\n')) *p-- = 0;

    return buf;
} 
Ну ладно, это вcё компиляторы, которые все могут ошибаться.

Возьмём стандарт С, описание функций стандартной библиотеки:
SO/IEC 9899:1999 писал(а):7.19.4.4 The tmpnam function
...
if the argument is a null pointer, the tmpnam function leaves its result in an internal static object and returns a pointer to that object (subsequent calls to the tmpnam function may modify the same object).
Или вот описание и пример реализации функции asctime
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

Алекс, ошибки как раз нет
А я и не говорил что ошибка :)
С низкоуровневой точки зрения, подобный финт должен прокатить
Я, как раз, и имел в виду, что вернётся указатель, на неизменяемую область.
Просто как то не логично получается, не айс вощем 8)
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

urry писал(а):Алекс, ошибки как раз нет
Во-во, толко я слишком долго это писал :)))
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
illarionovsp
Прорезались зубы
Сообщения: 234
Зарегистрирован: Ср апр 29, 2009 22:22:13
Откуда: СПб

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

Сообщение illarionovsp »

Alex, передавал из вызывающей массив. Всё равно ругается. Не хочет через имя функции перелават строку. Через входной массив, охотно передаёт. Ну прямо как ftoа(char *s, float val), во паразит!
Ещё одна морока. Мой VC++ 2010 не хочет работать, требует обновление KB983509. А оно ставиться не хочет. Конфликт какой-то находит. Переустановил VC++ 2010. Результат тот-же. Отключил инет. Результат тот-же. Хотел установить VС++ 2012, так там не вижу версии под ХР. Всё под семёрки, да осьмёрки. "Куды хрестьянину подасти...".
Последний раз редактировалось illarionovsp Ср окт 17, 2012 14:02:20, всего редактировалось 1 раз.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Аlex писал(а):Я, как раз, и имел в виду, что вернётся указатель, на неизменяемую область.
Просто как то не логично получается, не айс вощем 8)
Если компилятору С что-то там такое кажется, что «не айс», то он должен выдать предупреждение, а не ошибку.

Но в данном случае всё абсолютно корректно и «освящено» стандартом (в который иногда стоит заглядывать).
Вот, кстати, про те же всяике asctime из стандарта
7.23.3 Time conversion functions

Except for the strftime function, these functions each return a pointer to one of two types of static objects: a broken-down time structure or an array of char.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

avreal, да кто же спорит ?Я же не говорил, что так делать нельзя. Зачем Вы пытаетесь доказать свою правоту ? :)
Просто выразил своё мнение, что для меня подобное - изврат. :))
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

illarionovsp писал(а):Alex, передавал из вызывающей массив. Всё равно ругается. Не хочет через имя функции перелават строку. Через входной массив, охотно передаёт.
Несколько непонятно.
Покажите конкретный код, достаточно большой, чтобы были видны взаимосвязи, и достаточно маленький, чтобы spoiler не порвать :-)
И конкретные сообщения об ошибках с номерами строк, на которые ругается (обозначить в коде комментариями).
illarionovsp писал(а):Ещё одна морока. Мой VC++ 2010 не хочет работать,
..."Куды хрестьянину подасти...".
У ребёнка в школе кроме MSVS ещё DevC++/mingw32-gcc стоят.
Я для Win-any DLL-ки под С++-any/дельфийские программы в Code::Blocks пишу. В Win компилятор mingw-gcc (32 и 64 бита). Работает и в Win2000, как раз недавно на старючей машинке проверял.
И в Code::Blocks же для AVR, включая ассемблер, для Cortex-M3. И в нём же avreal Win/Lin (/BSD только иногда мелочь в vim подправляется и из командной строки gmake-ом пересобирается).
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
avreal
Опытный кот
Сообщения: 842
Зарегистрирован: Чт дек 31, 2009 19:27:45
Откуда: Бровари, Україна
Контактная информация:

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

Сообщение avreal »

Аlex писал(а):Зачем Вы пытаетесь доказать свою правоту ? :)
Просто выразил своё мнение, что для меня подобное - изврат. :))
Не свою, а такого варианта кода.
Затем, что кто-то прочтет это мнение, в котором не было «для меня», а было «вообще»:
Аlex писал(а):С низкоуровневой точки зрения
Так с низкоуровневой или с Вашей ;) ?
Аlex писал(а):подобный финт должен прокатить, но возвращать из функции объект, область которого - предел этой функции, не поддаётся ни какой логике. Возможно, по этому компилятор и "матерится".
Правильнее будет посылать в функцию указатель на изменяемую этой функцией строку/массив.
и поверит, что это финт, что он не работает, а прокатывает, и что это не поддаётся ни какой логике (а не Вашей лично).

Если Вы не видите разницы между таким заявлением и словами «мне такое кажется извратом, и, хотя тут и всё в рамках стандарта и обязано работать на любом комипляторе, мне такое не нравится и я не буду использовать», то я вижу эту разницу. И поэтому показал, что это вполне стандартная вещь, в рамках логики языка С и даже для стандартной библиотеки С его используют наравне с тем, что по Вашему правильнее.
Лень в виде мании величия: «ты гений, зачем стараться?». В виде комплекса: «всё равно не выйдет, зачем упираться?». Как логика: «если достаточно, зачем знать и уметь больше?». Цель одна: остановить. Не любит тепло работающих мышц и шум работающего мозга.
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

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

А чем Вам не угодило слово "Финт" ? Что Вы в нём увидели плохого ?
Предположим, какой-нибудь новичок воспользуется Вашим примером и создаст какую-нибудь функцию, возвращающую чего-нибудь. Возьмём, для примера, возвращение даты ну или время, в строке.

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

char* Get_Time(void){
static ret_str[7];
..........
тут заполняем массив.
..........
return ret_str;
}
А потом, не понимая всех прелестей Вашего финта, будет её использовать:

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

char* pTime_1, pTime_2;

pTime_1 = Get_Time();
...................
...................
...................
pTime_2 = Get_Time();
и начнёт, к примеру, их сравнивать, думая, что в этих строках разное содержимое. А для новичков непонятны всякие там термины типа указателей, для них проще - строка. Частенько встречаешься с подобными заблуждениями.
Представляете, какими нехорошими словами он будет вспоминать Ваш ник на форуме, когда узнает, что строки одинаковые. :)) Т.к. указатель на них один и тот-же. И до этого он допетрит только тогда, когда сам будет в состоянии понимать, использовать и создавать подобные коды.
Эта ситуация, всего-лишь, для примера, на которую новичок легко может напороться.
Наверное, всё-таки, будет правильнее и нагляднее видеть подобный код(?):
void Get_Time(char* pStr){
..........
тут заполняем pStr
..........
}

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

char Time_1[7], Time_2[7];

Get_Time(Time_1);
..........
..........
Get_Time(Time_2);
Только по этому я и выразился словом "низкоуровневой". Что означает понимание того, что реально происходит. Это далеко не означает - "Моей".

Это был, всего-лишь, пример, не означающий Вашу неправоту. По этому, не стоит на него реагировать неадекватно, "вставая на дыбы". :)

PS: И ещё, в догонку, новичкам пофиг на Ваши стандарты и указатели. Они понимают так, как им проще. И для них проще слышать и понимать слово "строка", а не указатель. А Си, к сожалению, не умеет возвращать строки, он не какой-нибудь там бейсик для ПК который тупо возвращает весь массив. По этому, я и считаю, что это - изврат. И моему участку мозга, отвечающему за логику, так-же как и многим, пофигу на эти Ваши стандарты, которыми Вы прикрываетесь и через каждое слово вставляете. :)
Tolmi
Говорящий с текстолитом
Сообщения: 1658
Зарегистрирован: Вс дек 11, 2011 05:25:04
Откуда: Киев, Украина
Контактная информация:

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

Сообщение Tolmi »

Аlex писал(а): PS: И ещё, в догонку, новичкам пофиг на Ваши стандарты и указатели. Они понимают так, как им проще. И для них проще слышать и понимать слово "строка", а не указатель. А Си, к сожалению, не умеет возвращать строки, он не какой-нибудь там бейсик для ПК который тупо возвращает весь массив. По этому, я и считаю, что это - изврат. И моему участку мозга, отвечающему за логику, так-же как и многим, пофигу на эти Ваши стандарты, которыми Вы прикрываетесь и через каждое слово вставляете. :)
И тем не менее есть формальное описание языка, если этот язык - C, то и компилятор с него, и человек, на нём пишуший, должен уметь понимать такие конструкции. А работа с С в низкоуровневых средах навроде embedded программирования на МК ничем кардинально не отличается от ассемблеров, к примеру. Где там можно встретить строковые операции ? ;)
avreal абсолютно прав, так что не нужно с ним спорить.
Конструкция

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

char *foo()
{
static char buffer[20];
////....
buffer[0]='x';buffer[1]=0;
////.... 
return buffer;
}
достаточно часто используется при программировании на C, и ту же asctime avreal уже упоминал. Единственной проблемой таких функций является её нереентерабельность, но в условиях ограниченных ресурсов МК "хочешь жить, ещё не так раскорячишься"(с)
Да, я согласен, что более корректной с этой точки зрения является конструкция

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

char *foo(void *arg1,void *arg2, char *buffer)
{
////...
buffer[0]='x';
////....
return buffer;
}
///////////
void main()
{
static char buffer[30];
////....
printf("%s",foo(a,b,buffer));
////....
}
In theory, theory and practice are the same. In practice, they're not.
HHIMERA
Друг Кота
Сообщения: 4583
Зарегистрирован: Вс дек 05, 2010 06:10:34
Откуда: ЮВ

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

Сообщение HHIMERA »

Tolmi писал(а):И тем не менее есть формальное описание языка, если этот язык - C, то и компилятор с него, и человек, на нём пишуший, должен уметь понимать такие конструкции.
Должен... Но бездумное применение монстроподобных конструкций перетянутых с "большого серого брата IBM" на МК приводят к плачевному раздутию кода и тормознутости...
avreal абсолютно прав, так что не нужно с ним спорить.
Никто с ним и не спорил... а то ещё и MISRA сюда притянуть можно...
Alex только указал, что "матрёшка из чёрных ящичков" никак новичкам не поможет... и здесь он прав...
в условиях ограниченных ресурсов МК "хочешь жить, ещё не так раскорячишься"(с)
Эт точно...
Тут уж не до злоупотреблений указателями... при недоразвитой индексной адресации...
"Я не даю готовых решений, я заставляю думать!"(С)
illarionovsp
Прорезались зубы
Сообщения: 234
Зарегистрирован: Ср апр 29, 2009 22:22:13
Откуда: СПб

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

Сообщение illarionovsp »

Коты, дорогие. Расскажите мне, бестолковцу, почему такая функция:
void mf(char* s) { s="15"; }
ничего не делает. С чем в s вошёл, с тем и вышел. А такая:
void mf(char* s) { itoa(15, s}; }
возвращает в s строку 15, не важно, с чем вошёл.
И ещё вопрос, риторический, конец этому будет, или как?
ЗЫ. Ничего не делает и в VC++ 2008. Вторую функцию проверить не могу: инклайды не подключаются. Почему, не знаю, раньше подключались.
Ответить

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