Файл: Обязательные результаты обучения.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 11.01.2024

Просмотров: 25

Скачиваний: 1

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Пример 2.
/* Демонстрация операций с переменными-указателями */
/* ----------------------------------------------- */
#include
#include int main()
{ int x=5,y; int *px,*py; /* Описание указателей px и py на целое */
/* ------------------------------------------------- */ px=&x; /* Переменная px указывает на x */ printf(" (%u)=%d\n\n",px,*px);
/* ------------------------------------------------- */ y=*px; /* Переменная y получает значение того */
/* объекта, на который указывает px, */
/* т.е. значение переменной x */ printf(" y=*px; => y=%d\n",y);
/* ----------------------------- */ printf(" *px=0 => x=%d\n",*px=0);
/* Переменная х получает значение 0 */
/* --------------------------------------------- */ printf(" y=*px+1 => y=%d\n",y=*px+1);
/* Переменная y получает значение */
/* большее на 1 значения х */
/* ------------------------------------------- */ printf(" *px+=1 => x=%d\n",*px+=1);
/* Увеличение содержимого x на 1 */
/* ------------------------------------------ */ printf(" *px++ => x=%d\n",*px++);
/* Увеличение адреса px на 1; постфиксная */
/* операция ++ не изменяет px, пока объект */
/* по адресу px не будет получен */
/* ---------------------------------------------------- */ printf(" *++px => x=%d\n",*++px);
/* Префиксная операция ++ увеличивает px */
/* до получения значения x */
/* ---------------------------------------------------- */ printf(" *--px => x=%d\n\n",*--px);
/* Префиксная операция -- уменьшает px до */
/* получения значения x */
/* ---------------------------------------------------- */ py=px; /* Копирование содержимого указателя px в */
/* указатель py в результате py указывает */
/* на тот объект, на который указывает px */
/* ---------------------------------------------------- */ printf(" (%u)=%d\n\n",py,*px);
getch(); return 0;
}
Результат работы программы:
В ячейке с адресом 65524 содержится 5
Значение переменной y равно 5
Значение переменной x равно 0
Значение переменной y равно 1
Значение переменной x равно 1
Значение переменной x равно 1
Значение переменной x равно 347
Значение переменной x равно 0
В ячейке с адресом 65526 содержится 0
Пример 3.
/* Демонстрация синтаксиса и семантики функций */
/* calloc() и free() */
/* ------------------------------------------- */
#include
#include
#include
/* ------------- */ void main()
{ int *p; p=(int *) calloc(sizeof(int),1);
/* ------------------------------------------ */
/* Резервирование участка в heap-области для */
/* динамической переменной, на которую указы- */
/* вает p, схематично изобразим так: */
/*
*/
/* */
*p=1; /* Присваивание значения переменной *p */
/* */
/*
*/
/* */
/* ------------------------------------------ */ printf("Значение динамической переменной: %d\n",*p); free(p);
/* ------------------------------------------ */
/* Освобождение участка в heap-области, кото- */
/* торый занимало значение динамической пере- */
/* менной */

/*
*/
/* */
/* ------------------------------------------ */ if (!p) /* Вместо if (p==NULL) ... */ printf("Значение указателя равно NULL.\n"); else printf("Значение указателя не равно NULL.\n"); p=NULL; /* Только теперь значение указателя равно NULL */ getch(); return 0;
}
Результат работы программы:
Значение динамической переменной: 1
Значение указателя не равно NULL.
Пример 3
1
/* Демонстрация синтаксиса и семантики операции sizeof */
/* --------------------------------------------------- */
#include
#include int main()
{ char c; short s; int i; long l; float f; double d; long double ld;
/* ------------------------------------------------- */ printf("Размер типа char = %2d\n",sizeof(char)); printf("Размер типа short = %2d\n",sizeof(short)); printf("Размер типа int = %2d\n",sizeof(int)); printf("Размер типа long = %2d\n",sizeof(long)); printf("Размер типа float = %2d\n",sizeof(float)); printf("Размер типа double = %2d\n",sizeof(double)); printf("Размер типа long double = %d\n\n", sizeof(long double));
/* ---------------------------------------------------- */ printf("Размер переменной типа char =%2d\n",sizeof c); printf("Размер переменной типа short =%2d\n",sizeof s); printf("Размер переменной типа int =%2d\n",sizeof i); printf("Размер переменной типа long =%2d\n",sizeof l); printf("Размер переменной типа float =%2d\n",sizeof f); printf("Размер переменной типа double =%2d\n",sizeof d); printf("Размер переменной типа long double =%d\n\n", sizeof ld);

getch(); return 0;
}
Результат работы программы:
Размер типа char = 1
Размер типа short = 2
Размер типа int = 2
Размер типа long = 4
Размер типа float = 4
Размер типа double = 8
Размер типа long double = 10
Размер переменной типа char = 1
Размер переменной типа short = 2
Размер переменной типа int = 2
Размер переменной типа long = 4
Размер переменной типа float = 4
Размер переменной типа double = 8
Размер переменной типа long double = 10
Пример 4.
/* Демонстрация определения свободного места в heap-облас- */
/* ти с помощью библиотечной функции coreleft() */
/* ------------------------------------------------------- */
#include
#include
#include
/* Файл заголовков alloc.h необходим для вызова функции */
/* coreleft(), возвращающей количество свободного места */
/* в heap-области */
/* ---------------------------------------------------- */ int main()
{ int *p; printf("Свободное место в heap-области: %u\n",coreleft()); p=(int *)calloc(sizeof(int),1000); printf("Свободное место в heap-области: %u\n",coreleft()); free(p); printf("Свободное место в heap-области: %u\n",coreleft()); getch(); return 0;
}
Результат работы программы:
Свободное место в heap-области: 63456
Свободное место в heap-области: 61456
Свободное место в heap-области: 63456
Пример 4
1
/* Демонстрация определения свободного места в heap- */
/* области с помощью библиотечной функции coreleft() */

/* ------------------------------------------------- */
#include
#include
#include
/* ------------- */ int main()
{ long int f1,f2; int *p;
/* ---------------------------------------- */ printf("Свободное место в heap-области: %p\n", f1=coreleft()); p=(int *)calloc(sizeof(int),3); printf("Свободное место в heap-области: %p\n", f2=coreleft()); printf("Занято в heap-области (в условных единицах):
%lu\n", (f1-f2)/sizeof(int)/3); printf("Контрольный вывод: %d %d %d\n",
*p=10,*(p++)=11,*(p++)=12); free(p-2); printf("Свободное место в heap-области:
%p\n\n",coreleft()); getch(); return 0;
}
Результат работы программы:
Свободное место в heap-области: F7B0
Свободное место в heap-области: F7A0
Занято в heap-области: 16
Контрольный вывод: 10 11 12
Свободное место в heap-области: F7B0
Пример 5.
/* Демонстрация работы с динамической памятью */
/* ------------------------------------------ */
#include
#include
#include
/* ------------- */ int main()
{ int *a,*b; printf("Свободное место в heap-области: %u\n",coreleft()); a=(int *)calloc(sizeof(int),1); b=(int *)calloc(sizeof(int),1);
*a=1; *b=2;
/* Изобразим выполнение этих операторов на схеме: */
/* ---------------------------------------------------- */

/* int *a;
*/
/* int *b;
*/
/* a=(int *)calloc(sizeof(int),1);
*/
/* b=(int *)calloc(sizeof(int),1);
*/
/* *a=1;
*/
/* *b=2;
*/
* ---------------------------------------------------- */ printf("a+b=%d\n",*a+*b);
/* --------------------------------------------------- */
/* free(a);
*/
/* free(b);
*/
/* ---------------------------------------------------- */ free(b); free(a);
/* Вызовы функции free() записаны в порядке, обратном */
/* тому, в каком записана последовательность функций */
/* calloc(), хотя это и не обязательно */
/* ---------------------------------------------------- */ printf("Свободное место в heap-области: %u\n",coreleft()); getch();
}
Результат работы программы:
Свободное место в heap-области: 63472 a+b=3
Свободное место в heap-области: 63472
Пример 6.
/* Демонстрация разыменования указателя, который не */
/* был инициализирован. Это может привести: */
/* (1) к фатальной ошибке во время выполнения прог- */
/* раммы; */
/* (2) случайному искажению данных, в результате */
/* чего программа завершается с неверным результатом */
/* ------------------------------------------------- */
#include
#include

int main()
{ int dec=10,
*ptr=&dec, /* Указатель ptr инициализирован */
*ptr1; /* Указатель ptr1 не инициализирован */
/* --------------------------------------------- */ printf("Указатель инициализирован:\n"); printf(" (%p)=%d\n",ptr,*ptr); printf(" &*ptr=%p\n *&ptr=%p\n\n",&*ptr,*&ptr);
/* ----------------------------------------- */ printf("Указатель не инициализирован:\n"); printf(" (%p)=%d\n",ptr1,*ptr1); printf(" &*ptr1=%p\n *&ptr1=%p\n\n",&*ptr1,*&ptr1);
/* --------------------------------------------- */ printf("Инициализируем неинициализированный указатель:\n"); ptr1=&dec; printf("(%p)=%d\n\n",ptr1,*ptr1); getch(); return 0;
}
Результат работы программы:
Указатель инициализирован:
(FFF4)=10
&*ptr=FFF4
*&ptr=FFF4
Указатель не инициализирован:
(8E01)=12342
&*ptr=8E01
*&ptr=8E01
Инициализируем неинициализированный указатель:
(FFF4)=10
Пример 7.
/* Демонстрация использования указателя на "пустой" тип */
/* Компилятор: Borland C 3.1 */
/* ---------------------------------------------------- */
#include
#include
#include int main()
{ int dec=10,*u,*v; void *ptr=&dec;
/* ----------------------------- */
/*
*/
/* (void *) */

/* */
/* ----------------------------- */ printf("(%u)=%d\n",u=ptr,*(u=ptr)); printf("Свободное место в heap-области: %u\n",coreleft()); u=(int *)calloc(sizeof(int),1); printf("Значение указателя: %u\n",ptr);
*u=12; ptr=u;
/* ---------------------------------------------------- */
/* */
/*
*/
/* ---------------------------------------------------- */ v=ptr;/* Нет необходимости в явном преобразовании типов */ printf("(%u)=%d\n",ptr,*((int *)ptr)); ptr=v=NULL; free(u);
/* ------------------------------------------ */ printf("Свободное место в heap-области: %u\n\n", coreleft()); getch(); return 0;
}
Результат работы программы:
По адресу 65524 хранится 10
Свободное место в heap-области: 63424
Значение указателя: 1548
Свободное место в heap-области: 63424
Значение указателя: 1548
Пример 8.
/* Демонстрация определения размера динамической памяти */
/* ---------------------------------------------------- */
#include
#include
#include
/* ------------- */ int main()
{ int k; void *ref; for (k=1;;k++)
{
ref=calloc(k,1); if (!ref) break; free(ref);
} printf("Размеры доступной heap-области: %u\n",--k); printf("Контроль свободного места: %u\n\n",coreleft()); getch(); return 0;
}
Результат работы программы:
Размеры доступной heap-области: 63464
Контроль свободного места: 63456
Пример 9.
// Демонстрация использование операций манипулирования
// динамической памятью (new и delete)
// Компилятор Borland C++ 3.1
// ----------------------------
#include
#include
#include int main()
{ printf("Свободное место в heap-области: %u\n",coreleft()); int *iPtr=new int; // Указатель iPtr содержит адрес динами-
// ческой переменной типа int
// --------------------------------- double *dPtr=new double (3.1415926);
// Указатель dPtr содержит адрес динами-
// ческой переменной типа double и ини-
// циализирует ее значением 3.1415926
// -----------------------------------------------------
// Для знатоков строк в языке C int strlen=4; char *str; str=new char[strlen]; // Указатель str содержит адрес
// массива элементов типа char str[0]='А'; str[1]='б'; str[2]='В'; str[3]='\0';
// --------------------------------------------- if (iPtr&&dPtr&&str==0)
{ printf("Не хватает памяти для динамически "
"размещаемых переменных!\n"); return 1;
} else {
*iPtr=1000;

printf("По адресу iPtr=%p содержится *iPtr=%d\n", iPtr,*iPtr); delete iPtr;
// ---------------------------------------------- printf("По адресу dPtr=%p содержится *dPtr=%f\n", dPtr,*dPtr); delete dPtr;
// -------------------------------------------- printf("Строка по адресу str=%p содержит %s\n", str,str); delete[] str;
// --------------------------------------------- printf("Свободное место в heap-области: %u\n\n", coreleft()); getch(); return 0;
}
}
Результат работы программы:
Свободное место в heap-области: 61872
По адресу iPtr=0C10 содержится *iPtr=1000
По адресу dPtr=0C18 содержится *dPtr=3.141593
Строка по адресу str=0C24 содержит АбВ
Свободное место в heap-области: 61872
ЗАДАЧИ ДЛЯ САМОСТОЯТЕЛЬНОГО РЕШЕНИЯ
Собственно говоря, вы всегда должны проверять все
указатели, как только начнут появляться любые ошибки.
Г.Шилдт
1. Указатели
1. Проверьте, соответствует ли описание типов приведённым рисункам? int dec=10; int *ptr1=&dec; int *ptr2=ptr1;
int **ref=&dec;
2. Дано следующее описание переменных: int *p,*q;
Пусть переменные p и q имеют значения, показанные ниже:
(a) Что является значением переменной p: ссылка на объект (переменную) целого типа или сам этот объект? (б) Что обозначает переменная *p: ссылку на объект целого типа, сам этот объект или целое число 5? (в) Каковы типы переменных p и *p?
3. Дано описание переменных int *p,*q;
Пусть переменные p и q имеют значения, показанные ниже:
Что будет выдано на печать в результате выполнения следующих программных фрагментов?
(1)
*p=*q; if (p==q) p=NULL; else if (*p==*q) q=p; if (p==q)
*q=4; printf("%d",*p);
(2)
*p=*q; if (p==q) p=NULL; else if (*p==*q) q=p; if (!p==q)
*q=4; else *p=6; printf("%d",*p);
(3)
*p=*q; if (p!=q) p=NULL; else if (*p==*q) q=p; if (!p==q)
*q=4; else *p=6; printf("%d",*p);
4. Дано следующее описание переменных: int *p,*q; char *r;
Какие из следующих операторов присваивания неправильны и почему?
(а) p=q;
(в) p=NULL;
(д) q=*p;
(б) q=r;
(г) r=NULL;
(е) *p=NULL.
5. Дано следующее описание переменных: int *p,*q; char *r;
Какие из следующих операторов неправильны и почему?
(а) *r=*p;
(б) *q=(int)*r;
(в) if (r!=NULL)
*r=*NULL;
(г) if (q>NULL)
*q=*p;
(д) if (q==p) printf("%d",q);
(e) if (q!=r) scanf("%c",r);

6. Допустимы ли в языке C конструкции
*q+2, **q, ++*q, *++q? Ответ обоснуйте.
7. Верно ли утверждение о том, что операторы присваивания px=&x; y=*px; семантически эквивалентны одному оператору y=x;?
8. Рассмотрим следующую программу:
#include
#include int main()
{ int *x,y; x=(int *) calloc(sizeof(int),1); /* A */
*x=1; y=-*x; /* B */ free(x); /* C */ printf("Значение y: %d",y); /* D */ return 0;
}
(a) Какие из переменных существуют в каждой из точек A, B, C, D и каковы их значения в эти моменты? (б) Почему объекты (переменные), создаваемые функцией calloc() и уничтожаемые функцией free(), называют динамическими
объектами? Почему им не дают имена? (в) Можно ли переменной x присвоить ссылку на переменную y? Можно ли с помощью функции free() уничтожить переменные x и y?
9. [Дейтел,Дейтел,2002,с.311,№7.4]
Выполните каждую из следующих задач при помощи одиночного оператора.
Считайте объявленными переменные с плавающей точкой number1 и number2, причём number1 присвоено значение 7.3.
(а) Объявите указатель fPtr на тип float.
(б) Присвойте адрес переменной number1 указателю fPtr.
(в) Выведите значение величины, на которую ссылается fPtr.
(г) Присвойте значение величины, на которую указывает fPtr, переменной number2.
(д) Выведите значение number2.
(е) Выведите адрес number1. Используйте спецификатор формата %p.
(ж) Выведите адрес, сохранённый в fPtr. Используйте спецификатор формата
%p. Совпало ли выведенное значение адреса с адресом number1?
10. [Дейтел,Дейтел,2002,с.313,№7.10]
Выполните каждое из следующих заданий, используя для этой цели только один оператор. Считайте объявленными переменные value1 и value2 типа long, причём переменной value1 присвоено значение 20000.
(а) Объявите указатель lPtr на объект данных типа long.
(б) Присвойте значение адреса переменной value1 указателю lPtr.
(в) Выведите значение объекта, на который ссылается lPtr.
(г) Присвойте значение объекта, на который ссылается lPtr, переменной value2.
(д) Выведите значение value2.
(е) Выведите адрес value1.


(ж) Выведите значение адреса, находящееся в lPtr. Совпадает ли выведенное значение с адресом value1?
11. (По [Дейтел,Дейтел,2002,с.321-322,№7.23])
Найдите ошибку в каждом из следующих программных фрагментов. Если ошибку можно исправить, объясните, как это сделать.
(а) int *number; printf("%d\n",*number);
(г) short *numPtr,result; void *genericPtr=numPtr; result=*genericPtr+7;
(б) float *realPtr; long *integerPtr; integerPtr=realPtr;
(д) float x=19.34; float xPtr=&x; printf("%f\n",xPtr);
(в) int *x,y; x=y;
(е) char *s; printf("%s\n",s);
12. Определите, правильно ли представлен графически следующий программный фрагмент: int *p=NULL,
**q=&p,
***r=&q; p=(int *)&r; printf("%p %p %p %p %p %p %p\n", p,*q,r,*p,q,*r,***r);
Если фрагмент правилен, то определите, что будет напечатано в результате его работы.
13. Напишите программный фрагмент, который представлен графически следующим образом:
14. Правилен ли приведённый ниже программный фрагмент: int a=4,*p=&a; char b='d',*q=&b; q=p; printf("%d %d %c\n",*p,*q,b); который позволяет перейти от графического представления к представлению
Если фрагмент правилен, то определите, что будет выведено на экран в результате его работы.