Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Флаги


Автор: Hagrael 27.7.2011, 15:10
Привет всем. Я много раз видел применение флагов во встроенных функциях, но как применить их в своей функции, ума не приложу. Я вообще не представляю, что это. Пожалуйста, приведите простой пример приема флага в качестве аргумента в функции и вызов этой функции.

Автор: borisbn 27.7.2011, 16:18
Не до конца понял, что ты хочешь, но, кажется, это (или нет?)
Код

#define CAN_BE_AT_LEFT      0x1
#define CAN_BE_AT_RIGHT    0x2
#define CAN_BE_AT_TOP       0x4
#define CAN_BE_AT_BOTTOM  0x8
#define CAN_BE_AT_LEFT_TOP ( CAN_BE_AT_LEFT | CAN_BE_AT_TOP )
#define CAN_BE_AT_RIGHT_BOTTOM ( CAN_BE_AT_RIGHT | CAN_BE_AT_BOTTOM )
// и т.п.
unsigned int can_be_flag = 0;
void set_can_be( unsigned int flag ) {
    can_be_flag = flag;
}
void move( int x, int y ) {
    if ( x == 0 && (can_be_flag & CAN_BE_AT_LEFT) == 0 ) {
        return;
    }
    if ( y == 0 && (can_be_flag & CAN_BE_AT_TOP) == 0 ) {
        return;
    }
// и т.п.
}

// вызов
set_can_be( CAN_BE_AT_LEFT | CAN_BE_AT_BOTTOM );

Автор: Dem_max 27.7.2011, 16:30
Код

bool flFlag = true;

//вызов
func(flFlag);

int func(bool Flag)
{
   if(Flag) return 0;
return 1;
}

Автор: Hagrael 27.7.2011, 19:55
borisbn, да-да, это то, что было нужно! Но как это работает? Что делает операция |, &, обязательно ли в 16-ричной системе? Пожалуйста, дайте ссылку или объясните. Я, правда, ничего не нашел.

Автор: asmdzen 27.7.2011, 21:11
Цитата(Hagrael @  27.7.2011,  19:55 Найти цитируемый пост)
обязательно ли в 16-ричной системе?

нужно знать как цифры представлены в двоичном виде.
1 = 1
2 = 10
3 = 11
4 = 100
5 = 101
6 = 110
7 = 111
8 = 1000
тебе нужны только те в которых только одна единица, типа 1, 2, 4, 8, 16, если присмотреться то можно заметить что это степени двойки.
есть например у тебя функция которая выводит номер в консоль, как параметр она принимает номер и флаги, типа как именно выводить
Код

enum style{WITH_ENDL = 1, IN_HEX = 2, SOME_OTHER = 4};
void OutNum(int n, style outStyle)
{
   if(outStyle & IN_HEX) cout << hex;
   cout << n;
   if(outStyle & WITH_ENDL) cout << endl;
}
 

Автор: azesmcar 27.7.2011, 21:11
Hagrael

В одном байте 8 бит, т.е. флагов (1 или 0). 1 означает, что флаг установлен, 0 - что флага нет.
Допустим мы используем тип char, размер которого 1 байт.
В него можно установить 8 битов. Назначаем каждому биту определенное имя, допустим речь идет о доступе.
0 - read
1 - write
2 - execute
(ну прямо как в unix)
теперь создаем перечисление
Код

enum access
{
   access_none = 0,  // 000 в двоичном виде
   access_read = 1,   // 001 в двоичном виде
   access_write = 2,  // 010 в двоичном виде
   access_exec = 4    // 100 в двоичном виде
};

операция | (т.е. bitwise OR) работает так
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0
т.е. если оба бита нулевые, то результат будет нулевым. Рассмотрим пример
01010010 OR
11010100
-------------
11010110
теперь посмотрим, что происходит с нашим перечислением
Код

char c = access_read | access_write;

001 OR
010
-----
011 - 3 в двоичном виде, т.е. мы даем доступ на чтение и на запись.
Теперь второй этап - проверка флага
Здесь используется операция & (т.е. bitwise AND). Работает она так
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0
т.е. если хотя бы один из битов нулевой - результат будет нулевым. Применяем это к нашему char-у, в котором на данный момент записано число 3 (011 в бинарном виде).
Код

if ((c & access_read) != 0) ...

получается так
011 AND
001
-----
001
выходит что флаг access_read установлен, так-как результат не нулевой.
т.е. проверка
Код

if ((c & access_read) != 0) ...

проверяет установлен ли флаг access_read, а скобки нужны для приоритета.

Автор: Hagrael 28.7.2011, 07:15
azesmcar, оператор | по-моему делает то же самое, что и оператор + smile
А оператор & возвращает число с такими включенными битами, которые были включены и в первом операнде и во втором?

Автор: azesmcar 28.7.2011, 08:07
Hagrael

Я же описал, что делают эти операторы. Если бы оператор | делал тоже, что и оператор +, то нафиг он вообще нужен этот лишний оператор? Пользовались бы плюсом и дело с концом. Это битовые операции, они делают побитовый OR и побитовый AND, т.е. выполняют

Цитата(azesmcar @  27.7.2011,  21:11 Найти цитируемый пост)
1 | 1 = 1
1 | 0 = 1
0 | 1 = 1
0 | 0 = 0

и
Цитата(azesmcar @  27.7.2011,  21:11 Найти цитируемый пост)
1 & 1 = 1
1 & 0 = 0
0 & 1 = 0
0 & 0 = 0

для каждого бита и возвращают результат.

Автор: ller 28.7.2011, 08:19
что то похожее на сложение дает xor (оператор ^)

0^0=0
1^0=1
0^1=1
1^1=0

1+1=2 или в двоичной системе 01+01=10. т.е. последний бит сбрасывается.

Автор: borisbn 28.7.2011, 08:24
Цитата(Hagrael @  28.7.2011,  07:15 Найти цитируемый пост)
оператор | по-моему делает то же самое, что и оператор +

Код

    int x = 0x7FFFFFFF;
    int x_plus_1 = x + 1;
    int x_or_1 = x | 1;
    cout << hex << "x_plus_1 = " << x_plus_1 << " x_or_1 = " << x_or_1 << endl;

http://liveworkspace.org/code/a63c4684e167c46f6af536ba20b655ae
Цитата(Hagrael @  28.7.2011,  07:15 Найти цитируемый пост)
А оператор & возвращает число с такими включенными битами, которые были включены и в первом операнде и во втором?

 smile

Добавлено через 1 минуту и 51 секунду
Цитата(ller @  28.7.2011,  08:19 Найти цитируемый пост)
что то похожее на сложение дает xor (оператор ^)

на что похоже и чем ? smile

Автор: ller 28.7.2011, 08:54
На оператор + smile

1^1=0
1+1=0 + переполнение, ну или что то в этом роде.
Я так думаю! smile

Автор: borisbn 28.7.2011, 09:49
ller, в принципе ты прав. XOR ещё называют "сложение по модулю 2". Т.е.
Цитата

X ^ Y == (X + Y) % 2

где X и Y - одиночные биты (значение X может быть либо 0 либо 1. Для Y - то же самое)
% - остаток от деления

Автор: Hagrael 30.7.2011, 08:08
Спасибо за помощь smile

Автор: voral 30.7.2011, 09:14
Б. Керниган, Д. Ритчи - Язык Си - Глава 6.9 Битовые поля
Кроме описанного варианта есть такой:
Код

struct {
    unsigned int is_keyword : 1;
    unsigned int is_extern  : 1;
    unsigned int is_static  : 1;
} flags;

Автор: Alca 30.7.2011, 09:26
CFlags.h

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)