Будь умным!


У вас вопросы?
У нас ответы:) SamZan.net

Лабораторная работа

Работа добавлена на сайт samzan.net: 2016-03-13

Поможем написать учебную работу

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

Предоплата всего

от 25%

Подписываем

договор

Выберите тип работы:

Скидка 25% при заказе до 21.5.2024


Рубанчик В.Б.,

Михайличенко В.Н.

Лабораторная работа "Изучение свойств указателей"

5/5


Р
Л

ЛАБОРАТОРНАЯ РАБОТА

Тема:   Изучение свойств указателей

Цель работы:     Закрепить на практических примерах понимание основных свойств указателей  

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

Работа с указателями тесно связана с двумя другими операциями языка Си — вычислением размера объекта или типа, и приведением типов данных.

Операция вычисления размера sizeof

Так как размеры базовых типов Си стандартом языка строго не регламентируются, то они зависят от платформы и реализации (т.е. от воли разработчика компилятора). Реальные размеры объектов часто нужны программисту при написании кода.

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

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

Унарная операция sizeof возвращает  размер  своего операнда в байтах, т.е. количество байт памяти, которые занимает соответствующий объект программы (константа, переменная, результат вычисления выражения, массив и т.п.):

sizeof 2, sizeof x, sizeof(2*x+1)

Результат применения операции имеет специальный вспомогательный тип size_t, определенный в нескольких заголовочных файлах, включая stdio.h.  

Размер этого типа выбирается так, чтобы он мог содержать число, описывающее теоретически самый большой размер массива данных любого типа. Для шестнадцатиразрядных компиляторов, к которым относится ВС 3.1, это синоним типа unsigned int.

Операция sizeof обладает приоритетом и типом ассоциативности остальных унарных операций.

Она имеет два основных применения.

  •  Операция sizeof применена к  переменной или другому конкретному объекту данных (выражение, константа), и,  если того не требует определение порядка действий, операнд sizeof брать в скобки не требуется:

2*sizeof x +1.

  •  Операция sizeof может быть применена к типу данных. Результатом является размер памяти, отводимой компилятором для указанного типа.  В этом случае операнд (т.е. имя типа данных) нужно обязательно заключать в круглые скобки:    

sizeof(float).

Операцию  sizeof можно  применять к любым типам:

а) к базовым типам — int,  float, … ,

б) к типам, производным от базовых, например, sizeof(int*) — размер "указателя на int", или к массиву;

в) к структурным типам данных, формируемым программистом (будут изучаться  позже).

ЗАДАНИЕ 1 (анализ результатов выполнения операции sizeof)

1. Подготовить и выполнить программу, содержащую следующие операторы  (файл lab4_1.c):

 float x=-8.92;

int y=5;

printf("sizeof x=%u\n", sizeof x);

printf("sizeof y=%u\n", sizeof y);

printf("sizeof x+y=%u\n", sizeof x+y);

printf("sizeof (x+y)=%u\n", sizeof (x+y));

printf("sizeof x*2+1=%u\n", sizeof x*2+1);

printf("sizeof 2*y+1=%u\n", sizeof 2*y+1);

printf("sizeof ++y=%u\n", sizeof ++y*2);

printf("sizeof y--*2=%u\n", sizeof y--*2);

В отчете результаты работы программы оформить в виде таблицы

Выражение

Размер объекта

в байтах

Порядок вычислений

. . .

. . .

. . .

. . .

. . .

. . .

В последнем столбце требуется расставить скобки в соответствии с приоритетами операций.

2. Написать программу, которая в отдельных строках выводит  информацию о размере каждого из базовых типов языка (char, short, int, long, float, double, long double).  Выводится название типа данных и его вычисленный размер.

Размер указателя и указываемого объекта

В языке Си  указатели — это переменные, которые предназначены для хранения адресов объектов программы.

Как любые переменные, указатели должны быть определены. Они могут быть определены или объявлены на внешнем (глобальном) или внутреннем (локальном) уровнях, иметь любой из классов памяти, ссылаться на любой тип данных.

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

Результатом выполнения операции разадресации указателя является значение объекта, на который он ссылается. И, чтобы оперировать с этим значением, компилятору недостаточно знать адрес, ему нужно знать тип объекта.

Поэтому при определении указатели связываются с определенным типом данных, и их характеризуют как "указатель на <тип_данных>". Здесь <тип_данных> — это любой базовый или производный тип.

Например, определение  float *px;  вводит в программу объект px, имеющий тип "указатель на float".

Замечание

Реальный размер указателя (как переменной) в байтах зависит от используемого адресного пространства. В 16-разрядных приложениях для операционной системы MS-DOS размер адресного пространства для хранения данных и кода определяется специальным параметром компилятора — моделью памяти. Модель памяти в BC++ 3.1 устанавливается в пункте меню

   Options | Compiler | Code Generation...

Например, в модели памяти Small для данных используются двухбайтовые адреса, а в модели Large — четырехбайтовые.

ЗАДАНИЕ 2 (адресная арифметика)

Написать программу, в которой определяются переменные типов char, int, double.

Для каждой переменной программа выводит (в строку) ее адрес и значения выражений "адрес + 2" и "адрес – 1" (какой тип имеют эти значения?).

В отчете результаты привести в виде таблицы с колонками

Tip (тип)

adr  (адрес)

adr + 2

adr –1

char

. . .

. . .

. . .

. . .

. . .

. . .

. . .

Пояснить полученные результаты.

Замечания

1. Для вывода на экран адресов в форматной строке функции printf необходимо использовать спецификацию %p (от pointer — указатель).

2. Вычисляемые выражения  adr+2 и adr-1 не имеют  практического смысла, они используются только для проверки правил адресной арифметики. Осмысленное использование адресной арифметики потребуется при выполнении задания 3.

Операция приведения типа

Приведение типа — это представление данных одного типа как данных другого типа.  Приведение типа часто предусматривается компилятором неявно. Например, при вычислении z

int x=3;

float y=0.15, z;

z=x+y;

компилятор сначала приведет операнды к одному типу,  и только потом сложит их. По умолчанию он выполняет только безопасные преобразования, несвязанные с потерей информации. Очевидно,  преобразование от более короткого (int) к более длинному типу (float), является безопасным.

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

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

(<тип_данных>) выражение.

Операция приведения типа является унарной.  

Ее результат вычисляется как значение операнда (выражения), представленное в ввиде  заданного преобразованием типа.  

При этом само выражение не меняется. Например, в условиях приведенного примера при вычислении выражения  (float)x значение x не изменится (т.е. останется 3), но результатом вычисления  будет 3.0.

Приводимое выражение может иметь любой базовый или производный тип, в том числе и адресный.

Замечание

Явные преобразования могут быть достаточно произвольными, например,  предусматривать потенциально опасные действия, такие как "укорачивание" данных (преобразование значения типа long к типу int и т.п.). За осмысленность явных  преобразований ответственность  несет программист.

ЗАДАНИЕ 3

1. Проверить, какие результаты будут получены при выполнении следующего фрагмента  программы, и объяснить, почему (файл lab4_2.c)?

 int x=8, y=3;

float z1, z2;

z1=x/y;

z2=(float)x/y;

printf("x/y=%f\n",z1);

printf("(float)x/y=%f\n",z2);

Битовые флагами

Язык Си разрабатывался для системного программирования, в котором часто используются флаги — переменные, позволяющие фиксировать одно из двух состояний объекта, например,  "включено–выключено", "доступно–недоступно", "скрыто–видимо" и т.п.

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

В Си для хранения удобно использовать беззнаковые целые типы, внутреннее представление которых не содержит знаковых разрядов, и поэтому все биты равноправны. Собственно целый тип выбирается в зависимости от количества флагов.

Когда флаги "упаковываются" в переменную, например, типа unsigned int, то эта переменная получит некоторое псевдозначение, лишенное реального смысла. Польза от такой переменной появляется при разборе значения на отдельные биты.

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

Чтобы выделить из представления числа первый байт, можно использовать операцию преобразования его адреса к типу unsigned char*, и затем применить к результату операцию разадресации.

Далее  отдельные биты можно выделить с помощью масок.

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

Замечание

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

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

ЗАДАНИЕ 4

1. Написать программу, которая поочередно выводит в шестнадцатеричной форме значения байтов представления переменной ul:

   unsigned long ul=0x77BBCCDD.

Сообщения должны иметь вид строк "Byte 1:  Znachenie ...").

Для выполнения задания нужно:

а) Определить в программе указатель pUL на тип unsigned long и присвоить ему адрес переменной ul.

б) Описать вспомогательный указатель pUC, на тип unsigned char.

в) Используя операцию приведения типа, присвоить указателю pUC преобразованное значение pUL.

г) Выполнить операцию разадресации для pUC, вывести значение полученного байта.

д) Используя адресную арифметику, перейти к следующим байтам и вывести их значения на экран.

Контрольные вопросы

1. Какой максимальный размер объекта может вернуть операция sizeof в шестнадцатеричном компиляторе ВС 3.1?

2. Каким уровнем приоритета и какой ассоциативностью обладает операция sizeof?

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

4. В чем различие между неявными и явными преобразованиями типа?

5. Какие преобразования типов называются безопасными?

6. Можно ли применять преобразование типа, например, для значений "указатель на указатель" и что в результате будет получено?

7. Какая спецификация формата применяется для вывода с помощью функции printf адресов объектов?




1. технологии могут применяться в виде компьютерных программ слайдфильмов презентаций [1]
2. Микробиология и вирусологи
3. Игра вслепую. Из-за чего и как началась Вторая мировая война
4. Георгий Огарев 22 закона управления людьми
5. Мировой опыт и российская практика функционирования фондовых бирж
6. Хозяйственные экономические отношения складываются при осуществлении хозяйственной экономической дея.html
7. д 53-02 ук2 д 62-23 ук3 пр
8. Резервы обучения чтению
9. Информатика. Тесты.html
10. Реферат на тему- Народження держави Україна історія та сучасність Нова незалежна держава Україна з~яв
11. реферату- Огляд світового ринку перестрахування- тенденції переходу на сезон 20032004 рокуРозділ- Страхування
12. тема в международных отношениях смогла образоваться лишь после того как установился устойчивый баланс межд
13. НА ТЕМУ 5- Патофизиология микроциркуляции и периферического кровообращения Дисциплина- ПАТОФИЗИОЛ
14. ТЕМАТИЧНИХ ЗАДАЧ 13
15. Адамсит ~ай улы заттар тобына жатадыТітіркендіргіш ~серлі Иприт Люизит улы заттарды~ ~ай тобына жа.html
16. История изучения и использования природных вод на Урале
17. Рубіж 1919 1920 pp
18. 2013 уч.год Физика ~ 9 класс Дата проведения- февраль 2013 года
19. Тема 3 Акції Акціонерні товариства ~ емітенти акцій
20. числовые знаковые n~ целое double x; double не целочисленное действительное число х cin]]n;