рекламная строчка Nolix

Показаны сообщения с ярлыком Программирование. Показать все сообщения
Показаны сообщения с ярлыком Программирование. Показать все сообщения

понедельник, 6 апреля 2020 г.

Директива #if в языке С

Об одном нюансе относительно использования директивы #if почему-то редко пишут в учебниках, поэтому на этом нюансе нередко спотыкаются новички. В этой статье мы рассмотрим этот нюанс.
Напомним, что директива #if является одной из директив препроцессора в языке С (как и, само собой, в языке С++). Вспомним также, что препроцессор - это программа, которая занимается подготовкой кода, написанного программистом, к компиляции. То есть тот код, который будет скомпилирован и впоследствии будет выполнятся при запуске программы, зависит от того, как отработает препроцессор.
Существует понятие условная компиляция. Суть его заключается в том, что в зависимости от некоторых условий будет скомпилирован тот или иной код. И вот одной из директив (по- простому говоря, команд) условной компиляции и является директива #if.
Синтаксис этой директивы такой:

#if константное_выражение последовательность операторов #endif
Если константное_выражение имеет ненулевое значение, тогда выполняется последовательность операторов.
Часто в учебниках не упоминают о том, что это константное_выражение обязательно должно быть целочисленным. И совсем редко пишут о том, что в этом константном выражении не могут использоваться целочисленные константы.
Напомним, что именованные константы - это такие константы, которые объявляются с применением спецификатора const, например, так:

const int M = 10;
Почему же нельзя в выражении, стоящем после #if, использовать именованные константы? Потому что директива #if используется еще на этапе препроцессинга, а компьютер на этом этапе еще не знает, что некоторая константа (например, вышеупомянутая M) имеет значение, например, 10. Поэтому такая программка (см. ниже) не приведет к выводу на экран текста "It's OK", как мог бы ожидать автор этого кода.

int main()
{
         const int M = 10;
         #if M == 10
                 cout << "It's OK\n";
        #endif
}


Для решения проблемы достаточно задать константу M другим способом - с помощью директивы #define:

#define M 10
int main()
{
    #if M == 10
          cout << "It's OK\n";
    #endif
}

воскресенье, 9 октября 2016 г.

Бесплатные русскоязычные онлайн курсы программирования

Как всем известно, профессия "программист" в наши дни стала популярной. Спрос на квалифицированных программистов постоянно растёт, также растут и их зарплаты во всём мире. Программист - это одна из самых востребованных и высокооплачиваемых профессий.
Развитие информационных технологий привело также и к появлению совершенно новых, более эффективных, чем традиционные, методов обучения. К таким методам относятся, например, онлайн-курсы. Хорошие онлайн-курсы позволяют достигать высоких результатов благодаря тому, что восприятие информации происходит через два "канала восприятия" - зрение и слух. К тому же , онлайн-курсы удобны тем, что позволяют студенту обучаться в любое удобное для него время.
В русскоязычном сегменте, пожалуй, наилучшие онлайн-курсы - это GeekBrains
На этом портале онлайн-обучения программированию собрано огромное количество всевозможных курсов, причем многие из них бесплатны. Один такой бесплатный курс, посвященный созданию сайтов на языке PHP, прохожу и я.

вторник, 19 января 2016 г.

О наследовании для начинающих программистов

  В этом посте приведен простой пример на языке с++, который помогает помять, что такое наследование. Здесь определены два класса - A и B, которые находятся в отношении наследования: класс B является дочерним по отношению к классу A.
  Поле данных в базовом (иначе говоря, родительском) классе только одно - это переменная целого типа a. В классе B вроде бы присутствует только одно поле данных - int b. Однако как раз суть наследования именно в том и заключается, что все члены базового класса являются также и членами дочернего класса. То есть int a является также и членом класса B. Членами класса B являются два одноименных метода Print(). Если метод Print() вызывается для объекта класса B, то по умолчанию подразумевается, что вызывается "родной" для класса B Print().
В противном случае используется оператор разрешения области видимости "::"



using namespace std;

class A
{
 protected:
int a;
 public:
A(int x){  a = x; }                         // конструктор
void Print() { cout << a << endl;};  // функция - член класса (выводит a)

class B: public A
{
int b;
public:
B() : A(15)     // так как a является членом класса B, то необходимо
{                    // 
проинициализировать путем вызова
b = 20;      // конструктора класса A с параметром типа int
}
B(int y) : A(15)
{
b = y;
}
B(int x, int y) : A(x), b(y)  // с помощью этого конструктора можно                                      
{                                      // проинициализировать  a и через параметры
}

void Print()

      {
A::Print();   // вызов функции Print() из класса A
std::cout << b << endl;
}
};

void main()
{
B obj(40, 50);
obj.Print();      // вызов функции Print() из класса B
obj.A::Print();  // вызов функции Print() из класса A
}


Рисование мышью в консоли

суббота, 16 января 2016 г.

Рисование мышкой в консоли (с++)

Оказывается, в консоли можно сотворить даже что-то типа графического редактора paint. Ниже показан код, как это делается. И добавлены некоторые комментариями.


using namespace std;

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE),
hIn = GetStdHandle(STD_INPUT_HANDLE);

void main()
{
CONSOLE_CURSOR_INFO cinfo = {100, false};
SetConsoleCursorInfo(hOut, &cinfo);//скрыли курсор
COORD c = { 0, 0 };
DWORD d;
CONSOLE_SCREEN_BUFFER_INFO csbi;
INPUT_RECORD ir;
         // устанавливаем режим консоли
SetConsoleMode(hIn, ENABLE_MOUSE_INPUT | ENABLE_INSERT_MODE);
while (1)  // бесконечный цикл
{
while (ReadConsoleInput(hIn, &ir, 1, &d))  // считываем инфу из входного потока
{
if (ir.EventType == MOUSE_EVENT)   // если произошло некое событие с мышью
{
if (ir.Event.MouseEvent.dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED)  // если нажата левая кнопка мыши
{
 // курсор ставится в позицию, где кликнула мышь
         SetConsoleCursorPosition(hOut, ir.Event.MouseEvent.dwMousePosition);
cout << '*';   // при каждом клике левой кнопкой рисуется символ "звездочка"
}
                      // при нажатии правой кнопки мыши всё перекрашиваем в черный цвет (стираем)
else if (ir.Event.MouseEvent.dwButtonState==RIGHTMOST_BUTTON_PRESSED)
{
GetConsoleScreenBufferInfo(hOut, &csbi);
FillConsoleOutputAttribute(hOut, 0, csbi.dwSize.X*csbi.dwSize.Y, c, &d);
}
}
}
}
}
Рисование окон в консоли

пятница, 1 января 2016 г.

Рисование окон в консоли на с++

Пытаясь разобраться с вопросом рисования окон в консоли на с++, я столкнулся с тем, что в Интернете об этом вовсе не много информации. А в примерах кода не хватает комментариев, чтобы быстро понять код.
Ниже приведен код программы на с++ с некоторыми комментариями, которая рисует два окна друг над другом.

//получить дескриптор окна консоли
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

// функция рисования окна, заглавие которого определяется параметром title
// верхний левый угол этого окна будет находиться по координатам x и y
// ширина окна - width, высота - height

void DrawWindow(char * title, int x, int y, int width, int height)
{
COORD c = { x, y };
DWORD d;
SetConsoleCursorPosition(hOut, c); //переставить курсор в координаты x, y
SetConsoleTextAttribute(hOut, FOREGROUND_BLUE | BACKGROUND_RED); // устанавливаем цвет - синий на красном фоне

// рисуем прямоугольник заданного выше цвета
for (int i = 0; i<= width; ++i)
{
if (i == width)
cout << 'X';
else if (i < strlen(title))
cout << title[i];
else
cout << ' ';
}
SetConsoleTextAttribute(hOut, 0);
for (int i = 1; i <= height; ++i)
{
c.X = x;
c.Y = y + i;
//заполнение цветом
FillConsoleOutputAttribute(hOut, 0xff, width + 1, c, &d);
//заполнение символом "пробел"
FillConsoleOutputCharacter(hOut, ' ', width + 1, c, &d);
c.X = x + width + 1;
SetConsoleCursorPosition(hOut, c);
cout << ' ';
}
c.X = x + 1;
c.Y = y + height + 1;
FillConsoleOutputAttribute(hOut, 0, width + 1, c, &d);
//заполняет символом
FillConsoleOutputCharacter(hOut, ' ', width + 1, c, &d);

}

void main()
{
COORD c = { 0, 0 };
DWORD d;
// Информация о курсоре
CONSOLE_CURSOR_INFO ci = { 100, false };
SetConsoleCursorInfo(hOut, &ci);
//Информация об окне консоли будет храниться в структуре csbi
CONSOLE_SCREEN_BUFFER_INFO csbi;
//получаем информацию об заданном экранном буфере консоли
GetConsoleScreenBufferInfo(hOut, &csbi);
//заполняет цветом
// цвет определяется шестнадцатиричным числом - в данном случае 00 означает черный цвет
FillConsoleOutputAttribute(hOut, 0x00, csbi.dwSize.X*csbi.dwSize.Y, c, &d);
// заполняет символом "пробел"
FillConsoleOutputCharacter(hOut, ' ', csbi.dwSize.X*csbi.dwSize.Y, c, &d);
// рисуем окно с координатами левого верхнего угла 3, 3
DrawWindow("MyWindow", 4, 4, 20, 5);
// рисуем окно с координатами левого верхнего угла 6, 6
DrawWindow("MyWindow", 7, 7, 20, 5);
_getch();
}

Рисование мышкой в консоли с++