вторник, 23 ноября 2010 г.

36. Дайте определение дружественной функции. Как объявляется дружественная функция? А как определяется?

Функция может быть дружественнной не сама по себе, а только по отношению к другим классам. Функция дружественная классу - обычная функция, которой доступны скрытые и защищенные члены этого класса.

Объявляется и определяется точно так же как и обычная функция. Но чтобы объявить ее дружественной некоторому классу, этот класс сам должен указать у себя в объявлении этот факт ключевым словом friend

Пример:
class A{
friend void f(A& a);
int x;
};

void f(A& a){a.x = 1;}

35. Какие операции разрешается перегружать только как методы класса?

= [] () ->

воскресенье, 14 ноября 2010 г.

34. Какие операции не рекомендуется перегружать как методы класса? Почему?

Даже и не знаю. Страуструп рекомендует перегружать как методы класса только те операторы, которым требуется изменить защищенные члены. Например:
class A{
  int x;
public:
  A& operator+=(int b){x+=b;} //Этому оператор изменяет защищенный член
}

//А этому не нужно менять, и он может воспользоваться оператором +=
A operator+(A& a, int b){A res = a; return res+=b;}

33. Что означает выражение *this? В каких случаях оно используется?

Разыменованный указатель на себя. Часто используется, если функции-члену класса нужно вернуть ссылку на текущий объект:
class A{
  int x;
public:
  A& operator=(const A& a){x = a.x; return *this;} 
}

32. Как различаются перегруженная префиксная и постфиксная операции инкремента и декремента?

Выражение ++a компилятор превращает в вызов operator++(a), а для a++ в вызов operator++(a, int). Параметр int добавлен только для различия сигнатур функций и его значение не используется. Аналогично для декремента.

31. Какой результат должны возвращать операции с присваиванием?

Вообще говоря, ничего они не должны. Однако, для всех классов, по умолчанию, этот оператор означает копирование объекта и возвращение ссылки. Поэтому, при переопределении оператора, отступать от этого правила нежелательно. Но мы не обязаны использовать этот оператор только для копирования объектов.

class A{
public:
  int x;
  A& operator=(const A& a){x = a.x; return *this;} //переопределили стандартное поведение
  void operator=(int xx){x=xx;} //определили поведение при присваивании целого. Но здесь тоже можно вернуть *this.
};

int main(){
  A a;
  a=1;
  A a2;
  std::cout << (a2=a).x;
}

пятница, 29 октября 2010 г.

30. Перечислите особенности перегрузки операций как методов класса. Чем отличается перегрузка внешним образом от перегрузки как метода класса?

  • Первый параметр оператора опускается, им становится экземпляр класса (this).
  • Его можно сделать константным методом.
  • У него имеется доступ к не-public членам.
  • Оператор можно сделать виртуальным.
Этим и отличается.

среда, 27 октября 2010 г.

29. Можно ли определить новую операцию?

Нельзя. Технически это было бы несложно, но создало бы больше проблем, чем решило. Допустим, мы решили добавить операцию **, означающую в некоторых языках возведение в степень. Посмотрим, какие возникают трудности.
  • Неоднозначность. Как интерпретировать a**b? (a)**(b) или a*(*b). Заметьте, оба варианта синтаксически корректны, но имеют разный смысл. Придется создавать правила для разрешения этой ситуации.
  • Ассоциативность. Чему эквивалентно a**b**c? (a**b)**c или a**(b**c)?
  • Приоритет. Чему эквивалентно a+b**c? (a+b)**c или a+(b**c)?
Напоминаю, с точки зрения разработчика языка, проблемы не являются неразрешимыми. В некоторых языках есть такая возможность.

вторник, 26 октября 2010 г.

28. Можно ли при перегрузке изменить приоритет операции?

К счастью, нет :) Это создало бы слишком много проблем.

понедельник, 25 октября 2010 г.

27. Можно ли перегружать операции для встроенных типов данных?

Нет. Вообще, хотя бы одно из значений оператора должно являться пользовательским типом.

воскресенье, 24 октября 2010 г.

26. Какие операции нельзя перегружать? Как вы думаете, почему?

По-моему, чаще используется слово "оператор", я так и буду их называть.
Перегружать можно следующие операторы:
+ - * / % ^ & | ~ ! = < >
+= -= *= /= %= ^= &= |=
<< >> >>= <<= == != <= >=
&& || ++ -- ->* , -> [] ()
new new[] delete delete[]


А нельзя (подсмотрел у Страуструпа):
  • :: (разрешение области видимости)
  • (выбор члена)
  • .* (выбор члена через указатель на член)
  • ?: тернарный оператор
  • sizeof, typeid
У первых трех в правой части имя, а не значение. У тернарного оператора аж 3 параметра, к тому же его возвращаемое значение является l-value. Переопределять sizeof, typeid, думаю, просто нет смысла.
Также нельзя определить новые лексемы.

суббота, 23 октября 2010 г.

Размер объекта (класса). Что на него влияет.

Раз уж начались вопросы о размере объекта, то перечислим все факторы, влияющие на размер.
  1. Нестатические члены
  2. Выравнивание
  3. Наличие виртуальных методов (+размер указателя на таблицу виртуальных методов)
  4. Количество виртуально пронаследованных классов в иерархии наследования (+размер указателя на таблицу виртуальных методов каждого такого класса)
Вот и все.

25. Одинаков ли размер класса и аналогичной структуры?

Да. У структуры всего одно отличие: доступ к членам по умолчанию открыт (public)

см. также:
6. Является ли структура классом? Чем класс отличается от структуры?
10. Для чего используются ключевые слова public и private?

пятница, 22 октября 2010 г.

24. Влияют ли методы на размер объекта?

Нет. Метод класса един для всех объектов класса, и разумеется, не создается каждый раз при создании объекта.

см. также:
14. Что такое метод? Как вызывается метод?

четверг, 21 октября 2010 г.

23. Каков размер «пустого» объекта?

class A{
}
В теории не меньше одного байта. На практике ровно один байт. Не ноль потому, что, согласно спецификации, каждый объект должен иметь свой адрес. Объекты с нулевым размером запросто могли иметь один и тот же адрес.

вторник, 19 октября 2010 г.

21. Объясните принцип полиморфизма.

Неинтересный вопрос. В том смысле, что в двух словах не рассказать, а расписывать подробно не хочу. О полиморфизме и так много информации в книгах и интернете. Понравилось в Википедии: Кратко смысл полиморфизма можно выразить фразой: «Один интерфейс, множество реализаций». И от себя неплохой, как мне кажется, примерчик.
class Animal{
public:
virtual string voice() = 0;
};

class Cat: public Animal {
public:
string voice(){return "Мяу!";}
};

class Dog: public Animal {
public:
string voice(){return "Гав!";}
};

void printVoice(Animal* animal){
cout << animal->voice(); //Здесь происходит полиморфизм.
}

int main()
{
Animal* animal1 = new Cat;
Animal* animal2 = new Dog;

printVoice(animal1);
printVoice(animal2);

delete animal1;
delete animal2;
}

понедельник, 18 октября 2010 г.

20. Может ли константный метод вызываться для объектов-переменных? А обычный метод — для объектов-констант?

Проще всего посмотреть самому:
class A{
public:
void f1() {}
void f2() const {}
};

int main()
{
A a;
const A& ac = a;

a.f1();
a.f2();
ac.f1(); //ошибка!
ac.f2();
}
Вывод: нельзя вызывать неконстантные функции константных объектов. Но деструктор можно.

воскресенье, 17 октября 2010 г.

19. Зачем нужны константные методы? Чем отличается определение константного метода от обычного?

a. Для отмечания факта, что метод не изменяет члены класса. Компилятор пресечет попытки такого случайного вмешательства. Следующий вопрос посвящен вызову константных методов.
b. void A::f() const {/*...*/}

суббота, 16 октября 2010 г.

18. Что обозначается ключевым словом this?

В каждой нестатической функции-члене класса this является указателем на объект, для которого вызвана функция. Страуструп пишет, что это не совсем обычная переменная и невозможно получить ее адрес. Мне не очень понятно это ограничение. Тем более, программа, откомпилированная MinGW, прекрасно вывела этот адрес.

пятница, 15 октября 2010 г.

17. Можно в методах присваивать параметрам значения по умолчанию?

Так же, как и в обычных функциях.

Это можно сделать либо в объявлении класса:
class A { 
  int f(float c = 3.14);
}
Либо при определении функции:
int A::f(float c = 3.14);

Но не там и там одновременно.

Inline. Встроенные функции.

Раз уж в 16 вопросе были упомянуты встроенные функции, думаю, хорошо было бы рассказать о них подробнее. Как уже сказано, компилятор будет пытаться заменять вызовы таких функций непосредственно на их определения. Например:

inline int plusOne(int n){
  return n+1;
}
/*...*/
int k=5;
cout << plusOne(k);
 

Компилятор заменит plusOne(k) на (k+1), подставив k вместо n в определении функции. Рассмотрим более интересный пример:

//рекурсивное вычисление факториала:
inline int fact(int n){
  return n!=1 ? n*fact(n-1) : 1;
}
/*...*/
cout << fact(3);
 

Действия компилятора с этим выражением по шагам:
  1. cout << (3!=1 ? 3*fact(3-1) : 1); //заменил вызов определением
  2. cout << 3*fact(2); //наш компилятор не дурак - упростил выражение
  3. cout << 3*(2!=1 ? 2*fact(2-1) : 1); //заменил
  4. cout << 6*fact(1); //упростил
  5. cout << 6*(1!=1 ? 1*fact(1-1) : 1); //вызов fact уже не нужен, так как условие не выполняется.
  6. cout << 6;
Теперь такое выражение:
cout << fact(100);
 

Что будет делать компилятор? Заменять вызов 100 раз? А если написать fact(1000)? А если так:
int k;
cin >> k;
cout << fact(k);
 

Опять рассмотрим по шагам:
  1. cout << (k!=1 ? k*fact(k-1) : 1); //Это уже не упростить. Ладно, заменим fact(k-1)
  2. cout << (k!=1 ? k*(((k-1)!=1 ? (k-1)*fact(k-2) : 1)) : 1); //Нда... Продолжаем?
  3. cout << (k!=1 ? k*(((k-1)!=1 ? (k-1)*(((k-2)!=1 ? (k-2)*fact(k-3) : 1)) : 1)) : 1);

Ну все-все, хватит. Компилятор тоже не будет долго церемониться. Если глубина замен вызовов слишком велика, он плюнет на inline, и оставит вызов функции без замены.

четверг, 14 октября 2010 г.

16. Как определить метод непосредственно внутри класса? А вне класса? Чем эти определения отличаются?

a.
class A {
  int f(){return 0;}
}


b.
class A {
  int f();
}

int A::f(){return 0;}


c. Эти классы практически идентичны, но есть небольшое отличие. Определение первого класса эквивалентено:
class A {
  int f();
}

inline int A::f(){return 0;}


То есть, оно отличается от второго наличием ключевого слова inline. Оно означает, что компилятор постарается(так как это не всегда возможно) заменить вызов этой функции его определением. Рекомендуется не использовать вариант a (желательно использовать эквивалентную запись), так как смешиваются "что делает класс" и "как это делает".

среда, 13 октября 2010 г.

15. Может ли метод быть приватный?

Конечно.
Представим функцию:
void A::save(){
  if(check()){
    commit();
  }
}

Перед принятием изменений происодит проверка, все хорошо и логично. Если бы нельзя было сделать commit() приватной, то пользователь данного класса мог бы напрямую вызвать commit() без проверки, что может быть опасно.

вторник, 12 октября 2010 г.

14. Что такое метод? Как вызывается метод?

а. Функция, принадлежащая классу. Методу доступны все поля класса (которому он принадлежит).
б.
class A{
  public:
  void f(int p);
};
1. Допустим, есть объявление: A a;
a.f(5); //вызов

2. Если есть указатель на A (A* pa), то:
2а. (*pa).f(5); //вызов
2б. pa->f(5); //синтаксически более удобный и рекомендуемый вызов.

Дополнение:
При инициализации класса A, в памяти создается метод f. На низком уровне он представляет собой обычную функцию с дополнительным параметром this (указатель на объект, вызвавший функцию). Поэтому a.f(5) заменяется компилятором на что-то вроде:
A__f(&a, 5);

понедельник, 11 октября 2010 г.

13. Обязательно ли делать поля класса приватными?

Конечно нет (Обычно, если все поля класса открытые, класс объявляют с помощью struct, но это только по желанию)

воскресенье, 10 октября 2010 г.

12. Существуют ли ограничения на использование public и private в классе? А в структуре?

Нет. Эти модификаторы(а также protected) могут следовать в любом порядке, и встречаться в определении класса более одного раза. Влияние модификатора продолжается до следующего модификатора или до конца класса.

пятница, 8 октября 2010 г.

10. Для чего используются ключевые слова public и private?

public и private (а так же protected) - модификаторы доступа.
Public – доступ открыт всем, кто видит определение данного класса.
Private – доступ открыт только для самого класса и друзьям (friend) данного класса.
Следует отметить, что public, private, protected могут означать и тип наследования.

четверг, 7 октября 2010 г.

9. Что такое композиция?

С точки зрения объектной модели - использование объекта как поле другого объекта. Мы используем композицию в случае если объект является составной частью другого объекта.

class Car {
  Engine engine;
  Wheel wheels[4];
}


В таком случае составной объект является хозяином своих объектов-частей и ответственнен за их создание и удаление.

среда, 6 октября 2010 г.

8. Объясните принцип инкапсуляции.

Инкапсуляция - сокрытие реализации класса с целью сохраниния целостности. Управляем автомобилем вы можете крутить руль, нажимать педали, переключать передачи и кое-что по-мелочи. Вам нужна возможность, например, менять концентрацию воздуха в горючей смеси или интервалы подачи искры в свечах? Спасибо, не надо.

QtCreator. Задаем опции компилятора.

В .pro файле нужно добавить один из параметров (-O2 только для примера):

QMAKE_CXXFLAGS += -O2 #опция будет включена во всех режимах компиляции.
QMAKE_CXXFLAGS_DEBUG += -O2 #только в режиме DEBUG
QMAKE_CXXFLAGS_RELEASE += -O2 #только в режиме RELEASE

Еще можно написать так:

CONFIG(debug, debug|release){
  # Debug
  QMAKE_CXXFLAGS += -Os
}else{
  # Release
  QMAKE_CXXFLAGS += -O2
}

А вообще все параметры можно посмотреть здесь

вторник, 5 октября 2010 г.

7. Какие ключевые слова в С++ обозначают класс?

Ключевые слова - это зарезервированные идентификаторы.
and and_eq asm auto bitand bitor bool break case catch char class compl const const_cast continue default delete do double dynamic_cast else enum explicit export extern false float for friend goto if inline int long mutable namespace new not not_eq operator or or_eq private protected public register reinterpret_cast return short signed sizeof static static_cast struct switch template this throw true try typedef typeid typename union unsigned using virtual void volatile wchar_t while xor xor_eq

Из них class и struct обозначают класс.

QtCreator. Не удалось сохранить сессию: /Users/%username%/AppData/Roaming/Nokia/qtcreator/default.qws

Такая ошибка появлялась у меня на Windows 7. Мой %username% - кириллический, и QtCreator, из-за проблем с кодировкой, не смог найти соответствующую папку в C:/Users. Желания заводить другого пользователя у меня не было. Пощелкав мышкой, по-кривому, но проблему решил. В QtCreator открываем: инструменты - параметры - вставка кода - основное. Видим поле "имя пользователя". У меня там крякозябры. "А-а-а", - в первый раз сказал я, и написал его нормально, по-русски. Облом, не сохраняет. Тогда я скопировал крякозябры, и создал папку с таким же именем в users. Облом. Ей еще понадобилось дать права всем на чтение и запись. Сейчас все хорошо.

понедельник, 4 октября 2010 г.

6. Является ли структура классом? Чем класс отличается от структуры?

а) Да
б)
класс обявленный как class имеет по умолчанию доступ private,
класс обявленный как struct имеет по умолчанию доступ public.

То есть, такие определения эквиваленты:

class A {
/* */
}

struct A {
private:
/* */
}


Больше отличий нет. На практике обычно структура используется как группировка переменных не требующих задавать поведение для них.

воскресенье, 3 октября 2010 г.

5. Как называется использование объекта одного класса в качестве поля другого класса?

Агрегация. Часто используется ее частный случай - композиция (B - составная часть A, и, в таком случае, А отвечает за создание и уничтожение B)

суббота, 2 октября 2010 г.

4. Допускается ли передавать объекты в качестве параметров, и какими способами? А возвращать как результат?

Так же, как и переменные основных типов - по ссылке(1) и по значению(2).
1. С передачей по ссылке все в принципе ясно: передали ссылку и продолжаем работать с тем же объектом как ни в чем не бывало. Но мне не очень нравится такой способ. Если в коде мы видим:

int x = 1;
f(x);

То мы не можем предугадать, как передан x и может ли измениться его значение в теле функции, так как определение может быть void f(int a) или void f(int &a). Та же неопределенность и при передаче объекта.
Отмечу, что возможности передачи по ссылке не было в C.

2. Если мы не хотим неопределенности, то можно просто передать адрес объекта объекта с помощью указателя (произойдет передача значения указателя). В таком случае код, возможно выглядит не так красиво, но мне нравится больше:

void f(A* a){/* разыменовываем: *a */}

A a;
f(&a);

При передаче объекта по значению будет передано содержимое объекта

void f(A a){/* разыменовываем: *a */}

A a;
f(a);

Будет вызван конструктор копирования.

Возврат результата производится аналогичными способами. Однако важно проследить за временем жизни объекта, иначе можно вернуть ссылку или указатель на уже несуществующий объект. При передаче по значению будет вызван конструктор копирования.

пятница, 1 октября 2010 г.

3. Разрешается ли объявлять указатель на объект? А указатель на класс?

Я много писал об указателях. Ясно, что объявлять указатель на объект конечно же можно.
Вообще говоря, на физическом уровне указатель представляет собой 4 байта, хранящие некоторый адрес. Теоретически можно объявить указатель на все что угодно, что занимает место в оперативной памяти. Но класс не хранится в явном виде в памяти.

Но ради интереса можно подумать что представляет собой класс на низком уровне.

class A{
int x;
int f(){return 1};
}

Если класс не используется в программе, то компилятор, скорее всего пропустит это объявление. Но допустим мы создали объект: A a; но где лежит информация, что член x имеет тип int, и занимает 4 (на других платформах может и не 4) байта? В исходном коде. Именно оттуда компилятор берет эту информацию и генерирует соответствующий код.
А вот код функции f() действительно загружается в память. Она скорее всего будет иметь свой адрес. А может и не будет, например, если компилятор или автор решит сделать ее встроенной (inline).
Как видим, в явном виде класс не хранится.

четверг, 30 сентября 2010 г.

2. Можно ли объявлять массив объектов? А массив классов?

С массивом объектов все ясно:

class A {
public:
int x;
};

A a[3];
//либо динамически:
//A* a = new A[3];
//(важно не забыть delete[] a;)
a[0].x = 1;
a[1].x = 2;
a[2].x = 3;

std::cout << a[0].x << a[1].x << a[2].x;


Переходим к следующему подвопросу. В Delphi можно было провернуть такую штуку:

type

A = class
end;

A1 = class(A)
end;

A2 = class(A)
end;

classA = class of A;

var
classArray : array[1..2] of classA;
objArray : array[1..2] of A;
i : Integer;

begin
classArray[1] := A1;
classArray[2] := A2;
for i := 1 to 2 do
begin
objArray[i] := classArray[i].Create();
ShowMessage(objArray[i].ClassName);
end;
end;

