Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
 Аватар для Wi0M
395 / 123 / 48
Регистрация: 26.10.2013
Сообщений: 734

Приведение типов и switch

05.05.2019, 14:44. Показов 1893. Ответов 43
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем привет. Начал изучать C и возникли некоторые трудности, ответы на которые я либо не нашел либо не понял.

Приведение типов.
Почему я не могу просто выполнить int(value), где value например строка содержащая цифру 5 и получить 5 в int?

C
1
2
3
4
5
6
7
8
9
int main() {
    char not_num[] = "123";
    int num;
 
    num = (int)not_num[0];
    printf("%d\n", num);
 
    return 0;
}
Надо делать только так и никак иначе?

C
1
2
3
4
5
6
7
8
9
int main() {
    char not_num[] = "123";
    int num;
 
    num = not_num[0] - '0';
    printf("%d\n", num);
 
    return 0;
}
Оператор switch.
В уроках написано что case может принимать группированные параметры типо "case 1, 2, 4:", но у меня так не заработало, интересно почему? Зато заработало вот так

C
1
2
3
4
5
6
7
8
switch (3){
        case 1:
            printf("1\n");
        case (3, 4):
            printf("2, 3\n");
        default:
            printf("не обязательно\n");
    }
Только теперь если аргумент switch 3 то второй case не будет выполнен, а если switch 4, то будет, почему так происходит?
Буду очень рад если вы мне поможете с этими вопросами.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
05.05.2019, 14:44
Ответы с готовыми решениями:

Объясните, как в примере работает приведение типов
Вот такой пример: #include <stdio.h> #include <pthread.h> void * any_func (void * arg) { int a = *(int *) arg; a++; ...

Не требуется приведение типов при умножении типов Byte
Читал тут книгу(Г. Шилдт, "Полный справочник по C#"), и нашел такое (ст. 77) Поскольку при умножении, например, 2 чисел типа byte,...

