Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.64/25: Рейтинг темы: голосов - 25, средняя оценка - 4.64
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164

Изменить знаковость переменной

26.06.2020, 13:54. Показов 6273. Ответов 80
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте!
Существует ли возможность в языке Си изменять знаковость переменной? То есть, допустим нужно узнать является ли значение некоторой переменной отрицательным числом, как в следующем примере:

C
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
 
typedef char Some_type; // Данная строчка может находится в другом модуле и
                        // содержать описание произвольного типа.
Some_type some_var;
 
int main(void)
{
    return some_var < 0;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
26.06.2020, 13:54
Ответы с готовыми решениями:

Изменить имя переменной в зависимости от данных переменной
Задача такова: пользователь вводит сроку и нужно создать объект с именем, как в строке. Пробовал сам, но одни ошибки. Подскажите,...

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

изменить значение переменной
Есть file.php, в нем есть переменная $kku = &quot;156666&quot;; Есть страница, smenap.php &lt;form action=\&quot;\form.php&quot;&gt; ...

80
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
28.06.2020, 17:42  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от ValeryS Посмотреть сообщение
сегодня используем short завтра int а переписывать все лень
Ну уж не лень. Просто хочется автоматизировать такие вещи. Сам по себе язык программирования одно из таких средств автоматизации. Мы же используем компиляторы не потому что нам лень писать в машинных кода, а для того чтобы наш труд был более эффективным.

Добавлено через 3 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
могу предложить union
К сожалению это не поможет.

Цитата Сообщение от ValeryS Посмотреть сообщение
на большее ума не хватает
Лично я предложил макрос MODIFY_INT_TYPE. Вы его кстати смотрели? Мне кажется проанализировать его это верный способ меня понять.

Добавлено через 15 минут
Вот тот пример с небольшими исправлениями:
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
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
 
#define MODIFY_INT_TYPE(int_obj, signed_or_unsigned) (\
    sizeof(int_obj) == sizeof(char) ? (signed_or_unsigned char) int_obj : \
    sizeof(int_obj) == sizeof(short) ? (signed_or_unsigned short) int_obj : \
    sizeof(int_obj) == sizeof(int) ? (signed_or_unsigned int) int_obj : \
    sizeof(int_obj) == sizeof(long) ? (signed_or_unsigned long) int_obj : \
    (signed_or_unsigned long long) int_obj)
 
#define is_negative(var) (MODIFY_INT_TYPE(var, signed) < 0)
 
unsigned char unsigned_char = UCHAR_MAX;
unsigned short unsigned_short = USHRT_MAX;
unsigned int unsigned_int = UINT_MAX;
 
char str_positive[] = "positive";
char str_negative[] = "negative";
 
int main(void)
{
    printf("unsigned_char is %s\nunsigned_short is %s\nunsigned_int is %s\n", 
        is_negative(unsigned_char) ? str_negative : str_positive,
        is_negative(unsigned_short) ? str_negative : str_positive,
        is_negative(unsigned_int) ? str_negative : str_positive);
    return EXIT_SUCCESS;
}
0
658 / 411 / 76
Регистрация: 21.09.2008
Сообщений: 1,411
29.06.2020, 05:20
"Меня терзают смутные сомнения..." (с) Ильф и Петров.
... что автор темы не до конца понимает опасность таких сравнений (знаковых и беззнаковых типов). Я столкнулся с этим давным-давно, когда проверял работу написанной на ассемблере PDP-11 другим разработчиком подпрограммы вывода десятичного числа из внутреннего представления. При пересечении диапазона (в терминах машинного кода - переполнении, когда при сложении двух положительных чисел получается отрицательное число - вот ведь парадокс для неискушенных?) происходил сбой, и вместо правильного числа выводилось неверное представление. Оказалось, что надо было заменить команду перехода при получении отрицательного результата (BMI) на команду перехода при отсутствии переноса (BCC/BHIS), и этот сбой был устранён. Даже метка перехода осталась прежней. Использовался весь диапазон отображения положительных чисел.
Современные компиляторы Си/С++ предупреждают о сравнении знаковых и беззнаковых типов. Их разработчики настолько глупые? Вовсе нет.
Неужели так сильно хочется набить шишек граблями?
1
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
29.06.2020, 06:13  [ТС]
sharpey, спасибо за ваше мнение! Но к сожалению оно тоже не впопад. Я клянусь что это не тот случай, но я не знаю как ясно это доказать. Я думаю что если вы внимательно почитаете последние мои сообщения вы это поймете. Вы опять же как и другие говорите про числа. Повторяю, что в представлении программиста там может быть вообще не число, а значит это уже не тот случай.
Цитата Сообщение от sharpey Посмотреть сообщение
Современные компиляторы Си/С++ предупреждают о сравнении знаковых и беззнаковых типов. Их разработчики настолько глупые?
В моем случае не возникает и не должно возникать никаких предупреждений. Это здесь тоже совершено не при чем.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
29.06.2020, 08:12
Цитата Сообщение от asbvic Посмотреть сообщение
Вот тот пример с небольшими исправлениями:
я так и не понял, как же этот пример решает задачу
Цитата Сообщение от asbvic Посмотреть сообщение
что тип может поменяться на этапе разработки,
где тут замены типа?
как все это можно применить на практике?
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
29.06.2020, 09:49  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
я так и не понял, как же этот пример решает задачу
Задачу можно было сформулировать следующим образом: нужно при приведении типа менять не просто сам тип, а менять только одну из его составляющих - знаковость (signed и unsigned), а размер типа оставлять прежним. Дак вот макрос MODIFY_INT_TYPE как раз это и делает. Вы с этим не согласны?

