Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.75/4: Рейтинг темы: голосов - 4, средняя оценка - 4.75
Nashorn
0 / 0 / 0
Регистрация: 20.08.2014
Сообщений: 10
1

Что должна вернуть функция?

20.08.2014, 02:29. Просмотров 657. Ответов 12
Метки нет (Все метки)

Здравствуйте. Функции turn_bit_on(), turn_bit_off() и toggle_bit() при передаче им некорректного номера бита должны каким-то образом проинформировать вызывающего об ошибке. На данный момент они возвращают -1, но ведь единички могут получиться и при корректной работе. Собственно, что должна вернуть функция в таком случае, каким образом можно обойти проблему?

Может быть, просто поставить запрет на использование старшего бита?

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include <stdio.h>
 
int check_range(int);
int check_bit(int, int);
int turn_bit_on(int, int);
int turn_bit_off(int, int);
int toggle_bit(int, int);
 
int main() {
    printf("check: %d\n", check_bit(5, 0)); // 1
    printf("on: %d\n", turn_bit_on(5, 1)); // 7
    printf("off: %d\n", turn_bit_off(5, 0)); // 4
    printf("toggle on: %d\n", toggle_bit(5, 1)); // 7
    printf("toggle off: %d\n", toggle_bit(5, 0)); // 4
 
    return 0;
}
 
int check_range(int bit_id) {
    int size = sizeof(int) * 8;
 
    return (bit_id >=0 && bit_id < size) ? 1 : 0;
}
 
int check_bit(int value, int bit_id) {
    int pattern = 1;
 
    if (check_range(bit_id)) {
        pattern <<= bit_id;
        value = (value & pattern) ? 1 : 0;
    } else {
        value = -1;
    }
 
    return value;
}
 
int turn_bit_on(int value, int bit_id) {
    int pattern = 1;
 
    if (check_range(bit_id)) {
        pattern <<= bit_id;
        value |= pattern;
    } else {
        value = -1;
    }
 
    return value;
}
 
int turn_bit_off(int value, int bit_id) {
    int pattern = ~1;
 
    if (check_range(bit_id)) {
        pattern <<= bit_id;
        value &= pattern;
    } else {
        value = -1;
    }
 
    return value;
}
 
int toggle_bit(int value, int bit_id) {
    int pattern = 1;
 
    if (check_range(bit_id)) {
        pattern <<= bit_id;
        value ^= pattern;
    } else {
        value = -1;
    }
 
    return value;
}
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.08.2014, 02:29
Ответы с готовыми решениями:

Что должна возвращать функция?
У меня есть задание: Написать функцию поиска LastIndexOf() последнего вхождения...

Одна функция должна вызываться из другой, в чём ошибка?
#include &lt;stdio.h&gt; void print (int number){ printf(&quot;you number...

Функция должна вывести cnt битов, расположенных в памяти, начиная с адреса addr
дана функция: void dump(void* addr, int cnt); Функция должна вывести cnt...

Вернуть HANDLE по указателю (Функция под WIN для открытия порта)
Пытаюсь написать функцию под WIN для открытия порта. int...

Программа не выполняет то что должна
помогите разобраться... программа не делает что должна ((( #include &lt;stdio.h&gt;...

12
HighPredator
5680 / 2002 / 720
Регистрация: 10.12.2010
Сообщений: 5,759
Записей в блоге: 3
20.08.2014, 09:12 2
Моя рекомендация будет заключаться в следующем: в функции ввести третий формальный параметр -- вычисляемое значение, а по return возвращать сведения об ошибках. Ну и работать с без знаковыми типами.
0
Nashorn
0 / 0 / 0
Регистрация: 20.08.2014
Сообщений: 10
20.08.2014, 14:19  [ТС] 3
Я правильно понял ход вашей мысли?

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
 
int check_range(int);
int toggle_bit(int*, int);
 
int main() {
    int value = 5;
 
    if (toggle_bit(&value, 100)) {
        printf("%d\n", value);
    } else {
        fprintf(stderr, "wrong bit id\n");
    }
 
    return 0;
}
 
int check_range(int bit_id) {
    int size = sizeof(int) * 8;
 
    return (bit_id >=0 && bit_id < size) ? 1 : 0;
}
 
int toggle_bit(int *value, int bit_id) {
    int result, pattern = 1;
 
    if (check_range(bit_id)) {
        pattern <<= bit_id;
        *value ^= pattern;
 
        result = 1;
    } else {
        result = 0;
    }
 
    return result;
}
0
Vtulhu
423 / 377 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
20.08.2014, 16:12 4
Позвольте трупу упасть!
0
Nashorn
0 / 0 / 0
Регистрация: 20.08.2014
Сообщений: 10
20.08.2014, 16:20  [ТС] 5
Программа не упадет, функция просто вернет некорректное значение, порушив логику.
0
Charles Kludge
Клюг
7642 / 3157 / 382
Регистрация: 03.05.2011
Сообщений: 8,382
20.08.2014, 19:22 6
Nashorn, если оформить ф-цию примерно так:
C
1
2
3
4
5
6
7
8
short int check_bit(long val, short int nr)
{
_asm{   movzx   ecx, nr
    bt  val, ecx
    setc    al
    cbw
};
};
то проц аппаратно сделает ecx = ecx & 0x1F .
1
Nashorn
0 / 0 / 0
Регистрация: 20.08.2014
Сообщений: 10
21.08.2014, 00:07  [ТС] 7
Charles Kludge, в asm пока не могу, только-только Си начал, но спасибо, как-нибудь сяду за разбор.
0
Vtulhu
423 / 377 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
21.08.2014, 09:26 8
Цитата Сообщение от Nashorn Посмотреть сообщение
Программа не упадет, функция просто вернет некорректное значение, порушив логику.
Такой подход плох, потому что если в функцию передан неправильный параметр - значит, где-то в программе ошибка. И лучше один раз программа упадет, вынудив нас найти и исправит ошибку, чем мы будем ловить какое-то непонятное поведение. Прочтите еще раз статью. Не надо возвращать код ошибки через значение, это крайне плохой стиль программирования. Можно использовать ассерты, получив некое подобие контрактного программирования.

C
1
2
3
4
5
6
unsigned long turn_bit_on(unsigned long val, const unsigned int n)
{
    assert( n < 32 );
    val &= 1 << n;
    return val;
}
Если же позарез надо делать именно так, как в задании (например, препод это требует), то я бы сделал так:

C
1
2
3
4
5
6
int turn_bit_on(unsigned long* const pval, const unsigned int n)
{
    if( n > 31 ) { return 0; }
    *pval &= 1 << n;
    return 1;
}
0
easybudda
Модератор
Эксперт CЭксперт С++
10100 / 6009 / 1507
Регистрация: 25.07.2009
Сообщений: 11,398
21.08.2014, 11:49 9
Лучший ответ Сообщение было отмечено Nashorn как решение

Решение

Цитата Сообщение от Vtulhu Посмотреть сообщение
*pval &= 1 << n;
Это не то, чтобы нулевой бит не установит, оно ещё и остальные обнулит

Цитата Сообщение от Vtulhu Посмотреть сообщение
Не надо возвращать код ошибки через значение, это крайне плохой стиль программирования.
Это вполне нормальный стиль, при чём достаточно часто и с успехом использующийся.
Цитата Сообщение от Vtulhu Посмотреть сообщение
if( n > 31 ) { return 0; }
а вот это и в правду плохой стиль. Обычно принято возвращать 0, если операция завершилась успешно, или код ошибки, если она была (в общем случае -1, если подробности не нужны).
Другое дело, что этот подход чаще применяется, когда функция работает со внешними данными, которые сами по себе могут содержать ошибку, а то и вовсе быть недоступными. Когда речь идёт об установке флагов, неверное значение параметра - это скорее всего и в правду ошибка в программе...

Добавлено через 10 минут
Nashorn, есть, кстати, ещё подход - в заголовке errno.h объявлена глобальная переменная errno, значение которой можно устанавливать в функции и проверять сразу при выходе из неё.
1
Nashorn
0 / 0 / 0
Регистрация: 20.08.2014
Сообщений: 10
21.08.2014, 16:15  [ТС] 10
Цитата Сообщение от easybudda Посмотреть сообщение
Обычно принято возвращать 0, если операция завершилась успешно, или код ошибки, если она была
Сделаю себе пометку, спасибо.

Цитата Сообщение от easybudda Посмотреть сообщение
ещё подход
Не могли бы вы вкратце описать ситуации, когда использовать его будет удобнее?
0
Vtulhu
423 / 377 / 200
Регистрация: 12.08.2011
Сообщений: 1,610
21.08.2014, 16:47 11
Цитата Сообщение от easybudda Посмотреть сообщение
Это не то, чтобы нулевой бит не установит, оно ещё и остальные обнулит
Да, опечатался, конечно.

Цитата Сообщение от easybudda Посмотреть сообщение
а вот это и в правду плохой стиль. Обычно принято возвращать 0, если операция завершилась успешно
Я предполагал, что удобно будет проверять ифом возврат значения, типа true и false. Мне это кажется логичным.
0
easybudda
Модератор
Эксперт CЭксперт С++
10100 / 6009 / 1507
Регистрация: 25.07.2009
Сообщений: 11,398
21.08.2014, 17:44 12
Цитата Сообщение от Nashorn Посмотреть сообщение
Не могли бы вы вкратце описать ситуации, когда использовать его будет удобнее?
К примеру стандартная функция strtol(), переводящая строку в число типа long. В случае, если строка не содержит число, функция возвращает 0, при этом устанавливая errno в EINVAL, в случае, если число не помещается в тип long, возвращается соответственно LONG_MIN или LONG_MAX и errno устанавливается в ERANGE. Поскольку 0, LONG_MIN и LONG_MAX - в принципе допустимые значения, отловить ошибку можно проверив значение errno...
1
Nashorn
0 / 0 / 0
Регистрация: 20.08.2014
Сообщений: 10
21.08.2014, 18:29  [ТС] 13
easybudda, большое спасибо.
0
21.08.2014, 18:29
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.08.2014, 18:29

Программа должна заменять МА на КО но что то не так написал
Подскажите где ошибка? Программа должна заменять МА на КО но что то не так...

Что такое функция или функция под капотом
Собственно меня очень сильно интересует этот вопрос. Функция это указатель...

Функция дублирует ввод как и должна но добавляется "Мусор"
Функция дублирует ввод как и должна но пробавляются &quot;Мусор&quot; char...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru