LINUX.ORG.RU

А как на C решаются проблемы одной переменной на несколько типов?

 


0

2

Возник вопрос. Можно ли в C использовать переменную произвольного типа в зависимости от контекста? Пример кода.

void test(int type) {

 if (type==1) {
  char *data = "Hello world";
 }
 if (type==2) {
  int data = 123;
 }
// ...
}

Экспериментировал с void. Работает лишь наполовину

void test(int type) {

 void *data;
 if (type==1) {
  char *data = "Hello world";
  printf("Data: %s\n",data); // Тут data - правильные
 }
 if (type==2) {
  int data = 123;
 }
// ...
 printf("Data: %s\n",data); // А вот тут data - поломанные
}

Первый printf выводит как положено, Hello world.

А вот второй printf вне условия, выводит �ÐUH��H�� H�}�H�

Благодарю.

★★★★★
Ответ на: комментарий от u-235

Он и так у меня в руках. Уже много лет. Граблей не ощущаю. Сейчас речь о питоне и питоняшках, которые напридумывали себе табу и компьютер у них работает по божественным законам.

hibou ★★★★★
()
Ответ на: комментарий от hibou

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

кто мешает-то? почему это надо вводить прям в какой-нить язык?

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от hibou

Да нет, вводить конечно не надо. Но я не уверен, что такие конструкции как строки тоже прям вот надо вводить в язык. Тянет на библиотеку может быть.

А они введены.
struct позволяет создать объект любой сложности (в т.ч. какой-нибудь строковый тип).

anonymous
()
Ответ на: комментарий от hibou

Зависит от языка, если он прикладной - то можно и даже нужно ввести, если системный широкого профиля, - то не нужно, то есть в с++ сделано верно, То бишь это библиотечные типы, причем разные. Бери какой нужно и пиши себе.

alysnix ★★★
()
Ответ на: комментарий от alysnix

У меня на сях где-то была реализация черно-красного дерева. Писал когда-то давно по приколу. Я конечно в своем уме и не буду средствами языка писать: число + дерево. Но и как бы язык мне это не запретит. И это правильно.

Моя претензия к питону в том, что он:

  1. Скрывает как на самом деле работает машина.

  2. Вводит искусственные ограничения. Видимо, чтобы дети не убились.

Ну так вот. И вот это всё рождает программистов, которые ничего не понимают, что на самом деле происходит. И почему некоторые операции бессмысленны, они не запрещены. Они именно бессмысленны. Получается, что в голове есть список табу, которые нельзя делать, потому что оно божественно и бог тебя упаси оспаривать.

Короче, мне не нравится питон.

hibou ★★★★★
()
Ответ на: комментарий от alysnix

и мне не нравится питон. питон это скриптуха, с неправильным синтаксисом на отступах.

А мне табы не нравятся.
Многие редакторы с ними правильно и работать не могут.
Исходный текст то на экране показывается с учётом количества символов отведённых табам.
Так вот, когда пытаешься что-то изменить в промежутке между табом и следующим символом, то не все текстовые редакторы умеют правильно это сделать.
Речь о количестве пробелов между табом и следующим значащим символом.
Если скажем хочу «подтянуть» текст на несколько символов, то таб должен быть убран и вместо него добавлено нужно количество пробелов.
Так вот не все текстовые редакторы умеют такую «мелочь» правильно сделать.
Уж молчу когда производится работа с блоком текста.
Правда обычно в редакторах имеется настройка на использование табов или замены их пробелами.

anonymous
()

Это зависит от типа переменной. Например, ты можешь преобразовывать переменную bool к любому типу, но не сможешь преобразовать long long ни к какому другому.

int(x) + long(y) = long(x + y)
char(z) + bool(t) = char(z + t)

и т.д.

Всё зависит от размера переменной - меньший тип переменной может преобразовать к большему, но не наоборот.

C не различает типы переменных - всё числа. Пример:

#include <stdio.h>

int main () {
    int val = 67;
    printf("%d %c\n", val, val);
    return 0;
}
iskander9908
()
Ответ на: комментарий от hibou

Средства программирования не должны мне в этом мешать.

А вот это очень сложный вопрос. Куда сложнее чем может показаться.

Если говорить про суровую коммерческую разработку, а не для науки, души или искусства - то есть же очень большая проблема. Есть такие люди - 321сты, как много их среди программистов. Да, все этим грешат. Поэтому, если это бездуховный наемный труд, то надо приставлять к рабу другого негра с плеткой, который будет стегать по мягкому месту за определенные вещи. Вот компилятор всякой джавы и питона, и раста и есть такой негр. Раст против 321стов, короче.

James_Holden ★★★★★
()
Ответ на: комментарий от iskander9908

Всё зависит от размера переменной - меньший тип переменной может преобразовать к большему, но не наоборот.

Неправда.

C не различает типы переменных - всё числа. Пример

Тоже неправда. То что происходит в примере - прямое следствие ABI, и вообще говоря - UB.

bugfixer ★★★★★
()
Ответ на: комментарий от iskander9908

Тут вот осторожней надо. printf %c, конечно сделает что ты хочешь, напечатает символ. Но для компилятора val объявлена как инт. Он и положит инт на стек для функции принтф. А вот функция заберет со стека чар. Другой размер совсем.

Здесь правда одно но. Аргументы первые 4 передаются через регистры.Именно это спасет программу от краха. Если бы твой %с был 5-м и далее… то ты бы испортил стек. С дальнейшими трудно отследимыми последствиями.

hibou ★★★★★
()
Ответ на: комментарий от hibou

А вот функция заберет со стека чар. Другой размер совсем.

И вот после этого, люди спрашивают, а почему в C++ всю дорогу вместо printf использовались потоки. Ну совсем непонятно же зачем, ага

James_Holden ★★★★★
()
Ответ на: комментарий от bugfixer

С современными многобайтовыми кодировками конечно вообще не все так однозначно. Это действительно уже АБИ и зависит от реализации наверное.

Главный посыл тут надо быть осторожнее. Не делать того, что может где-то сломаться.

hibou ★★★★★
()
Ответ на: комментарий от bugfixer

Неправда.

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

Тоже неправда. То что происходит в примере - прямое следствие ABI, и вообще говоря - UB.

Всё - биты, множество битов образуют числа. Читая переменную val, программа читает первые восемь байт, если мы используем тип char, аналогично и с другими типами - читаются только младшие биты соответствующего типа (они могут как совпадать с типом переменной, так и нет)

iskander9908
()
Последнее исправление: iskander9908 (всего исправлений: 1)