Добавлено через 29 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
где тут замены типа?
как все это можно применить на практике?
А под "тут" вы что именно понимаете? Приведенные листинги? Дак в них этого явно и не видно. Замена типа может произойти на этапе разработки. Допустим вы изначально определили тип при помощи typedef, но в дальнейшем вам допустим не хватило размера данного типа и вы решили его увеличить (или по каким-то причинам наоборот уменьшить). Такое ведь может быть? И где-то в коде у вас может происходить такое приведение типа в выражениях, при котором размер этого типа не меняется, а меняется только его "знаковость" (не знаю как правильно назвать). И если вы вдруг думаете что такого не может быть, то посмотрите в свои исходники, вы обязательно это встретите (речь естественно именно про язык Си). В таком случае вам придется переписать эти места.

Да даже посмотрите на пример из самого вопроса. Из-за того что в одном компиляторе char является знаковым (signed char), а в другом наоборот, результат программы может быть разным. И как быть? Вы конечно же скажите: "Дак поставь оператор приведения типа (signed char)". А если через какое-то время тип Some_type будет переопределен с char на wchar_t. Получается нужно будет переписывать все подобные места. Хотя на самом деле вам просто по смыслу нужно было указать эту самую "знаковость", на трогая размер типа. Например, с помощью этого макроса это и можно сделать (т.е. как бы автоматизировать).

Да и дело даже не в том чтобы придумать такой инструмент автоматизации. Просто чисто логически такое должно присутствовать. Но этого нет.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
29.06.2020, 11:15
Цитата Сообщение от asbvic Посмотреть сообщение
Да даже посмотрите на пример из самого вопроса. Из-за того что в одном компиляторе char является знаковым (signed char), а в другом наоборот,
насколько сталкивался, в компиляторах с которыми работал, всегда есть настройка чем считать char- unsigned char или signed char
Цитата Сообщение от asbvic Посмотреть сообщение
Some_type будет переопределен с char на wchar_t.
а ниче что у них размеры разные?
Цитата Сообщение от asbvic Посмотреть сообщение
Например, с помощью этого макроса это и можно сделать (т.е. как бы автоматизировать).
а простое
C
1
typedef  int MyType ;
C
1
#define MyType int
уже не подходит?
Цитата Сообщение от asbvic Посмотреть сообщение
Просто чисто логически такое должно присутствовать. Но этого нет.
А может это никому не нужно ? за полвека существования языка, насколько знаю, таких вопросов не возникало

Добавлено через 3 минуты
Цитата Сообщение от asbvic Посмотреть сообщение
нужно при приведении типа менять не просто сам тип, а менять только одну из его составляющих - знаковость (signed и unsigned),
пойми это разные типы
приведение к char переменной int
это тоже самое что приведение к signed переменной unsigned
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
29.06.2020, 11:25  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
насколько сталкивался, в компиляторах с которыми работал, всегда есть настройка чем считать char- unsigned char или signed char
А настройки в исходнике программы находятся?

Цитата Сообщение от ValeryS Посмотреть сообщение
а ниче что у них размеры разные?
Дак именно поэтому этот пример и приведен. Я уже не знаю как объяснять.

Цитата Сообщение от ValeryS Посмотреть сообщение
а простое
C
1
typedef  int MyType ;
C
1
#define MyType int
уже не подходит?
Вроде подходит. Но почему-то многие используют именно typedef в данном случае (мы же все случаи должны охватить).

Цитата Сообщение от ValeryS Посмотреть сообщение
А может это никому не нужно ?
За всех вы знать не можете. Вот дворнику например скорее всего не нужно.

Добавлено через 5 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
пойми это разные типы
приведение к char переменной int
это тоже самое что приведение к signed переменной unsigned
А я где-то говорил что такие типы будут одинаковые? Я только говорю, что char и int могут быть разных размеров, а вот signed и unsigned будут равны. Вы согласны? Вот в чем разница между двумя этими приведениями типов.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
29.06.2020, 11:35
Цитата Сообщение от asbvic Посмотреть сообщение
а вот signed и unsigned будут равны. Вы согласны?
нет
пока не посмотрю стандарт,может где-то, когда-то и не равны
Цитата Сообщение от asbvic Посмотреть сообщение
За всех вы знать не можете.
а я и не за всех если этого нет в стандарте значит не кому не нужно

Добавлено через 3 минуты
Цитата Сообщение от asbvic Посмотреть сообщение
Вот в чем разница между двумя этими приведениями типов.
нет никакой разницы
(un)signed short =0xFFFF;
или 65535 или -1
что это если не потеря точности?
та же что и при приведении int к char
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
29.06.2020, 12:15  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
что это если не потеря точности?
Какая еще потеря точности? Потерей точности называется потеря информации. Тут-то где она потерялась?

Добавлено через 40 секунд
Вот как раз при переводе с int в char происходит потеря информации (когда они разных размеров).

Добавлено через 1 минуту
Цитата Сообщение от ValeryS Посмотреть сообщение
если этого нет в стандарте значит не кому не нужно
Надеюсь это шутка.

Добавлено через 4 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
нет
пока не посмотрю стандарт,может где-то, когда-то и не равны
Вот что сказано в стандарте на этот счет:
For each of the signed integer types, there is a corresponding (but different) unsigned integer type (designated with the keyword unsigned) that uses the same amount of storage (including sign information) and has the same alignment requirements.
Добавлено через 55 секунд
Ключевые слова:
Цитата Сообщение от asbvic Посмотреть сообщение
the same amount of storage (including sign information)
Добавлено через 9 минут
Только сейчас в стандарте увидел термин "signedness" и Google-переводчик перевел его как "знаковость". Проверьте.

Добавлено через 13 минут
И на Википедии есть целая статья про этот термин: https://en.wikipedia.org/wiki/Signedness
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
29.06.2020, 12:18
Цитата Сообщение от asbvic Посмотреть сообщение
Какая еще потеря точности? Потерей точности называется потеря информации.
-1 очень похожи на 65535?
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
29.06.2020, 14:44  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
-1 очень похожи на 65535?
Для вас нет. А вот для машины эта абсолютно равные вещи (т.е. информация не теряется).

Добавлено через 2 часа 22 минуты
Изменение знаковости при приведении типа (с сохранение размера):
C
1
2
3
4
5
6
7
8
9
#define CONVERT_SIGNEDNESS(signedness, integer) (\
    sizeof(integer) == sizeof(char) ? (signedness char) integer : \
    sizeof(integer) == sizeof(short) ? (signedness short) integer : \
    sizeof(integer) == sizeof(int) ? (signedness int) integer : \
    sizeof(integer) == sizeof(long) ? (signedness long) integer : \
    (signedness long long) integer)
 
