Что означает это выражение? (SetConsoleTextAttribute функция в C) - PullRequest
5 голосов
/ 24 сентября 2011

Я нахожусь в процессе создания небольшой консольной игры для нашего класса по программированию на C, и я решил сделать ее более презентабельной и уникальной, добавив цвета текста и фоновые изображения текста.В моих поисках решения я нашел эту удобную функцию, которая будет работать так, как я хотел для моего проекта, но проблема в том, что есть эта часть, которую я не понимаю:

WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);

Где, BackC и ForgC являются целыми числами, а тип данных WORD является просто typedef для беззнакового short int.В частности, я не понимаю, что такое ((BackC & 0x0F) << 4) + (ForgC & 0x0F).Кто-нибудь может мне с этим помочь?Я знаю, что могу просто использовать функцию, но я действительно хочу знать, как эта функция работает ... Спасибо!

Вот полный исходный код (colorExample.c)

#include <windows.h>
#include <stdio.h>
void SetColorAndBackground(int ForgC, int BackC);
int main()
{
    SetColorAndBackground(10,1);   //color value range 0 up-to 256
    printf("what is text background color \n");
    SetColorAndBackground(11,1);
    printf("how about this?");
    getch();
    return 0;
}
void SetColorAndBackground(int ForgC, int BackC)
{
     WORD wColor = ((BackC & 0x0F) << 4) + (ForgC & 0x0F);
     SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), wColor);
     return;
}

Ответы [ 2 ]

4 голосов
/ 24 сентября 2011

ForgC и BackC - это два значения, которые на самом деле могут расширяться только до 4 бит каждый (вы можете сказать это, потому что они побитовые ANDed с 0x0F, который очищает всено последние 4 бита первого операнда).

Так что, если мы посмотрим на них как на значения 8-битной ширины, они будут иметь вид

ForgC      0000xxxx
BackC      0000yyyy

Тогда вы сдвигаете по битам ForgC 4 бита слева, что делает

ForgC      xxxx0000
BackC      0000yyyy

И затем вы складываете их вместе…, делая

ForgC      xxxx0000
BackC      0000yyyy
Result     xxxxyyyy

Таким образом, в действительности это «объединяет» оба значения в одно.SetConsoleTextAttribute может затем разделить их снова или использовать объединенное значение как есть.


¹ Технически это должно быть побитовым ИЛИ вместо целочисленного сложения.Хотя в этом конкретном случае (где два операнда гарантированно не имеют 1-бит в одной и той же позиции) обе операции приведут к одному и тому же результату, побитовое ИЛИ сделает намерение более ясным.

0 голосов
/ 24 сентября 2011

If берет младшие 4 бита каждого из BackC и ForgC и объединяет их, чтобы получить 8-битное значение.

((
    BackC & 0x0F     // take last 4 bits of BackC
 ) << 4)             // and shift 4 to the left
 + 
 (
    ForgC & 0x0F     // plus take last 4 bits of ForgC
 )

например. если BackC равно 0b......abcd и ForgC равно 0b.....efgh (оба в двоичном представлении), вы получите значение 0xabcdefgh.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...