2012-03-18 2 views
3

Как программа/приложение знает, что данные в адресе памяти имеют определенный тип данных.Идентификация типа данных в памяти в C?

Например, предположим, что существует int a; и, если переменная a хранится по адресу 0x100. Где хранится информация о том, что она имеет тип int?

+0

См. Также [этот дубликат] (http://stackoverflow.com/questions/39206296/how-does-memory-determine-data-type-of-variable), который также привлек некоторые хорошие ответы. –

ответ

12

В таких языках, как C, информация всегда «хранится» в том, как вы интерпретируете данные. Некоторая привлекательность добавляется компилятором, который в некоторой степени понимает типы ваших переменных и пытается предотвратить операции, которые не имеют смысла.

Например, предположим, что у вас есть бит: 0xFFFFFFFF. Если вы интерпретируете их как «32b unsigned int», вы получите 4294967295. Если вы интерпретируете их как «32b подписанный int», вы получите -1(*). Если вы интерпретируете их как двойник, бог знает, что вы получите.

+1

«Если вы интерпретируете их как двойник, бог знает, что вы получите». Проблемы, как правило. «Двойной» имеет значение 64 бита. Если вы интерпретируете их как 'float', это NaN, если используется IEEE754. –

6

Нигде, это просто предполагается кодом.

+0

Важно отметить, что на других языках (C++) есть вещь, называемая динамической привязкой к vtables, которая содержит некоторую информацию о типе объекта. – Mikhail

+1

@ Миша этот вопрос был о C, поэтому я еще не добавил эту информацию – heinrich5991

1

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

Типы данных связаны с языком, когда исполняемый файл готов, язык больше не играет роль, так как теперь это все память и процессор.

3

Приложение A не хранит информацию о типе. Единственное применение - использование данных. И, в С, очень просто злоупотреблять этим исполнением.

Рассмотрим следующий пример:

short s; 
short *p = &s; 
*(long*)p = 0; 

Этот код принимает указатель на короткой переменной, а затем записывает в эту переменную, как если бы это было давно. Это перезаписывает память за пределами того, что принадлежит используемой переменной, вызывая неопределенное поведение.

+0

Возможно, вы имели в виду '* (long *) & s'? – asaelr

+0

Упс! Да, исправлено. –

+1

UB прямо здесь ('(long) p' не может быть выровнено). Лучше переключиться на короткий и длинный для примера. –

2

Эта информация не хранится. Например, вы можете делать такие вещи, как

int i=15; 
char *p=(char*)&i; 
char c=*p; //Now, c contain the first byte of 15, which may be 15 or 0 

Но не делайте этого, если вы действительно не знаете, что вы делаете. Делать такие вещи, как это, небрежно, является распространенным способом ошибок.

+0

Зачем это неправильно? Что произойдет, если мы напечатаем f («% c», c); –

+0

@SharatChandra Это нормально, если вы знаете, что делаете. Просто, если кто-то не знает и не делает такие вещи, это обычно вздор. –

+0

@SharatChandra Как писал Даниэль, все прекрасно, когда вы знаете, что делаете, но даже в этом простом примере 'c' может быть 0 или 15. В более сложных случаях нам нужно быть осторожным и относительно выравнивания. – asaelr

Смежные вопросы