#define SIGNED(integer) CONVERT_SIGNEDNESS(signed, integer)
#define UNSIGNED(integer) CONVERT_SIGNEDNESS(unsigned, integer)
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
29.06.2020, 16:07
Цитата Сообщение от asbvic Посмотреть сообщение
А вот для машины эта абсолютно равные вещи
мне плевать на машину, я работаю с человеком
вот так и возникают "проблемы 2000"

Добавлено через 4 минуты
Цитата Сообщение от asbvic Посмотреть сообщение
Изменение знаковости при приведении типа (с сохранение размера):
еще раз спрошу
где в реальной программе можно использовать сей макрос?
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
30.06.2020, 06:47  [ТС]
Цитата Сообщение от ValeryS Посмотреть сообщение
еще раз спрошу
где в реальной программе можно использовать сей макрос?
Но ведь я уже все рассказал и повторил много-много раз. Если для вас это не убедительно или вы просто не поняли сказанного (но я больше не знаю как объяснить), то просто скажите себе что вам это не нужно, или что это вообще нечто малополезное или даже вредное (как вы выше написали). Ведь это может так и оказаться.

Добавлено через 23 минуты
ValeryS, вы кстати посмотрели свои исходники Си на наличие приведения типов без изменения размера типа (как я просил)?
0
658 / 411 / 76
Регистрация: 21.09.2008
Сообщений: 1,411
30.06.2020, 07:15
Цитата Сообщение от ValeryS Посмотреть сообщение
-1 очень похожи на 65535?
Можно я тоже "внесу свои 5 копеек"? Действительно, такое значение возможно для типа int в 16-битных ОС, в 32-битных ОС тип int будет уже 4-байтным и число -1 превратится в 429496729510.
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
30.06.2020, 07:39  [ТС]
Цитата Сообщение от sharpey Посмотреть сообщение
Можно я тоже "внесу свои 5 копеек"? Действительно, такое значение возможно для типа int в 16-битных ОС, в 32-битных ОС тип int будет уже 4-байтным и число -1 превратится в 429496729510.
С этим можно только согласится. Только к чему вы это написали? Тот пример ValeryS привел для того, чтобы якобы показать потерю точности. Ни в его ни в вашем случае точность не теряется. И вы снова говорите о числах, что мало связано с рассматриваемым.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
30.06.2020, 08:20
Цитата Сообщение от asbvic Посмотреть сообщение
Но ведь я уже все рассказал и повторил много-много раз.
не надо много рассказывать, можно показать реально один раз
только не надо приводить этот листинг с printf, я так и не понял что он делает, кроме того что печатает знаковое или беззнаковое
Цитата Сообщение от asbvic Посмотреть сообщение
вы кстати посмотрели свои исходники Си на наличие приведения типов без изменения размера типа
пересмотрел, очень редко используется, в основном как костыли,и это неплохо делается вручную

заводить как int возраст или счетчик это недосмотр программиста
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
30.06.2020, 08:42  [ТС]
ValeryS, есть такой реальный случай. В стандартной библиотеке есть функция clock, возвращающая счетчик времени. Результат функции определен как clock_t. Я видел что clock_t на разных системах определяется знаковым типом (например long). Теперь представьте, что вам нужно использовать в выражении результат этой функции как беззнаковый. Вы естественно прибегните к приведению типа - в данном случае (unsigned long). Но согласитесь, что в таком случае ваша программа перестанет корректно работать на системах где size_t определен как int. На самом деле вам же не нужно было менять размер типа, вы просто хотели изменить его знаковость. Но на деле вы изменили оба этих свойства. А с помощью этого макроса (или подобных ему решений) есть возможность преобразовать только знаковость, тем самым увеличить переносимость (автоматизировать процесс переписывания кода).

Добавлено через 12 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
пересмотрел, очень редко используется, в основном как костыли,и это неплохо делается вручную
Вот, как видите это подтверждение моих слов. Только в моих исходниках подобные случаи не выглядят как костыли (но это конечно же субъективно). Я вообще очень сильно стараюсь избегать костыли. И у меня таких мест весьма не мало (но все относительно).

Цитата Сообщение от ValeryS Посмотреть сообщение
заводить как int возраст или счетчик это недосмотр программиста
Вот как раз счетчик в стандартной библиотеке заведен как знаковый.
0
Модератор
Эксперт по электронике
8982 / 6749 / 921
Регистрация: 14.02.2011
Сообщений: 23,876
30.06.2020, 08:46
asbvic, противоречий не видишь
тип clock_t мы рассуждаем о нем

Цитата Сообщение от asbvic Посмотреть сообщение
В стандартной библиотеке есть функция clock, возвращающая счетчик времени. Результат функции определен как clock_t.
и вдруг
Цитата Сообщение от asbvic Посмотреть сообщение
. Но согласитесь, что в таком случае ваша программа перестанет корректно работать на системах где size_t определен как int.
а потом переходим на long, int.....
0
6 / 6 / 4
Регистрация: 14.01.2016
Сообщений: 164
30.06.2020, 08:51  [ТС]
ValeryS, ой, я извиняюсь. Конечно же под size_t я имел в виду clock_t. Теперь противоречия нет?
0
658 / 411 / 76
Регистрация: 21.09.2008
Сообщений: 1,411
30.06.2020, 09:22
Для сравнения определений типа clock_t глянул в заголовочные файлы FreeBSD (__int32_t), MinGW-9.2 (long), AVR-GCC 10.2 (unsigned long). Размерности соответствуют, а тип нет, ибо clock() должна возвращать -1 в случае ошибки.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.06.2020, 09:22

Изменить содержимое переменной
Есть переменяя fileWay - это пути к загруженным файлам на сервере разделенные символом &quot;;&quot; тегом перевода строки пример: ...

Изменить букву в переменной
Доброго всем здравия, программа выводит наиболее встречаемую букву в шифротексте, допустим -t-, это зашифрованная буква -e-, английского...

Изменить значение переменной
Помогите пожалуйста. Как сделать так чтобы значение переменной менялось. Переменная num это значение которое отвечает за количество статей...

Изменить значение переменной?
Вот есть у меня страничка index.php там есть вот такой код: PHP код: &lt;?php $file =...

Изменить значение переменной в функции
Возможно ли изменить значение переменной, передаваемой в функцию? Как-то так: void anyfunc(int a1) { //здесь прибавление на...


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Часы электронные
Uhbif79 12.08.2026
Выкладываю программу часов. Программа позволяет: 1. Использовать системное время и дату, 2. Есть возможность вводить время и дату вручную. 3. Реализованы 2 будильника: начало и конец рабочего дня. . . .
Часы с будильником на основе класса QLCDNumber
Uhbif79 12.08.2026
Всем добрый день, выкладываю программу часов с будильником на основе класса QLCDNumber. Здесь я пробовал самостоятельно создавал классы, впервые столкнулся с видимостью переменной одного класса из. . .
Установка MinGW GCC 16.2 и CMake
8Observer8 10.08.2026
VK Видео: https:/ / vkvideo. ru/ video-240781534_456239017 YouTube: eY5-5PyI9NM Текстовая версия
Неделя из жизни имитационной модели склада: мои кривые руки растут, откуда надо
anaschu 10.08.2026
Неделя из жизни имитационной модели склада: как я почти написал неправильную логику и что с этим делать Работаю сейчас над учебно-рабочим проектом: строю в AnyLogic имитационную модель процессов. . .
Калькулятор для расчета родства
russiannick 07.08.2026
1. Задача: Создать калькулятор для расчета родства. Родственных связей существует 8 ступеней, такие как: p - отец P - мать q - муж Q - жена b - брат B - сестра s - сын S - дочь
Мир по моей воле
kumehtar 07.08.2026
Когда-то кажется, что всё просто. Ты весь такой светлый. Причиняешь добро. Борешься за справедливость в этом тёмном мире. Потом начинаешь замечать одну неприятную вещь. Почти каждый хороший. . .
Кредитный калькулятор
Maks 05.08.2026
Решение задачи по прикладной информатике средствами 1С. Задача: Напишите приложение-калькулятор, которое помогает рассчитывать параметры кредита для аннуитетного и дифференцированного видов. . .
У нас сейчас поговорку "Опять 25" нужно переделать на "Опять +35".
kumehtar 04.08.2026
С ностальгией вспоминаю времена моего детства, когда у нас и правда +25 - была максимальная температура летом. Раньше +25 °C реально казались вершиной жары, когда можно было весь день пропадать на. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru