Страницы

Поиск по вопросам

понедельник, 25 марта 2019 г.

C, откуда 3 байта?

Вот простенький код, на экран выводит число равное 3, почему? откуда взялись эти 3 байта struct student { char name[20]; char sex; int age; float mark; };
struct student s2; int main( void ) { printf("%d", sizeof(s2) - sizeof(s2.sex) - sizeof(s2.age) - sizeof(s2.mark) -sizeof(s2.name)); // = 3 } и еще один вопрос той же темы union rec { int a[5]; struct student st; } r;
int main( void ) { printf("%d", sizeof(r) == sizeof(student) ); } почему выдает истину, если на самом деле ни какая не истина, 5 * 4 байтов разницы


Ответ

Эти три дополнительных байта - результат так называемого выравнивания. Суть его заключается в том, что данные помещаются в памяти не всегда "вплотную", вслед друг за другом, а по адресам, которые кратны размеру поля. Скажем, если int на данной платформе имеет размер 4 байта, то поле данного типа будет размещено не сразу вслед за предыдущим полем, а по ближайшему адресу, кратному четырем. Все эти хитрости с выравниванием служат одной цели - увеличению скорости работы, так как процессору проще обращаться к данным по "выровненном" адресам. Кстати, если бы ваша структура состояла только из однобайтных полей, то этого эффекта по понятным причинам бы не было По поводу второй части вопроса тоже вполне объяснимо - это вытекает из самой сущности union, который, в отличие от структур, хранит данные в одной и той же области памяти, и его размером является размер его максимального поля. Максимальным по размеру является st, следовательно sizeof(r) равен sizeof(student) По первой части вопроса почитайте тут и тут, по второй части - например, здесь Кстати: ААА, не могу понять, где лежать будут эти 20 байт???))) вот вам простая аналогия - представьте себе выключатель, которым вы включаете/выключаете свет. Вы могли бы использовать вместо одного выключателя два разных рубильника. Один - чтобы включить, а другой - чтобы выключить свет. Но удобнее иметь все это в одном выключателе. То есть когда свет включен, вы не можете его включить еще раз, когда выключен - не можете еще раз выключить. union - это нечто похожее - когда вы пользуетесь одним его полем, вы не можете пользоваться другим (точнее можете, но это не имеет смысла и приведет к ошибкам). Аналогия, конечно, кривовата, но, может, с ее помощью вам будет проще понять это

Комментариев нет:

Отправить комментарий