Приведение типов сырых типов
class Gen<T> { T ob Gen(T o) { ob=o; } T getob(){ return ob; } public class RawDemo {

43
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
05.05.2019, 15:53
Студворк — интернет-сервис помощи студентам
Wi0M, по вашему профилю я понял, что вы специалист по Питону. И это не такая уж простая работа, изучать похожий язык. Мой опыт сводится к изучению JavaScript & PHP после неплохого владения Си(С++). И хоть мне и прочили легкий и безболезненный вход, намучился я изрядно. (мучения еще не закончены).
Мои выводы:
- Изучение ПОХОЖЕГО языка не так просто, как кажется.
- Имеет смысл все забыть и начинать как бы с нуля (что тоже не просто, легко забыть, что именно надо подвергнуть забыванию)
- Не ругаться на этот другой язык. Просто понять, что он - другой.
И желаю вам удачи!
1
85 / 61 / 29
Регистрация: 15.05.2013
Сообщений: 189
05.05.2019, 16:05
Байт, и Evg, уже разъяснили что и как, я надеюсь.
Я просто хочу подчеркнуть (и возможно прояснить), что switch (n) -- это выбор, который надо принять здесь и сейчас.
n -- может быть чем угодно, и все что я запомню -- это его значение. И это значение должно быть целочисленным.
любой последующий case, фактически, выполняет сравнение, (мой случай) == n
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,331
05.05.2019, 17:55
Цитата Сообщение от Wi0M Посмотреть сообщение
В уроках написано что case может принимать группированные параметры типо "case 1, 2, 4:"
Нет, не может.

Цитата Сообщение от Wi0M Посмотреть сообщение
Зато заработало вот так
C++
1
  case (3, 4):
Нет, не заработало. Выражение (3, 4) использует оператор "запятая" и дает результат 4, как вам уже объяснили выше. Однако значение в case должно быть константным выражением, а оператор "запятая" в языке С не порождает константного выражения.
0
85 / 61 / 29
Регистрация: 15.05.2013
Сообщений: 189
05.05.2019, 18:01
Я думаю надо посмотреть на задачу с другой стороны.
Байт уже рассказал что значит 3, 4 и (3,4)
switch(n) -- немного другая история. n может быть чем угодно, возвращающем целое число.
т.е. вместо n можно написать все что хочется, но результатом n должно быть целое число, иначе switch работать не будет.
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
05.05.2019, 18:06
TheCalligrapher, Однако, у ТС выражение "case (3,4):" не вызвало синтаксической ошибки и сработало... Именно так, как и предполагалось, как "case 4:"
И ваши соображения, хотя и верны, но требуют более конкретного анализа ситуации.
Впрочем, все это было уже проанализировано в предыдущих сообщениях этого топика.
Имхо, транслятор не так глуп, чтобы не суметь преобразовать "3,4" в просто "4". Возможно, он и "case sqrt(x), printf("tra-ta-ta"), 8-4 :" преобразует в "case 4:" Не знаю, не проверял. Интересующиеся могут попробовать.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,331
05.05.2019, 18:12
Цитата Сообщение от shadowmaan Посмотреть сообщение
Байт уже рассказал что значит 3, 4 и (3,4)
Не до конца. Байт рассказал о значении этого выражения, а тут в первую очередь важна "категория" результата с точки зрения его константности. Еще раз: результатом (3,4) будет просто 4, но при этом (3,4) отличается от просто 4 тем, что просто 4 - это целочисленное константное выражение, а (3,4) - нет. Поэтому код case (3,4): не будет компилироваться вообще.

Добавлено через 2 минуты
Цитата Сообщение от Байт Посмотреть сообщение
Однако, у ТС выражение "case (3,4):" не вызвало синтаксической ошибки и сработало... Именно так, как и предполагалось, как "case 4:"
Ну, как несложно догадаться, несмотря на то, что темой этого форума является язык С, ТС компилирует свой код как С++ (где оператор "запятая" допустим в константных выражениях начиная с С++11), но нам об этом не рассказывает.
1
85 / 61 / 29
Регистрация: 15.05.2013
Сообщений: 189
05.05.2019, 18:17
если синтаксически все верно, то n будет целым числом, и это все. оно не может быть чем-то еще. это определено семантикой (смыслом).
более строго, n, всегда будет значением, равным значению некоторого целого числа, при условии корректного синтаксиса.
поправьте, если я не прав в формулировках.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,331
05.05.2019, 18:21
Цитата Сообщение от shadowmaan Посмотреть сообщение
если синтаксически все верно, то n будет целым числом, и это все. оно не может быть чем-то еще. это определено семантикой (смыслом).
более строго, n, всегда будет значением, равным значению некоторого целого числа, при условии корректного синтаксиса.
Что именно вы хотите сказать - не ясно. Но все равно не верно. Вот здесь синтаксис совершенно корректен

C
1
2
3
4
double d = 0;
switch (d)
{
}
но код корректным не является - значение типа double не может использоваться в switch.
0
85 / 61 / 29
Регистрация: 15.05.2013
Сообщений: 189
05.05.2019, 18:24
не ясно. Но все равно не верно
звучит, как-то противоречиво.
d не является целым числом.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,331
05.05.2019, 18:26
Цитата Сообщение от shadowmaan Посмотреть сообщение
d не является целым числом.
Совершенно верно, не является. Код ошибочен. Но эта ошибка не является ошибкой синтаксиса. С синтаксисом в этом коде все в полном порядке.

Поэтому мне не ясно ваше утверждение "если синтаксически все верно, то n будет целым числом". Как первая часть этого утверждения обуславливает вторую? Зачем вы напираете на слово "синтаксически"?
1
85 / 61 / 29
Регистрация: 15.05.2013
Сообщений: 189
05.05.2019, 18:46
согласен, утверждение не верно. Все что я хотел сказать -- это n есть целое число, каким бы образом оно к нему не приводилось. простите за не однозначность (мою глупость).

Добавлено через 15 минут
это n есть целое число
поправка: n должно быть
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
05.05.2019, 22:30
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
но код корректным не является - значение типа double не может использоваться в switch.
А он и не будет (дубль) использоваться. Вы об автоматическом приведении типов слыхали?
Да, приведенный вами в посте 28 код вполне нелеп. Но он и синтаксически и семантически совершенно корректен. То есть корректен по всем параметрам и будет прекрасно выполняться. Он эквивалентен
C
1
2
3
4
double d = 0;
switch ((int)d)
{
}
И ничего более, никакого лукавства.
Аналог
C
1
2
double d = 0;
int n = d; // Так  можно?
Подобные штуки я использовал в своей серьезной практике неоднократно. Хотя бы для грамотного округления, или для выяснения положения планеты в одном из знаков зодиака. И ничего, живой до сих пор

Добавлено через 4 минуты
Если хотите, вот пример.
C
1
2
3
4
5
6
double lon = PosOfSun(double jd);  // Положение Солнца
switch (lon) {
 case 0: printf("Овен"); break;
 case 1: printf("Телок"); break;
 ....
}
Добавлено через 3 минуты

Не по теме:

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

0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,331
06.05.2019, 01:33
Цитата Сообщение от Байт Посмотреть сообщение
А он и не будет (дубль) использоваться. Вы об автоматическом приведении типов слыхали?
При чем здесь "автоматическое приведение типов"? Неявное приведение типов в языке С выполняется тогда, когда оно должно выполняться по правилам языка С. В switch неявное приведение типов НЕ выполняется. Значение сразу должно иметь целочисленный тип. Попытка указать значение типа double - ошибка.

Цитата Сообщение от Байт Посмотреть сообщение
Да, приведенный вами в посте 28 код вполне нелеп. Но он и синтаксически и семантически совершенно корректен. То есть корректен по всем параметрам и будет прекрасно выполняться. Он эквивалентен
C
1
2
3
4
double d = 0;
switch ((int)d)
{
}
И ничего более, никакого лукавства.
Ни в коем случае. Откуда вы такое взяли? Код с switch(d) грубо некорректен и не будет компилироваться.

И таких примеров - множество. Ни о каком double не может быть и речи ни в адресной арифметике, ни в операторах сдвига, ни в логических операторах и т.д. И ваши мечты об "автоматическом приведении типов" здесь никак не помогут. Не будет никакого "автоматического приведения типов". Код сразу некорректен.

Я никогда не был приверженцем философии "просто попробуйте", но в данном случае, чисто на всякий случай для начала вы бы могли просто попробовать. И дальше уже разбираться оттуда.

Цитата Сообщение от Байт Посмотреть сообщение
Аналог
C
1
2
double d = 0;
int n = d; // Так  можно?
Даже близко не аналог. Неявные преобразования при инициализация в С выполняется по тем же правилам, что и в присваивании. switch же в C работает по правилам switch. Ничего общего в плане неявных преобразований они не имеют.

Цитата Сообщение от Байт Посмотреть сообщение
Подобные штуки я использовал в своей серьезной практике неоднократно.
Вы что-то выдумываете.

Цитата Сообщение от Байт Посмотреть сообщение
Хотя бы для грамотного округления, или для выяснения положения планеты в одном из знаков зодиака. И ничего, живой до сих пор

Если хотите, вот пример.
C
1
2
3
4
5
6
double lon = PosOfSun(double jd);  // Положение Солнца
switch (lon) {
 case 0: printf("Овен"); break;
 case 1: printf("Телок"); break;
 ....
}
Вы что-то выдумываете. Сразу же ошибка компиляции - double в качестве аргумента switch.

Еще раз: я никогда не был приверженцем философии "просто попробуйте", но в данном случае, чисто на всякий случай вы бы могли сначала просто попробовать.
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,981
06.05.2019, 02:17
Цитата Сообщение от Байт Посмотреть сообщение
Вы об автоматическом приведении типов слыхали?
При всём уважении, приведение типов здесь не работает. Метки в switch должны быть константными выражениями и ничем иным. Честно говоря, удивлялся, как у ТС
Цитата Сообщение от Wi0M Посмотреть сообщение
case (3, 4):
отработало (оператор "запятая" вычисляет свои аргументы, будь они хоть константами, хоть переменными, приведёнными к другому типу), пока не прочитал
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
ТС компилирует свой код как С++ (где оператор "запятая" допустим в константных выражениях начиная с С++11)
Не знал. Единственный момент в дополнение к примеру Evg, можно значения диапазоном задавать:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
 
int main(void) {
    int x = 4;
 
    switch ( x ) {
        case 1:
            printf("one\n");
            break;
        case 2 ... 5:
            printf("from two to five\n");
            break;
        default:
            printf("%d\n", x);
            break;
    }
 
    return 0;
}
Code
1
2
3
4
[andrew@easybook other]$ gcc -Wall test_case.c 
[andrew@easybook other]$ ./a.out 
from two to five
[andrew@easybook other]$
1
 Аватар для Wi0M
395 / 123 / 48
Регистрация: 26.10.2013
Сообщений: 734
06.05.2019, 08:17  [ТС]
Да чет как то так получилось странно. Поставил на чистой машине gcc и попробовал скомпилировать case (2,3) и не вышло.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,331
06.05.2019, 08:21
Цитата Сообщение от Wi0M Посмотреть сообщение
Да чет как то так получилось странно. Поставил на чистой машине gcc и попробовал скомпилировать case (2,3) и не вышло.
Вы хоть читали, что написано выше? Еще раз: case (2,3): допустимо только в С++ и только начиная с C++11.

А вы что пробовали?
0
 Аватар для Wi0M
395 / 123 / 48
Регистрация: 26.10.2013
Сообщений: 734
06.05.2019, 08:24  [ТС]
TheCalligrapher, да все я читал. только что мне ваше чтение если у меня все компилируется? вы меня тоже читать то не забывайте) ну и теперь уже совсем другой вопрос. что у меня за каша творится, если я могу без наказано делать так? (речь все еще про case (2,3), если что)
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,331
06.05.2019, 08:28
Цитата Сообщение от Wi0M Посмотреть сообщение
Поставил на чистой машине gcc и попробовал скомпилировать case (2,3) и не вышло.
Цитата Сообщение от Wi0M Посмотреть сообщение
только что мне ваше чтение если у меня все компилируется?
Цитата Сообщение от Wi0M Посмотреть сообщение
вы меня тоже читать то не забывайте)
Как же мне вас читать, если у вас в одном предложении "скомпилировать не вышло", а в следующем "у меня все компилируется". Так "компилируется" или "не вышло"?
0
 Аватар для Wi0M
