Скачать презентацию Л 4 2012 -2013 г Ионов Скачать презентацию Л 4 2012 -2013 г Ионов

4_2012.pptx

  • Количество слайдов: 13

Л. № 4, 2012 -2013 г. , Ионов Ю. Г. В данной презентации приводятся Л. № 4, 2012 -2013 г. , Ионов Ю. Г. В данной презентации приводятся дополнителные сведения по 2 -м темам: 1 - массивы и указатели (необходимо разобраться в том, какой смысл следует вкладывать в арифметические операции над указателями и в каком отношении между собой находятся массивы и указатели); 2 - функции (здесь на примерах с помощью комментариев рассмотрен ОБМЕН ДАННЫМИ между функциями программы. При этом используются разные механизмы обмена. Необходимо понять, какая между ними разница и в каких случаях следует предпочесть тот или иной механизм). Примечание: мы начинаем готовиться ко 2 -й контрольной работе !

I. О массивах и указателях I. О массивах и указателях

/*Вначале проиллюстрируем различие в способе обращения к переменным*/ # include < iostream. h > /*Вначале проиллюстрируем различие в способе обращения к переменным*/ # include < iostream. h > # include < conio. h > void main ( ) { clrscr(); int *x, y; //объявление указателя и переменной *x=200; y=300; cout <

Адресная арифметика Пусть дано следующее описание int a[100], определяющее массив из ста элементов типа Адресная арифметика Пусть дано следующее описание int a[100], определяющее массив из ста элементов типа int. Поскольку a==&a[0] , то адрес элемента a[i] равен a + sizeof(int)*i, где функция sizeof(int)- возвращает размер типа в байтах. Если учесть соглашение о том, что выражение вида a+i как раз и определяет адрес i-ого элемента, т. е. &a[i] == a+i, тогда обозначение a[i] становится эквивалентным адресному выражению *(a+i) в том смысле, что оба они определяют одно и то же числовое значение, а именно: a[i] == *(a+i). Пусть теперь имеются описания int a[10]; int *pa; выполняя операцию присваивания pa = a или pa = &a[0] мы устанавливаем указатель pa на нулевой элемент массива a и поэтому справедливы равенства &a[i] == pa+i и a[i] == *(pa+i), т. е. операцию pa+i, увеличивающую значение указателя, можно интерпретировать как смещение вправо на i элементов базового типа. Все это означает, что всякое обращение к i-ому элементу массива или его адресу допустимо представлять как в индексной форме, так и на языке указателей.

Пусть array – имя массива, а ptr - указатель Первый способ доступа: // указатели Пусть array – имя массива, а ptr - указатель Первый способ доступа: // указатели array[2]=3 или array[i+1]=7 // с использованием обычных // индексных выражений array[2] и 2[array] //эквивалентные выражения или ptr[2] или 2[ptr] //доступ к 3 -му элементу Второй способ: Ptr : Ptr+1 : Ptr+2 : • • array: array[0] Ptr+3 : • • можно: *( Ptr+i ) т. е. *( Ptr +2 )=3

1. Использование указателей для объявления сложной структуры такой, как массив, снижает затраты на указатели. 1. Использование указателей для объявления сложной структуры такой, как массив, снижает затраты на указатели. 2. Память, связанную с указателем, можно вернуть в свободную область памяти. Этого нельзя делать с обычными величинами, в том числе, с массивом, объявленным например так: int x[75]. 3. С объектом, объявленным как указатель, проще оперировать в случае, если есть необходимость обработки объекта как целого.

II. Функции и обмен данными между ними II. Функции и обмен данными между ними

Пример передачи данных по значению #include <stdio. h> //подключаем библиотеку средств ввода//вывода //прототип функции Пример передачи данных по значению #include //подключаем библиотеку средств ввода//вывода //прототип функции //заголовок главной функции int fun 1(int, int); void main() { int i, j, constanta; //объявление переменных i=2; j=3; constanta = fun 1(i, j); //значение fun 1(2, 3) присваивается // переменной constanta printf(“%dn”, constanta); //печать значения constanta, равной //зн. fun 1 } int fun 1(int a, int b) //описание функции { return a+b; //возвращение значения функции }

Пример передачи данных по указателю // расчет максим. эл-та массива с его передачей как Пример передачи данных по указателю // расчет максим. эл-та массива с его передачей как указателя #include # include int maximum (int *, int); // прототип функции void main (void) { clrscr (); int a[100], n; cin >>n; for (int i=0; i> a[i]; int max = maximum (a, n); // вызов функции cout << max; } //функция int maximum (int * a, int n) { int max = a[0]; for (int i=1; i

Пример передачи данных по ссылке //переменная a главной функции и локальная переменная y //указывают Пример передачи данных по ссылке //переменная a главной функции и локальная переменная y //указывают на одну и ту же область памяти, поэтому увел. на 1 //значения y приводит к увеличению a в главной функции #include # include void example (int &y, int w) // определение неглавной функции { cout << y << “ ” << w << “n”; y++; w++; } // главная функция void main () { clrscr (); int a = 5, b = 10; example (a, b); cout << a << “ ” << b; } // здесь b и w указывают на разные области памяти

//Еще пример обмена данными между функциями по адресу (ссылке): #include<stdio. h> // подключаем библиотеку //Еще пример обмена данными между функциями по адресу (ссылке): #include // подключаем библиотеку функций ввода-вывода void object (int * m) //заголовок описания функции (не главной) { *m = *m > 0 ? *m : -*m; //вспомним: //в правой части - трехместная арифметическая //операция (? , : ). При ее выполнении требуется //три операнда, каждый из которых является //выражением: 1 -е *m > 0 , 2 -е *m, 3 -е -*m /*Значение всего выражения равняется значению выражения 2, если 1 -е выражение истинно, и выражению 3 – в ином случае */ } void main ( ) //главная функция { int k= -3; //объявление переменной и присваивание ей значения -3 object (&k); //вызов описанной выше функции printf(“nk=%d”, k); //печать значения k } //здесь обмен по ссылке (&k) осуществлен между main ( ) и object () ! Работу кода проверить самостоятельно

!Предупреждения: 1) функции, не имеющие возвращаемых значений, должны объявляться как тип void. Если функции !Предупреждения: 1) функции, не имеющие возвращаемых значений, должны объявляться как тип void. Если функции не присвоен никакой тип, компилятор Си считает, что функция имеет тип int. Однако стандарт Си 99 рекомендует объявлять тип int явно; 2) до появления языка в стандарте ANSI Cи типы аргументов в скобках заголовка разрешалось опускать. Но в этом стандарте и в Си 99 рекомендуется объявлять типы аргументов явно. Рекомендация не касается функции main (см. примеры выше).

Рекомендация: Если прототипы функций в программе опускаются, то рекомендуется все их определения поместить прежде, Рекомендация: Если прототипы функций в программе опускаются, то рекомендуется все их определения поместить прежде, чем функция используется в первый раз. Пример: … int min (int a, int b) {return a < b ? a : b; } … int main () { … printf (“минимум из %d и %d будет %d. n”, 3. 0, 5, min(3. 0, 5)); … }