Информация об изменениях

Сообщение Re[5]: Пригласите меня к себе на собеседование! от 23.04.2018 12:04

Изменено 23.04.2018 12:07 AleksandrN

Re[5]: Пригласите меня к себе на собеседование!
Здравствуйте, RussianFellow, Вы писали:


AN>>2. Написать функцию, вычисляющую факториал.


RF>
RF>int  factorial(int n)
RF>{
RF>    int  res;

RF>    if (n==0)
RF>        res = 1;
RF>    else
RF>    {
RF>        res = 1;
RF>        for (i=1; i<=n; i++)  res *= i;
RF>    }
RF>    return  res;
RF>}
RF>


Нет проверки корректности входных условий. Использован знаковый тип, поэтому на входе может быть -1.

Я бы сделал чуть по другому.
    // long лучше, чем int для данного случая, т.к. число может быть очень большим.
    unsigned long fact( unsigned long value )
    {
        if ( value < 2 )
            return 1;
        
        unsigned long result = 2;
        // Сэкономим пару итераций. 
        for ( unsigned long i = 3; i <= value; i++ )
            result *= i;

        return result;
    }


Можешь решить рекурсией и сравнить решения с помощью рекурсии и итерации?

AN>>3. Найти потенциальные проблемы в коде и исправить.

RF>
RF>unsigned long a = 1234567;
RF>char *s;

RF>strcpy( s, "Hello world!" );

RF>printf( "Data: %d %s; address: 0x%x\n", a, s, s );
RF>


RF>Я бы так написал:


RF>
RF>unsigned long a = 1234567;
RF>char *s;

RF>s = new char[80]; // выделяю память для строки s, вместо 80 можно поставить любое другое разумное число
RF>strcpy( s, "Hello world!" );

RF>printf( "Data: %ld %s; address: 0x%x\n", a, s, (unsigned int)s ); // %ld--для числа типа long, указатели в C++ имеют тип беззнакового целого числа
RF>


Памяти выделено избыточно и она не освобождена. Размер указателя и размер int не на всех архитектурах совпадают. Для указателя есть модификатор %p. Знаешь, как производится работа с параметрами в функции с переменным числом аргументов? Чем опасно использование модификатора для типа, размер которого отличается от размера аргумента?

Лучше так
    unsigned long a = 1234567;
    // Если знаем, что строку большего размера записывать не будем, то лучше использовать strdup()
    // для выделения памяти и копирования строки.
    char *s = strdup( "Hello world!" );

    printf( "Data: %lu %s; address: %p\n", a, s, s );
    // Не надо забывать освобождать ресурсы.
    free( s );


Но ещё лучше так:
    unsigned long a = 1234567;
    // Что здесь происходит, можешь объяснить?
    const char *s = "Hello world!";

    printf( "Data: %lu %s; address: %p\n", a, s, s );
Re[5]: Пригласите меня к себе на собеседование!
Здравствуйте, RussianFellow, Вы писали:


AN>>2. Написать функцию, вычисляющую факториал.


RF>
RF>int  factorial(int n)
RF>{
RF>    int  res;

RF>    if (n==0)
RF>        res = 1;
RF>    else
RF>    {
RF>        res = 1;
RF>        for (i=1; i<=n; i++)  res *= i;
RF>    }
RF>    return  res;
RF>}
RF>


Нет проверки корректности входных условий. Использован знаковый тип, поэтому на входе может быть -1.

Я бы сделал чуть по другому.
    // long лучше, чем int для данного случая, т.к. число может быть очень большим.
    unsigned long fact( unsigned long value )
    {
        if ( value < 2 )
            return 1;
        
        unsigned long result = 2;
        // Сэкономим пару итераций. 
        for ( unsigned long i = 3; i <= value; i++ )
            result *= i;

        return result;
    }


Можешь решить рекурсией и сравнить решения с помощью рекурсии и итерации?

AN>>3. Найти потенциальные проблемы в коде и исправить.

RF>
RF>unsigned long a = 1234567;
RF>char *s;

RF>strcpy( s, "Hello world!" );

RF>printf( "Data: %d %s; address: 0x%x\n", a, s, s );
RF>


RF>Я бы так написал:


RF>
RF>unsigned long a = 1234567;
RF>char *s;

RF>s = new char[80]; // выделяю память для строки s, вместо 80 можно поставить любое другое разумное число
RF>strcpy( s, "Hello world!" );

RF>printf( "Data: %ld %s; address: 0x%x\n", a, s, (unsigned int)s ); // %ld--для числа типа long, указатели в C++ имеют тип беззнакового целого числа
RF>


Памяти выделено избыточно и она не освобождена. Немножко внимательнее — тест по C, а не C++. Размер указателя и размер int не на всех архитектурах совпадают. Для указателя есть модификатор %p. Знаешь, как производится работа с параметрами в функции с переменным числом аргументов? Чем опасно использование модификатора для типа, размер которого отличается от размера аргумента?

Лучше так
    unsigned long a = 1234567;
    // Если знаем, что строку большего размера записывать не будем, то лучше использовать strdup()
    // для выделения памяти и копирования строки.
    char *s = strdup( "Hello world!" );

    printf( "Data: %lu %s; address: %p\n", a, s, s );
    // Не надо забывать освобождать ресурсы.
    free( s );


Но ещё лучше так:
    unsigned long a = 1234567;
    // Что здесь происходит, можешь объяснить?
    const char *s = "Hello world!";

    printf( "Data: %lu %s; address: %p\n", a, s, s );