Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   С/С++, C#, Delphi, .NET, Asm (https://forum.antichat.xyz/forumdisplay.php?f=24)
-   -   [C/C++] ЗАДАНИЯ (https://forum.antichat.xyz/showthread.php?t=126299)

Fata1ex 21.06.2009 15:46

[C/C++] ЗАДАНИЯ
 
По аналогии с темой Krist_ALL'a решил создать отдельный топик с заданиями по С/С++. Надеюсь что вы enjoy it ;)

Задание 1.
Код:

int a, sum=0; char buf[4096];
        printf("Tell me your name:"); gets(buf);
        for(a=0; a<100; a++) sum+=0;
        //(с) мыщьх

Как оптимизировать программу с точки зрения использования ею оперативной памяти? И что в ней не так?

Верное решение


Задание 2.

Мы создаем класс без конструкторов. Что сгенерирует компилятор дополнительно?
Мы создаем класс, в котором есть только конструктор без аргументов. Что сгенерирует компилятор дополнительно?
Мы создаем класс, в котором есть только конструктор копии. Что сгенерирует компилятор дополнительно?


Задание 3.
Код:

class SimpleClass {
                private:
                        int a;
                        int b;
                public:
                        SimpleClass(int x) : b(x), a(b) {}
                        void print() {
                                std::cout << "a=" << a << " b=" << b << std::endl;
                        }
        };

        int main() {
                SimpleClass a(42);
                a.print();
        return 0;
}

Что здесь не так?

Верное решение


Задание 4.
Код:

class A {
public:
    virtual void Foo (int n = 10) {
        cout << "A::Foo, n = " << n << endl;
    }
};

class B : public A {
public:
    virtual void Foo (int n = 20) {
        cout << "B::Foo, n = " << n << endl;
    }
};

int main() {
    A * pa = new B ();
    pa->Foo ();

    return 0;
}
//(c) habrahabr//h1ppo

Что выведет программа и почему?

Верное решение


Задание 5.
Код:

foo() {
    char a;
    char b;
    char c;
    char d[5];
}
(c) мыщьх

Сколько байт локальной памяти мы израсходовали? Почему? Как оптимизировать эту "оптимизированную"(здесь подсказка;)) программу?

Верное решение


Задание 6.
Код:

void display(int in) {
    // What im doing here????????/
cout << ++in;
}

void foo() {
    int a=10;
    display(a);
}

Что выведет программа?

Верное решение


Задание 7. (by slesh)

Код:

struct _REC {
unsigned char data1;
unsigned short data2;
bool data3;
bool data4;
bool data5;
bool data6;
bool data7;
unsigned short data8;
} REC;

Как оптимизировать данную структуру чтобы она занимала в памяти 6 байта, то есть sizeof(REC) = 6
В таком виде структура занимает 12 байт.
При этом не был потерян функционал!!!

Верное решение
Верное решение



Задание 8. (by slesh)


Необходимо откомпилить консольную прожку. Я тестил на VC++ 2008
ПРИМЕЧАНИЯ:
1) в коде нельзя ничего удалять!!
2) нельзя подключать новые хидеры!!
Код:

#include "stdio.h"
void _stdcall Sleep(unsigned long dwMilliseconds);
int main(int argc, char* argv[]) {
 printf("START PAUSE");
 Sleep(2000);
 printf("STOP PAUSE");
 return 0;
}

ПОДСКАЗКА: решение требует дописания одной строки.

Верное решение


Задание 9. (by slesh)

Код:

#include "stdio.h"
#include "windows.h"
int main(int argc, char* argv[]) {
 printf("SRART\n");
 __asm
 {
  hlt
 }
 return 0;
}

При выполнении появляется ошибка из-за того, что команда hlt является привилегированной и недоступной из пользовательского режима.
Необходимо обработать это исключение, выдать на экран сообщение об ошибке и завершить работу программы.
И Главное - решение не должно использовать конструкцию try except и должно иметь глобальные характер. т.е. даже если это исключение появится в отдельном потоке, то действия программы должны быть такими же.
P.S. Решение требует примерно 5 строчек кода.

Верное решение


Задание 10.

Создать динамический двумерный массив размерностью N. Заполнить его значениями. Вывести значения массива на экран. Запрещается использовать символы '[' и ']'.

Верное решение
Верное решение


Задание 11.

Как можно выполнить эффективное побайтовое сравнение структур, не используя прагмы компилятора и группировку членов?

Верное решение


Задание 12.

Код:

for (int k=0, int A=0; k < strlen(str); k++)
    A+=str[k];

Оптимизировать код.

Верное решение
Особое решение slesh'a :)


Задание 13.

Что эффективней использовать и почему:
Код:

strcpy(str, "bytes "); strcat(str, very_long_string);
или
strcpy(str, "bytes: "); strcat(str, very_long_string);

?

Верное решение


Задание 14.

Создать массив, начальный индекс которого есть произвольное число (например, 1, а не с 0).

Верное решение


Задание 15.
Код:

const int x = 1;  {
        enum { x = x + 1, y, z = x };
        std::cout << x << ' ' << y << ' ' << z << std::endl;
}

Что выведет программа и почему? Без компиляции, пожалуйста )

Верное решение


Задание 16. (by desTiny)

Что будет в переменной после выполнения кода (не компилить!)
Код:

/*very very long not ever overflowable*/ int a = 5+765432l;
?

Верное решение


Задание 17. (by fker)

Ввести число n, и заполнить двухмерный массив размерностью n числами от 1 до n*n по спирали.

Верное решение


Задание 18.

Привести три эффективных варианта выхода из большого количества вложенных циклов без использования операторов break.

Верное решение (Part 1) + Верное решение (Part 2)


################################################## ###########################

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

Еще хочу добавить: если вам интересны интересные(оО) и нестандартные задачи по С/С++, вам понравится книги
Г. Саттер - Решение сложных задач C++
Г. Саттер - Новые сложные задачи C++
М.В. Мозговой - 85 нетривиальных проектов, решений и задач

Gar|k 21.06.2009 16:26

задание одын
Код:

int sum=0; char buf[]="Tell me your name:";
puts(buf); fgets(buf, sizeof(buf), stdin);

??

Fata1ex 21.06.2009 16:31

Нет, имелось в виду несколько не это ) Присмотрись к циклу, к порядку появления переменных.
PS Переполнение здесь роли не играет.

nemaniak 21.06.2009 21:22

может быть так?

int a, sum=0; char buf[4096];
printf("Tell me your name:"); gets(buf);
for(a=0; a<100; a++, sum++);

jawbreaker 21.06.2009 21:37

В первой задаче для локальных переменных будет использовано слишком много стековой памяти (8 килобайт вместо 4). Бороться с этим можно если запихать данные в структурку

Fata1ex 21.06.2009 21:42

Совершенно верно )

Fata1ex 21.06.2009 22:13

Добавил пару задачек

FireFenix 22.06.2009 01:04

Цитата:

foo() {
char a;
char b;
char c;
char d[5];
}
За счёт выравнивания будет 20 байт (3[a,b,c] по 4 байта, d выравняет на 8 байт = 20 байт)
Если всё запихнуть в структуру, то будет оптимизированно
Цитата:

void display(int in) {
// What im doing here????????/
cout << ++in;
}

void foo() {
int a=10;
display(a);
}
Поидее должно вывести 11, т.е. вначале выполнится инкремент (т.к. знак инкремента стоит слева, если справа - то после вывода), птом вывод

slesh 22.06.2009 09:25

А вот задачка от меня

Код:


struct _REC
 {
  unsigned char data1;
  unsigned short data2;
  bool data3;
  bool data4;
  bool data5;
  bool data6;
  bool data7;
  unsigned short data8;
} REC;

Как оптимизировать данную структуру чтобы она занимала в памяти 6 байта. т.е. sizeof(REC) = 6
В таком виде структура занимает 12 байт.
При этом небыл потерян функционал!!!

Ra$cal 22.06.2009 09:50

Код:

struct _REC
{
        unsigned short data2;
        unsigned short data8;
        unsigned char data1;
        bool data3:1;
        bool data4:1;
        bool data5:1;
        bool data6:1;
        bool data7:1;
} REC;

=)

slesh 22.06.2009 09:54

Практически правильно, но есть способо без изменения позиции переменных

Его необходимо применить чтобы данная структура стала 7 байт и не потерялся функционал
Код:

struct _REC
{
  struct
  {
      unsigned char data1;
      unsigned short data2;
      bool data3;
      bool data4;
    bool data5;
  } first_rec;
  bool data6;
 bool data7;
 unsigned short data8;
} REC;

Также более наглядно будет в этом примере:
Размер должен быть 7 байт!!
Код:

struct _REC
 {
  unsigned short data1;
  unsigned short data2;
  unsigned short data3;
  bool data4;
  bool data5;
  bool data6;
  bool data7;
  bool data8;
} REC;


slesh 22.06.2009 10:05

P.S. Существуют 2 решения, оба сводятся к одному и томуже, но реализуются соверщенно по разному

FireFenix 22.06.2009 10:13

Цитата:

Сообщение от slesh
Практически правильно, но есть способо без изменения позиции переменных

Использовать вместо структуры - объединения (union)?

slesh 22.06.2009 10:17

Нет union делает другое

slesh 22.06.2009 10:20

А вот еще одно задание довольно интерестное, если сразу задуматься, то быстро можно решить.

ЗАДАЧА: необходимо откомпилить консольную прожку. Я тестил на VC++ 2008
ПРИМЕЧАНИЯ:
1) в коде нельзя ничего удалять!!
2) нельзя подключать новые хидеры!!
Код:

#include "stdio.h"

void _stdcall Sleep(unsigned long dwMilliseconds);

int main(int argc, char* argv[])
{
 printf("START PAUSE");
 Sleep(2000);
 printf("STOP PAUSE");
 return 0;
}

ПОДСКАЗКА: решение требует дописания одной строки.

Ra$cal 22.06.2009 10:29

вот вам моя задачка. есть класс с перегруженным оператором <. есть вектор, который хранит shared_ptr'ы на объекты этого класса. задача - поюзать std::sort не создавая левые функции, только при помощи stl b boost::bind. второй день не могу понять в чем дело =\ был бы вектор чистых объектов - можно было отсортировать строкой

Код:

std::sort(state_lines.begin(), state_lines.end());
а я уже опустился до дублирования сравнения в статик методе less

Код:

std::sort(state_lines.begin(), state_lines.end(),
    boost::bind<bool>(&HorizontalStateLine::less, _1, _2));

все равно не компилится =\
Код:

e:\Program Files\boost\boost_1_38\boost\bind.hpp(282): error C2664: 'bool (const geometry::HorizontalStateLine &,const geometry::HorizontalStateLine &)' : cannot convert parameter 2 from 'std::allocator<_Ty>::value_type' to 'const geometry::HorizontalStateLine &'
        with
        [
            _Ty=geometry::HORIZONTALSTATELINE_PTR
        ]
e:\Program Files\boost\boost_1_38\boost\bind.hpp(282): error C2664: 'bool (const geometry::HorizontalStateLine &,const geometry::HorizontalStateLine &)' : cannot convert parameter 1 from 'std::allocator<_Ty>::value_type' to 'const geometry::HorizontalStateLine &'
        with
        [
            _Ty=geometry::HORIZONTALSTATELINE_PTR
        ]
        Reason: cannot convert from 'std::allocator<_Ty>::value_type' to 'const geometry::HorizontalStateLine'
        with
        [
            _Ty=geometry::HORIZONTALSTATELINE_PTR
        ]
        No constructor could take the source type, or constructor overload resolution was ambiguous

люто бешено не понимаю почему от простого изменения типа элемента с объекта на указатель творится такая жопа


[ADDED]
сцуко скомпилелось =\\\ пришлось сделать внутри класса такое вот

static bool less (const HORIZONTALSTATELINE_PTR& left, const HORIZONTALSTATELINE_PTR& right);

FireFenix 22.06.2009 10:37

Цитата:

Сообщение от slesh
А вот еще одно задание довольно интерестное, если сразу задуматься, то быстро можно решить.

ЗАДАЧА: необходимо откомпилить консольную прожку. Я тестил на VC++ 2008
ПРИМЕЧАНИЯ:
1) в коде нельзя ничего удалять!!
2) нельзя подключать новые хидеры!!
Код:

#include "stdio.h"

void _stdcall Sleep(unsigned long dwMilliseconds);

int main(int argc, char* argv[])
{
 printf("START PAUSE");
 Sleep(2000);
 printf("STOP PAUSE");
 return 0;
}

ПОДСКАЗКА: решение требует дописания одной строки.

extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long dwMilliseconds);

slesh 22.06.2009 10:41

Ну и вот еще одна задачка от меня, если заюзать поиск то можно быстро решить её.
ЗАДАЧА: существует програмка
Код:

#include "stdio.h"
#include "windows.h"

int main(int argc, char* argv[])
{
 printf("SRART\n");
 __asm
 {
  hlt
 }
 return 0;
}

При выполненни вылезит ошибка из-за того что команда hlt является привелегированной и недоступной и пользопательноского режима.

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

И Главное - решение не долно использовать конструкцию try except и должно иметь глобальные характер. т.е. даже если это исключение появится в отдельном потоке, то действия программы должны быть такимиже.

P.S. Решение требует примерно 5 строчек кода.

desTiny 22.06.2009 11:20

Цитата:

Сообщение от slesh
Практически правильно, но есть способо без изменения позиции переменных

Его необходимо применить чтобы данная структура стала 7 байт и не потерялся функционал
[code]
Размер должен быть 7 байт!!
Код:

struct _REC
 {
  unsigned short data1;
  unsigned short data2;
  unsigned short data3;
  struct{
    unsigned data4:1;
    unsigned data5:1;
    unsigned data6:1;
    unsigned data7:1;
    unsigned data8:1;
  } noch_eine_struktur;
} REC;


неявное преобразование типа должно сжевать.

только чушь это всё конечно)

slesh 22.06.2009 11:41

2 desTiny всё делает намного проще )
И то что ты показал, то 12 байт вообще )

rudvil 22.06.2009 12:03

Извиняюсь за глупый вопрос, но что делает эта единица в конце?
Код:

bool data7:1;
Ведь таким же образом наследуют структуры и классы, а тут мистическая цифра "1" =/

slesh 22.06.2009 12:06

это значит что ты эта переменная будит занимать 1 бит.
И по этому конструкция в структуре типа
bool data1:1;
bool data2:1;
bool data3:1;
bool data4:1;
bool data5:1;
bool data6:1;
bool data7:1;
bool data8:1;
тудет занимать 1 байт

rudvil 22.06.2009 12:13

Интерестно, спасибо.

jawbreaker 22.06.2009 12:13

Цитата:

Сообщение от Fata1ex
Задание 4.
Код:

class A {
public:
    virtual void Foo (int n = 10) {
        cout << "A::Foo, n = " << n << endl;
    }
};

class B : public A {
public:
    virtual void Foo (int n = 20) {
        cout << "B::Foo, n = " << n << endl;
    }
};

int main() {
    A * pa = new B ();
    pa->Foo ();

    return 0;
}
//(c) habrahabr//h1ppo

Что выведет программа и почему?

Ну видимо B::Foo, n = 10 потому что значение по умолчанию будет взято из другой функции?

desTiny 22.06.2009 12:13

ок, так:
Код:

struct _REC
 {
        unsigned data1:16;
        unsigned data2:16;
        unsigned data3:16;
        unsigned data4:1;
    unsigned data5:1;
    unsigned data6:1;
    unsigned data7:1;
    unsigned data8:1;
} REC;

//его почему-то short смущал

slesh 22.06.2009 12:16

2 desTiny Это правильный, но некрасивый способо. Есть более красивый и удобный)

Fata1ex 22.06.2009 12:57

Спасибо всем, кто поддержал тред. Обновил первый пост: есть нерешенные задачи!

Lee_fx 22.06.2009 13:32

Код:

void display(int in) {
    // What im doing here????????/
cout << ++in;
}

void foo() {
    int a=10;
    display(a);
}

Ничего не выведет, ??/ - триграф = \(конкатенация), в итоге получится функция void display(int in) {}

Lee_fx 22.06.2009 13:33

Код:

class SimpleClass {
                private:
                        int a;
                        int b;
                public:
                        SimpleClass(int x) : b(x), a(b) {}
                        void print() {
                                std::cout << "a=" << a << " b=" << b << std::endl;
                        }
        };

        int main() {
                SimpleClass a(42);
                a.print();
        return 0;
}

Насколько помню тут первой инициализируется переменная a, так как стоит первая в объявлении в private и инициализируется соответственно мусором из b. Короче SimpleClass(int x) : b(x), a(b), порядок b(x), a(b) или a(b), b(x) не важен.

Fata1ex 22.06.2009 13:43

Немного поправлю:
Списки инициализаторов инициализируют члены данных в порядке их следования в определении класса. Отсюда проблемы = )
Решения приняты )

desTiny 22.06.2009 20:33

Цитата:

Сообщение от slesh
2 desTiny Это правильный, но некрасивый способо. Есть более красивый и удобный)

разумеется, он убогий) как и вся идея сожрать 4 байта

Кстати, мой VS сказал про него "8 байт". и про такое тоже:
Код:

struct _REC
 {
                unsigned short a,b,z;
                  bool c:1,d:1,e:1,f:1,g:1;
} REC;


slesh 22.06.2009 21:19

Вижу что мало кто юзает данный способ по этому напишу правильный ответ сам )
Это директивы компилятора, которые на время могут менять выравнение структур.
Подефолту выравнение идет на 4 байта. т.е. если структура будет 9 байт, то выравнеется на 12.
#pragma pack(1) - выравнение 1 байт
#pragma pack() - дефолтовое выранение. вот и выходит код типа

#pragma pack(1)
struct .....
#pragma pack()

Fata1ex 22.06.2009 21:22

Кстати, одним из решений другого задания (5) тоже были директивы и никто не написал :(
Забыли их, бедняжек (
Added: перечитал пару статей: действительно, скорость при использовании прагм компилятора падает. Иногда значительно.

slesh 22.06.2009 21:26

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

Fata1ex 22.06.2009 21:28

Вообще это можно использовать не только в сетевых приложениях, а везде ) Лишних пару сэкономленных байт еще никому не мешали.
Added: перечитал пару статей: действительно, скорость при использовании прагм компилятора падает. Иногда значительно.

slesh 22.06.2009 23:46

Кстати не всегда это делать желательно, потому как бываются случае что
адрес переменной должен быть выравнен на 4 байта иначе будет ошибка.
Такое встречается в некоторых WinAPI функцих которые просто убивают приложение если адрес буфера не выравненн на 4 байта

Ra$cal 23.06.2009 00:27

это еще приводит к замедлению работы, ибо обращение к невыравненной ячейке памяти дает штраф

Цитата:

При этом различные процессоры по-разному подходят к адресации слов.
Во-первых, некоторые процессоры (PDP-11, SPARC) запрещают обращения к словам, адрес которых не кратен размеру слова, и генерируют при попытках такого обращения исключительную ситуацию ошибки шины. Другие процессоры, например VAX и х86 такие обращения разрешают, но в документации есть честное предупреждение, что обращения к невыровненным словам будут минимум в два раза медленнее, чем к выровненным (рис. 2.4).

Fata1ex 23.06.2009 09:04

Добавил несколько несложных задачек. Не решены задания 2, 9, 10, 11, 12, 13, 14.
С радостью выслушаю любые ваши предложения и замечания )

slesh 23.06.2009 11:01

здание 12 хочу решить так ))

Код:

int a = 0;
char * k = str;
while (k[0])
 {
  a += k[0];
  k++;
 }


Fata1ex 23.06.2009 11:07

Нужно отредактировать исходный код )) Хотя твоя версия, безусловно, верна.


Время: 20:40