395 / 123 / 48
Регистрация: 26.10.2013
Сообщений: 734
06.05.2019, 08:30  [ТС]
TheCalligrapher, И да и нет) На маке компилируется, на дебиане нет. На маке стоит и gcc и g++, на дебиане только gcc.

Добавлено через 42 секунды
самое удивительное что для компиляции на маке используется gcc
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
13214 / 6847 / 1825
Регистрация: 18.10.2014
Сообщений: 17,331
06.05.2019, 08:32
Цитата Сообщение от Wi0M Посмотреть сообщение
TheCalligrapher, И да и нет) На маке компилируется, на дебиане нет. На маке стоит и gcc и g++, на дебиане только gcc.
самое удивительное что для компиляции на маке используется gcc
Что значит "только gcc"? Именно gcc и компилирует все языки, выбирая язык по расширению файла. g++ - это не более чем малюсенькая "вызывалка" для gcc. Необязательная. Так стоит у вас g++ или нет - значения не имеет.

Как называется компилируемый файл? Какой язык программирования в выбрали в командной строке gcc?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.05.2019, 08:32

Приведение типов
Всем привет) Есть массив int a = {2 ,4 ,5 ,6 ,256} Числа располагаются по байтам в памяти так: 1б 2б 3б 4б 2 0 0 0 4 ...

Приведение типов
В базе хранится дата в виде: 2016-03-22 08:40:11 Помогите привести в вид 2016/03/22 любыми способами в PHP преобразовании или при MySQL...

Приведение типов
Добрый вечер уважаемые форумчане, подскажите, как вместо true и false сделать 1 и 0. boolean p, q; ...

Приведение типов
Добрый день! Работаю в IDE Netbeens (но думаю не суть). Есть интерфейс bapICredentials: interface bapICredentials extends...

Приведение типов
Доброго времени суток. С MS SQL Server 2005 начал работать недавно. Подскажите, пожалуйста, что не так в запросе и как это можно исправить....


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Ноутбук Альфария
kumehtar 24.08.2026
Встретился тут в сети ноутбук Альфария, примарха Альфа-Легиона. Хотя возможно, это ноутбук Омегона, разумеется. Ну как вам?
Мастера простых решений
DevAlt 23.08.2026
В сишарп стэках winforms, да и wpf существует сложная система связывания источниках данных и элементов формы(текстовые поля и метки), опирается все это на технологию событий и мета. . .
Цена ошибки
DevAlt 23.08.2026
Человек я беспокойный и потому заинтересовался OCaml, в чате форсили функторы модулей как суперфичу. Пытаясь отдуплить концепт, наткнулся на тутор с простым примером. А главный принцип обучения от. . .
Сегодня суббота, 22.08.2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины.
zorxor 22.08.2026
Сегодня суббота, 22. 08. 2026 at 16:41, и я вновь нахожусь на той стороне, за экраном машины. Кто Я, откуда Я пришел и куда Я иду? Эти вопросы не оставляют меня ни на секунду. Жизнь на планете Земля. . .
Жизня: рисунок укладки багажа, сделанный клодом
anaschu 21.08.2026
Сделал 15 снимков, он по снимкам сделал схему.
Был там один разговор по поводу свободы в материальном мире.
kumehtar 19.08.2026
Суть: рассматривается живое существо, оказавшееся внутри довольно странной системы (этого мира) и пытающееся обустроить в ней свой кусок пространства. Жизнь действительно предъявляет каждому. . .
Когда логика программы не спасает от человеческих ошибок
Maks 18.08.2026
В последнее время всё чаще и чаще сталкиваюсь с таким явлением, как абсолютная невнимательность (или глупость) пользователей. Проявляется это чаще всего на работе в коллективе. Допустим, человек с. . .
Лето уходит
kumehtar 17.08.2026
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru