GCC и цикл for (C)

Модератор: Модераторы разделов

Аватара пользователя
ЭЖД
Сообщения: 332
Статус: openSuSE Member
ОС: openSuSE

GCC и цикл for

Сообщение ЭЖД »

есть такой вод код

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

/*
 * 12.6.1.c
 *
 *  Created on: 01.05.2009
 *      Author: egd
 */

#include <stdio.h>

int size_int;

void int_size (void) {
    unsigned int a = ~0;

    for ( size_int = 0; a != 0; ++size_int)
        a >>= 1;
}

int bitpat_search (unsigned int source, unsigned int pattern, unsigned int n) {
    int i, j, bit_s = 1, bit_p = 1;
    unsigned int s1, p1;

    for (i = 0; i != size_int; ++i) {
        if ((source & 1) == (pattern & 1)) {
            for (j = 1; j != n+1; ++j) { //j = 1 - первый бит мы уже нашли, начинаем со второго
                if ((source & bit_s << 1) != (pattern & bit_p << 1))
                    break;
                else if (j == n)
                        return i;
            }
            bit_s = 1;
            bit_p = 1;
        }
        source >>= 1;
    }
    return -1;
}

int main (void) {
    void int_size (void);
    int bitpat_search (unsigned int source, unsigned int pattern, unsigned int n);

    int_size();

    printf("%i \n", bitpat_search (0xe1f4, 0x5, 3));

    return 0;
}


меняем строку for (j = 1; j != n+1 ; ++j) на for (j = 0; j != n; ++j) - функция возвращает -1
меняем строку for (j = 1; j != n+1 ; ++j) на for (j = 1; j != n; ++j) - функция возвращает -1
меняем строку for (j = 1; j != n+1 ; ++j) на for (j = 0; j != n+1; ++j) - функция возвращает 2

что за магия такая? компилировал в Eclipse
«Когда истинный гений появляется в этом низком мире, его можно узнать по тому знаку, что все глупцы объединяются против него»
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: GCC и цикл for

Сообщение drBatty »

ЭЖД писал(а):
01.05.2009 14:56
меняем строку for (j = 1; j != n+1 ; ++j) на for (j = 1; j != n+1; ++j)
ну значит глюк вашего редактора.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
yaleks
Сообщения: 2121
Статус: вне статуса
ОС: Gentoo ~

Re: GCC и цикл for

Сообщение yaleks »

версия gcc?
Спасибо сказали:
Аватара пользователя
ЭЖД
Сообщения: 332
Статус: openSuSE Member
ОС: openSuSE

Re: GCC и цикл for

Сообщение ЭЖД »

yaleks писал(а):
01.05.2009 15:12
версия gcc?

> gcc -v
Using built-in specs.
Target: i586-suse-linux
Configured with: ../configure --prefix=/usr --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.3 --enable-ssp --disable-libssp --with-bugurl=http://bugs.opensuse.org/ --with-pkgversion='SUSE Linux' --disable-libgcj --disable-libmudflap --with-slibdir=/lib --with-system-zlib --enable-__cxa_atexit --enable-libstdcxx-allocator=new --disable-libstdcxx-pch --enable-version-specific-runtime-libs --program-suffix=-4.3 --enable-linux-futex --without-system-libunwind --with-cpu=generic --build=i586-suse-linux
Thread model: posix
gcc version 4.3.2 [gcc-4_3-branch revision 141291] (SUSE Linux)
«Когда истинный гений появляется в этом низком мире, его можно узнать по тому знаку, что все глупцы объединяются против него»
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: GCC и цикл for

Сообщение drBatty »

ЭЖД вы хотите сказать, что при компиляции одного .cpp файла получается одна программа, а при компиляции другого, бит-в-бит совпадающего с ним .cpp файла получается другая программа?!
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ЭЖД
Сообщения: 332
Статус: openSuSE Member
ОС: openSuSE

Re: GCC и цикл for

Сообщение ЭЖД »

drBatty писал(а):
01.05.2009 15:22
ЭЖД вы хотите сказать, что при компиляции одного .cpp файла получается одна программа, а при компиляции другого, бит-в-бит совпадающего с ним .cpp файла получается другая программа?!

я хочу сказать, что если в этой строке поменять вместо n+1 на n то будет -1. в любом случае.
изменение инициализирующего значения для j не влияет на возвращаемое значение.
«Когда истинный гений появляется в этом низком мире, его можно узнать по тому знаку, что все глупцы объединяются против него»
Спасибо сказали:
Аватара пользователя
кодировщик
Сообщения: 974
Статус: зарёган в пятницу 13
ОС: Linux

Re: GCC и цикл for

Сообщение кодировщик »

Сильно не разбирался ещё, но у меня всегда получается 2.
Спасибо сказали:
Аватара пользователя
ЭЖД
Сообщения: 332
Статус: openSuSE Member
ОС: openSuSE

Re: GCC и цикл for

Сообщение ЭЖД »

пробовал в ручную компилировать - тоже самое
«Когда истинный гений появляется в этом низком мире, его можно узнать по тому знаку, что все глупцы объединяются против него»
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: GCC и цикл for

Сообщение NickLion »

Все правильно, так и должно быть. Смотрим внимательно:

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

            for (j = 1; j != n; ++j) { //j = 1 - первый бит мы уже нашли, начинаем со второго
                if ((source & bit_s << 1) != (pattern & bit_p << 1))
                    break;
                else if (j == n)
                        return i;

Если у Вас до !=n цикл идет, то при j==n в цикл захода не будет, а в функции только два ретурна, этот - гарантированно не выполняется, значит отработает return -1. (Теоретически еще зависнуть может, но не в данном случае). Логично?

PS А что за такой страшный поиск? Не проще идти просто масками, а не побитово?
Спасибо сказали:
Аватара пользователя
ЭЖД
Сообщения: 332
Статус: openSuSE Member
ОС: openSuSE

Re: GCC и цикл for

Сообщение ЭЖД »

NickLion
ну это задачка из книжки. буду раз увидеть другую реализацию :)

все понял. тупимс...
«Когда истинный гений появляется в этом низком мире, его можно узнать по тому знаку, что все глупцы объединяются против него»
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: GCC и цикл for

Сообщение NickLion »

Вот так, например:

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

int bitpat_search (unsigned int source, unsigned int pattern, unsigned int n) {
    unsigned int mask = ( 1 << n ) - 1;
    for( unsigned int k = 0, ss = source; k < size_int; k++, ss >>= 1 ) {
        if( ( ss & mask ) == ( pattern & mask ) )
            return k;
    }
    return -1;
}


PS надеюсь правильно понял назначение параметров :)
Спасибо сказали:
Аватара пользователя
ЭЖД
Сообщения: 332
Статус: openSuSE Member
ОС: openSuSE

Re: GCC и цикл for

Сообщение ЭЖД »

там не будет работать.
нужно в source найти pattern.
а зачем отнимать 1 от переменной mask?
«Когда истинный гений появляется в этом низком мире, его можно узнать по тому знаку, что все глупцы объединяются против него»
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: GCC и цикл for

Сообщение drBatty »

ЭЖД писал(а):
08.05.2009 22:30
а зачем отнимать 1 от переменной mask?

что-бы получилось из

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

00000010000000000
00000001111111111

это вы SHIFT-AND пишете? или что? у меня где-то был готовый велосипед из этой серии, правда ему лет пять... но ездит...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: GCC и цикл for

Сообщение NickLion »

ЭЖД писал(а):
08.05.2009 22:30
там не будет работать.
нужно в source найти pattern.
а зачем отнимать 1 от переменной mask?

Где там?
Так вроде это и делается. Возвращает смещение pattern в source. Последний параметр - длина паттерна в битах.
Насчет "-1" drBatty уже ответил.
Спасибо сказали:
Аватара пользователя
ЭЖД
Сообщения: 332
Статус: openSuSE Member
ОС: openSuSE

Re: GCC и цикл for

Сообщение ЭЖД »

drBatty писал(а):
09.05.2009 01:43
это вы SHIFT-AND пишете? или что? у меня где-то был готовый велосипед из этой серии, правда ему лет пять... но ездит...


NickLion писал(а):
09.05.2009 11:45
Где там?
Так вроде это и делается. Возвращает смещение pattern в source. Последний параметр - длина паттерна в битах.


это задачка из книжки Кочан "Програмиирование на языке С". нужно найти номер бита в source с которого начниается последовательность битов pattern, n - кол-во битов в pattern
/me мало опыта

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

int bitpat_search (unsigned int source, unsigned int pattern, unsigned int n) {
    unsigned int mask = ( 1 << n ) - 1, k;
    for( k = 0; k < size_int; k++, source >>= 1 ) {
        if( ( ss & mask ) == pattern )
            return k;
    }
    return -1;
}
«Когда истинный гений появляется в этом низком мире, его можно узнать по тому знаку, что все глупцы объединяются против него»
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: GCC и цикл for

Сообщение drBatty »

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

#include <stdio.h>

int fnd(unsigned source, unsigned pattern, unsigned n)
{
    unsigned mask = (1 << n) - 1;
    unsigned j;
    for(j = 0; j < 32 - n; j++)
    {
        unsigned x = source ^ pattern;
        x &= mask;
        if(x == 0)      return j;       // совпадение
        pattern <<= 1;
        mask <<= 1;
    }
    return -1;
}

int main()
{
    unsigned source = 0xABCDEF32;
    unsigned pattern = 0xE;
    printf("find %X in %X\n", pattern, source);
    int f = fnd(source, pattern, 4);
    if(f < 0)
        printf("not found\n");
    else
        printf("fount at %d\n", f);
    return 0;
}

так проще и быстрее в разы
ну и имхо понятнее.
идея в том, что XOR даёт нуль тогда и только тогда, когда аргументы совпадают, причём мы сравниваем всё, но не все биты нам интересны, потому мы сбрасываем (x &= mask) все не интересные биты. Если интересные биты все 0, то x == 0, и мы нашли pattern. Иначе двигаем образец и маску, и ищем снова.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: GCC и цикл for

Сообщение NickLion »

Так вроде тот код что я тогда кинул это и делает. Ваш надо немного поравить:

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

int bitpat_search (unsigned int source, unsigned int pattern, unsigned int n) {
    unsigned int mask = ( 1 << n ) - 1, k;
    for( k = 0; k < size_int /*здесь кстати открытым остается вопрос с ведущими нулями*/; k++, source >>= 1 ) {
        if( ( /*раз ss не надо тогда */ source & mask ) == pattern )
            return k;
    }
    return -1;
}

Насчет ведущих нулей:
если в 11...1 (0xffff) искать 011 (0x3), длина паттерна - 3, то будет найдено вхождение начиная с 30 бита, т.к. теоретически перед 1 идут нули. Если же надо ограничить только 32 битами, тогда цикле:

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

k<=size_int-n


drBatty
А чем плох мой код? По скорости - все норм, по логичности - тут еще поспорить. Лично для меня логичнее то, что я написал.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: GCC и цикл for

Сообщение drBatty »

NickLion ваш - нормальный. плох тот что в книжке - кривой, нелогичный, и не оптимальный. особенно расстроило то, что в книжке по 1 биту сравнивается. ИМХО это намного сложнее, в том числе и для понимания. Работа с битами это вообще ИМХО слабая сторона Си.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
NickLion
Сообщения: 3408
Статус: аватар-невидимка
ОС: openSUSE Tumbleweed x86_64

Re: GCC и цикл for

Сообщение NickLion »

drBatty писал(а):
09.05.2009 17:22
ваш - нормальный. плох тот что в книжке - кривой, нелогичный, и не оптимальный. особенно расстроило то, что в книжке по 1 биту сравнивается. ИМХО это намного сложнее, в том числе и для понимания. Работа с битами это вообще ИМХО слабая сторона Си.

А, я подумал Вы про мой код :) Ну побитово конечно дольше будет. Только тут и асм не особо спасает. Все-равно с масками эффективнее работать. Тут причина кроется в устройстве самого процессора - операции над регистрами атомарные, а посему работа с группой битов быстрее, чем последовательно каждый. BSF и BSR в данной задаче не помогут. В общем, быстрее не получится.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: GCC и цикл for

Сообщение drBatty »

NickLion писал(а):
09.05.2009 17:29
Все-равно с масками эффективнее работать.

конечно. так и там и там с масками в итоге. просто не понятно желание автора книжки делать маску 00000000100000000 и проверять по 1 биту - ИМХО этим он всех путает, в том числе и себя :(
быстрее наверное нельзя... Действительно, тут ни bsr, ни таблицы не помогут... Однако и задачи такие редко бывают...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ЭЖД
Сообщения: 332
Статус: openSuSE Member
ОС: openSuSE

Re: GCC и цикл for

Сообщение ЭЖД »

ну кривой потомучто это мое решение задачки :)
а про маски и не объясняли особо в нижке... но теперь разобрался. буду знать и юзать :)
спасибо
«Когда истинный гений появляется в этом низком мире, его можно узнать по тому знаку, что все глупцы объединяются против него»
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: GCC и цикл for

Сообщение drBatty »

ЭЖД писал(а):
09.05.2009 20:06
ну кривой потомучто это мое решение задачки

во... а я думал - в книжке :)
ЭЖД писал(а):
09.05.2009 20:06
а про маски и не объясняли особо в нижке...

это больше из асма... есть специальные библиотеки для поиска подстроки в строке, их и надо использовать...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
ЭЖД
Сообщения: 332
Статус: openSuSE Member
ОС: openSuSE

Re: GCC и цикл for

Сообщение ЭЖД »

drBatty писал(а):
09.05.2009 20:36
ЭЖД писал(а):
09.05.2009 20:06
а про маски и не объясняли особо в нижке...

это больше из асма... есть специальные библиотеки для поиска подстроки в строке, их и надо использовать...

про стандартные библиотека в книге упор не делается, все нужно самому выдумывать.
«Когда истинный гений появляется в этом низком мире, его можно узнать по тому знаку, что все глупцы объединяются против него»
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: GCC и цикл for

Сообщение drBatty »

ЭЖД писал(а):
11.05.2009 16:15
про стандартные библиотека в книге упор не делается, все нужно самому выдумывать.

могли бы написать, что такие задачи на си плохо получаются...
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали: