понедельник, 3 марта 2014 г.

Вопрос-ответ: какие преимущества даёт знание C++?

Вопрос:
какие преимущества даёт знание C++?
Ответ:
Работа на C++ позволяет вникнуть в основы (но не гарантирует, что вы в них вникните). А если верить вот этому, то сегодня (апрель, 2013) перспективнее Java. 

Вопрос-ответ: зачем в видеоуроках используется несколько getchar() подряд?

Вопрос:
Несколько раз в видеоуроках проскакивала фраза о том, что после printf() надо использовать несколько getchar(), но не объяснялось почему (либо я не заметил). Я так подозреваю что это потому что printf не делает перенос на последующую строку. Более того, getchar() адекватно реагирует кажись только на ввод символа, а не на any key типа стрелок. Ввиду этого возможно есть смысл использовать команду _getch()? Она ж вроде работает корректнее?

Ответ:
Два вызова getchar() нужно для задержки программы (ожидания нажатия Enter) после scanf(). Когда вы вводите данные с клавиатуры, используя scanf(), то функция scanf() "вычитывает" введенные с клавиатуры данные, оставляя в буфере клавиатуры нажатие на Enter (#13). Если после этого вызвать getchar(), то функция считает из буфера клавиатуры этот символ и "подумает", что пользователь нажал Enter, вернет значение. Соответственно, задержки-ожидания нажатия клавиши не получится. Поэтому нам понадобится второй getchar(). Первый "проглотит" оставшийся Enter, второй будет ждать нажатия. При этом, сколько бы раз вы ни вызывали scanf() в вашей программе, в буфере клавиатуры останется только один последний Enter. С предыдущими scanf() справится сам.

Вопрос-ответ: почему в видеоуроках вы используете _tmain() вместо main()?

Вопрос:
В видеоуроках вы используете процедуру _tmain (), хотя если в настройках проекта убрать пару опций и начинать с пустого проекта, то можно обойтись и без библиотеки stdafx.h, имхо это лишняя информация для тех кто изучает язык. И тогда будет "классический" вариант с main().

Ответ:
Можно и так, согласен. Но задачей было не получить классический канонический си, а писать программы (и начать как можно быстрее). Поэтому мы начинаем с того, что генерирует мастер создания проекта. Если вы при создании проекта уберете галочку с precompiled headers, то тогда stdafx.h можно не подключать.

Вопрос-ответ: почему в видеоуроках вы используете printf() вместо cout?

Вопрос:
Вы в основном используете команду вывода на экран printf(), хотя это более С-шный вариант, в С++ для этого есть команда cout. Вроде как она сама распознает и тип вывода переменных, и несколько проще для ознакомления с С++. Скажите, пожалуйста, возможно я чего-то не учитываю, а printf функциональнее?

Ответ:
Я использую printf() и scanf() для того, чтобы мои студенты освоили форматирование строк и выучили базовые символы формата, например, %d, %f, %g, \n и т.д. Это пригодится в будущем. Даже если не писать консольных приложений, очень часто возникает задача вывода на экран строк, "собранных" в программе. Например, диалог подтверждение: "Вы действительно хотите удалить 25 выбранных файлов?". Для этого используются функции, очень похожие на printf(). Напиример, sprintf(). Объединяет все эти функции то, что символы формата у них одинаковые, чтобы соблюсти единообразие с printf(). Резюме - функции printf()/scanf() используются только для того, чтобы выучить символы форматов. Никаких преимуществ по сравнению с потоками нет.

Как стать экспертом

Интересный совет прочитал у Эрика Липперта о том как стать экспертом в выбранной области. Этот совет дал ему менеджер, когда Эрик в 1996 году, сразу после окончания колледжа, устроился в Microsoft, в команду, разрабатывающую VBScript/JavaScript компиляторы.

На момент трудоустройства Эрик знал многое о VBScript, но практически ничего о JavaScript. Так как он пришел в команду по разработке компилятора (интерпретатора), то ему не просто нужно было понять основы JavaScript, а стать экспертом.

Менеджер Эрика посоветовал ему выбрать достаточно узкую область, например, семантику языка JavaScript, и затем находить все вопросы в Интернете и внутри Microsoft, которые задают другие люди по этой теме. Если ответ известен - ответить. Если нет - изучать вопрос до тех пор, пока не будет найден ответ.

Для Эрика это стало не просто повышением уровня знаний по JavaScript. Благодаря такому подходу он узнал с какими проблемами разработчики, использующие JavaScript (то есть, клиенты команды), сталкиваются чаще всего.

Более того, это помогло более тесно взаимодействовать с клиентами, некоторые из которых сами были экспертами. История закончилась наймом одного из таких экспертов, что оказалось весьма полезным для всей команды.

В 1990-е новостные группы Usenet и Fidonet были лучшим средством общения. В настоящее время существуют такие ресурсы как StackOverflow, являющиеся ценными источниками хороших ворсов и ответов.

Эрик Липперт (Eric Lippert) - ведущий разработчик в команде по разработке компилятора C# и член комитета по развитию языка. Автор книг по языку C#. Ранее в Microsoft работал над развитием и разработкой языков VBScript, JavaScript, Windows Script Host и Visual Studio For Office.

i++ VS ++i. Различия префиксного и постфиксного операторов инкремента

Во многих источниках (книгах или заметках, а также в исходных текстах программ) можно встретить примеры циклов или другие конструкции, в которых применяется операция инкремента, то есть увеличения значения переменной на 1. Например, следующая:
int i = 0;
i = i + 1;
В языках Си и C++ существует также оператор инкремента, делающий, по сути, то же самое (также есть и оператор декремента, т.е. уменьшения значения переменной на 1).
int i = 0;
i++; // значение переменной i теперь 1
Особенность операторов инкремента и декремента состоит в том, что у них есть префиксная (т.е. записанная перед аргументом) и постфиксная (т.е. записанная после аргумента) формы с немного отличающейся семантикой.

Практически во всех примерах, которые можно встретить, используется постфиксная, т.е. записанная после аргумента, форма (см. пример выше).
Однако если Вы были внимательны, то заметили, что в видеуроках я использую префиксную, т.е. записанную перед аргументом, форму оператор инкремента.
int i = 0;
++i; // значение переменной i теперь 1
Так в чем же разница?
Обе формы выполняют одно и то же действие – увеличивают (или уменьшают, если мы говорим о декременте) значение своего аргумента на 1.

Разница в том, что постфиксные формы операторов ++ и -- возвращают исходное (старое) значение, а префиксные – новое.

Чтобы было понятнее, проиллюстрируем сказанное на примере:
int i = 0; 
int k = i++; // i = 1, k = 0, 
    // т.к.  постфиксный оператор
    // инкремента, увеличивая i на 1, 
    // возвращает исходное,
    // то есть, старое занчения 0
      

int n = ++i; // i = 2, k = 2
    // т.к. префиксный оператор
    // инкремента, увеличивая i на 1, 
    // возвращает новое значение, т.е. 2
В вашем коде лучше всего лучше всего использовать префиксные операторы, если только вам не требуется исходное значение, возвращаемое постфиксной формой. Префиксная форма может оказаться немного эффективнее постфиксной, т.к. не создает нового объекта для временного хранения старого значения переменной.

Пример с циклом for:
for (int i = 0; i < 10; ++i)
{
 cout << i << endl;
}

Пример с циклом while:
// имеется некая строка
// необходимо вывести 
// строку на экран, пропустив
// пробелы в начале строки
char *str = /*.....*/; 
//.....
while (str[i] == ' ')
 ++i; //пропустить все пробелы

cout << "строка без ведущих пробелов: " 
        << str + i << endl;

Hello, World!


   
#include <stdio.h>
int main(int argc, char* argv[])
{
    printf("Hello, world!\n");
    return 0;
}