То есть действительно реализовать некий массив классов (можно ли его так назвать?). В C++ я был не очень уверен и погуглил "массив классов". Можно сделать похожий механизм через порождающие фабрики. Но так как это не массив, в обычном понимании, и это только 2-й вопрос, то ответ - "нельзя".
А еще поиск ответа показал, что очень многие спрашивают про "массив классов" имея в виду "массив объектов". Значит первый вопрос (чем обличается класс от объекта?) вполне актуален :)

среда, 29 сентября 2010 г.

1. Что определяет класс? Чем отличается класс от объекта?

Класс определяет структуру и поведение. Объект определяет состояние (наполнение структуры) и меняет его в зависимости от поведения, заданным классом.
Вопрос "Чем отличается класс от объекта?" задает экзаменатор студенту, когда пытается вытащить его на троечку. А студент даже не открывал первую страницу отксеренных лекций. Это примерно то же самое, что спрашивать: "А чем вот этот Тузик(см. рис.) отличается от биологического подвида "собака домашняя"?".

пятница, 24 сентября 2010 г.

Большой список вопросов на знание C++

http://www.rsdn.ru/forum/cpp/1870577.1.aspx
Целых 385 вопросов. От простых до очень сложных.
Буду отвечать понемногу, и помечать топики с ответами меткой "385"

воскресенье, 8 августа 2010 г.

QT интернационализация.

Хорошие статьи о создании поддержки нескольких языков в приложении.
1. Qt — трудности перевода
2. Локализация и числительные

суббота, 7 августа 2010 г.

QT. Цвета виджета.

QPalette p = MyLabel->palette();
p.setColor(QPalette::Window, Qt::black); //фон
p.setColor(QPalette::WindowText, Qt::red); //шрифт
MyLabel->setWidget(p);


все.

пятница, 6 августа 2010 г.

QT. QObject. Первые ошибки. Collect2: ld returned 1 exit status.

В связи со срочностью написания приложения на QT, была бегло пролистана соответствующая книжка. За эту спешку поплатился кучей глупых ошибок. Решил собрать коллекцию таких, на которые MinGW невразумительно ругается :)

При работе с QObject, очень просто получить такое:
1. no matching function for call to 'QObject::connect(...)'
2. undefined reference to 'vtable for MyClass'
3. collect2: ld returned 1 exit status

Последняя ошибка на первом месте моего хит-парада неприятных ошибок :)

Итак, если мы хотим использовать объект QObject, нужно не забывать:

  • Определять классы, использующие макрос Q_OBJECT в заголовочном файле (а не cpp). Иначе схлопочем ошибки 1 и 3.
  • Вставлять макроса Q_OBJECT (Ошибка 1). Примечание: если собрать проект без этого макроса, потом вставить его и опять попробовать собрать, то можно получить ошибки 2 и 3. Нужно произвести чистку проекта (или тупо грохнуть папку с билдом. В QT Creator она по умолчанию-MyProject-build-desktop)
  • Наследоваться от QObject, или его производного класса (Ошибка 1).
  • Вставлять #include . Ошибки можно и не получить, но сигналы и слоты работать не будут.
  • Определять объявленные слоты, если не хотим получить ошибку 3. С этим я конкретно намучался. "collect2: ld returned 1 exit status" и все! Ну как тут понять, что я просто забыл написать тело для слота MyClass::mySlot(){/* */}


UPD (7.08.10 18:25):
Блин, мне было нужно смотреть консоль сборки (QT Creator). Я бы сразу увидел дополнительную информацию о причинах ошибки.

среда, 7 июля 2010 г.

Еще 2 теста на Quizful

Я просто был обязан их пройти :)

Pascal - Основы:
Правильных ответов: 13 / 16 (81 %) требуется: 12
Синтаксис 3 / 4 (75 %)
Управляющие конструкции 3 / 4 (75 %)
Процедуры и функции 2 / 3 (66 %)
Указатели и ссылки 1 / 1 (100 %)
Типы данных 4 / 4 (100 %)

Delphi 7 - Основы
Правильных ответов: 14 / 18 (77 %) требуется: 14
Синтаксис 4 / 4 (100 %)
Ход выполнения программы 2 / 3 (66 %)
Указатели и ссылки 2 / 3 (66 %)
Массивы 2 / 3 (66 %)
Классы и объекты 3 / 4 (75 %)
Остальные 1 / 1 (100 %)

Радует, что провалов нет.

понедельник, 5 июля 2010 г.

"Это же БИБЛИЯ))) Не продам..."

Таким был один из комментариев в местном сообществе, на мое предложение купить бумажную книгу Страуструпа :) Ее нигде нет. В Ozon'е, Books.ru, Bolero и в куче других нет. В электронном виде не интересно.

воскресенье, 4 июля 2010 г.

Сервис онлайн тестирования Quizful

Про этот сервис я знал уже давно, если не ошибаюсь, прочитал про него на Хабре. После прочтения заглянул на него, ради интереса прошел какой-то тест. И только потому, что саморазвиваться мне не очень хотелось, я долго не возвращался туда. Но когда захотел проверить свои знания c++, сразу же вспомнил о нем. Итак, описание с сайта Quizful.net:

Проект Quizful предназначен для онлайн-тестирования специалистов в сфере информационных технологий. Quizful является community-driven сервисом и развивается во многом благодаря усилиям сообщества ИТ-специалистов.

Цель проекта - предоставить качественный бесплатный сервис, который бы не только проверял уровень имеющихся знаний, но и помогал в получении новых знаний.


То, что нужно. Сразу был выбран тест "C++ - Основы". И вот горькая правда: тест не пройден.

Правильных ответов: 11 / 20 (55 %) требуется: 15
Базовые понятия 2 / 5 (40 %)
Управляющие конструкции 3 / 3 (100 %)
Функции 2 / 3 (66 %)
Ссылки и указатели 3 / 3 (100 %)
Структуры и классы 0 / 4 (0 %)
Массивы 1 / 2 (50 %)

Я конечно очень расстроился, но комменты приободрили:

Отличный тест на знание C++! Я его 2 раза завалил - прошел только с 3-ей попытки, хотя программирую на нем уже 8 лет! После теста возникает непреодолимое желание схватить книгу Страуструпа и читать до посинения! Жаль что времени на это у меня нет и не предвидится :( А так Автору теста - 5!

До прохождения теста считал себя если не крутым, то неплохим знатоком С++, благо кодирую на нем уже года три, есть несколько завершенных проектов... но тест оказался "ушатом холодной воды" выявил кучу моих пробелов в теории - пройти его сумел только с 4го раза. Почувствовал себя невеждой. Срочно открыл книги Кернигана, Страуструпа и Майерса - сидеть мне с ними по вечерам месяц, пока не пройду без ошибок все тесты.

Значит все не так уж плохо. И не зря я долбил указатели, 3/3 - порадовало :)

Обычно я не люблю тесты за их требования знать половину справочника, то, что я за полторы секунды найду в гугле. Тут же, видимо благодаря сообществу, вопросы в целом понравились. То, с чем мы сталкиваемся на практике.

Например: Что будет выведено на экран после выполнение данного фрагмента кода?
int x = 0;
int y = 0;

if (x++ && y++){
y += 2;
}

cout << x + y;


Не буду писать (но очень хочется, так как из-за этого я ответил неверно), что есть подвох - в программировании все строго.

Варианты ответа:
0 (84 / 368)
1 (77 / 368)
2 (103 / 368)
3 (12 / 368)
4 (91 / 368)
В скобках количество давших такой ответ и это самое любопытное :)

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

Планы

Первый день нового года - отличный повод строить планы.

Для работы:
· В первую очередь (в первых месяцах), хотелось бы занятся изучением процесса разработки ПО.
· Администрирование Windows Server
· Нужно более хорошее знание Oracle, pl/sql.
· Основы информационной безопасности.

Для себя
· Основы Linux
· Основы Adobe Flash (просто интересно)

В конце года можно будет подвести итоги :D