Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Индексация с помощью указателей↑ ⇐ ПредыдущаяСтр 4 из 4 Содержание книги
Поиск на нашем сайте
Указатели и массивы очень тесно связаны между собой. Имя массива без индекса – это указатель на первый элемент массива. Пусть имеется массив
char p[10];
p &p[0]
p == &p[0]
Справедливо и обратное. Любой указатель может быть проиндексирован, как будто это массив. Например,
int *p, i[10];
p = i; p[5] = 1000; *(p+5) = 1000;
Данные способы индексации совершенно справедливы для массивов размерности 2 и более. Предположим, что а – это целочисленный массив 10 на 10. Тогда нижеприведенные операторы эквивалентны:
(int *)a &a[0][0]
Указатели иногда используются для обращения к массивам, поскольку арифметика указателей чаще всего выполняется быстрее, чем индексация массивов. Преимущество наиболее заметно, когда осуществляется последовательный доступ к массиву. В данной ситуации указатель может увеличиваться или уменьшаться с помощью эффективных операторов увеличения или уменьшения. Если же доступ к массиву происходит случайным образом, то лучше использовать индексацию массива, а не указатели. Двумерные массивы подобны массивам указателей на строки. Поэтому использование отдельных указателей является одним из лёгких способов доступа к элементам двумерного массива. Следующая функция выводит содержимое указанной строки глобального целочисленного массива num:
int num[10][10]; … void pr_row(int j) { int *p, t;
p = num[j];
for(t=0; t<10; ++t) printf(“%d “, *(p+t)); }
Данный код может быть обобщён, если передавать в качестве аргумента номер строки, длину строки и указатель на первый элемент массива: void pr_row(int j, int row_dimension, int *p) { int t;
p = p + (j * row_dimension); for(t=0; t< row_dimension; ++t) printf(“%d “, *(p+t)); }
Во многих ситуациях невозможно знать размер массива. В С++ можно динамически выделять и освобождать память при помощи операторов new и delete. Если необходимо выделить память под целочисленный массив длины 100, то можно воспользоваться следующим кодом:
int *p; try{ p = new int[100]; } catch(…){ puts(“Cannot allocate”); exit(1); }
p[5]
Для освобождения памяти необходимо пользоваться оператором delete.
delete [] p;
Оператор delete должен освобождать память, только ранее выделенную оператором new, иначе это может привести к краху программы.
Функции Функции – это базовые блоки С, в которых выполняются все операции. Стандартный вид функций следующий:
спецификатор_типа имя_функции (список параметров) { тело функции } Спецификатор_типа определяет тип возвращаемого функцией значения с помощью оператора return. Это может быть любой допустимый тип. Список параметров – это разделённый запятыми список переменных, получающих значения аргументов при вызове функции. Функция может быть без параметров и в таком случае список параметров состоит из ключевого слова void. Оператор return
Оператор return имеет два назначения. Во-первых, немедленный выход из функции. То есть он осуществляет выход в вызывающий функцию код. Во-вторых, может использоваться для возврата значения. Рассмотрим оба назначения.
Выход из функции
Имеется два способа окончания работы функции и передачи управления вызывающему коду. Первый способ предполагает достижение последнего оператора функции, после чего работа функции заканчивается при встрече }. Например, следующая функция выводит на экран строку в обратном порядке:
void pr_reverse(char *s) { register int t;
for(t=strlen(s)-1; t>-1; t--) printf(“%c”, s[t]); }
После отображения строки функция ничего не делает, поэтому управление передаётся вызвавшему её коду. Большинство функций использует оператор return для окончания исполнения с целью возвращения значения или упрощения кода функции и увеличения его эффективности путём создания нескольких точек выхода. Например, функция, показанная ниже, возвращает или индекс первого появления подстроки, указываемой в s2, в строке, указываемой в s1, или -1, если не обнаружено совпадений:
int find_substr(char *s1, char *s2) { register int t; char *p, *p2; for(t=0; s1[t]; t++) { p = &s1[t]; p2 = s2; while(*p2 && *p2==*p) { p++; p2++; } if(!*p2) return t; } return -1; } Надо обратить внимание, как два оператора return упрощают функцию.
Возвращаемые значения
Все функции, кроме функций типа void, возвращают значения, Данное значение определяется в операторе return. Если функция не определена как void, она может использоваться в качестве операнда в любом корректном выражении. Следовательно, каждое из следующих выражений корректно:
x = power(y);
if(max(x, y) > 100) printf(“greater”);
for(ch=getchar(); isdigit(ch);) …; Функция не может стоять с левой стороны оператора присваивания. Оператор типа
swap(x, y) = 100;
Если функция определена как void, она не может использоваться в выражениях. Предположим, что f() объявлена как void. Следующие операторы не будут компилироваться:
int t;
t = f();
f() + f();
Если не указано, чему присваивается возвращаемое значение, то оно просто отбрасывается. Рассмотрим следующую программу, использующую mul():
#include <stdio.h>
int mul(int a, int b);
int main(void) { int x, y, z;
x = 10; y = 20; z = mul(x, y); /* 1 */ printf(“%d “, mul(x, y)); /* 2 */ mul(x, y); /* 3 */
return 0; }
int mul(int a, int b) { return a*b; }
Строка 1 присваивает возвращаемое функцией mul() значение переменной z. В строке 2 возвращаемое значение используется функцией printf(). В строке 3 возвращаемое значение теряется.
Значения, возвращаемые функцией main() Когда используется оператор return в main(), программа возвращает код завершения вызывавшему процессу. Возвращаемое значение должно быть целого типа. Большинство ОС трактуют 0 как нормальное завершение программы. Остальные значения воспринимаются как ошибки.
Правила видимости для функций
Каждая функция в С – это блок кода. Код функции является собственностью функции, и к нему нельзя получить доступ с помощью оператора или другой функции, помимо вызова данной функции. Переменные, определённые в функциях, называются локальными переменными. Локальные переменные создаются при входе в функцию и уничтожаются при выходе из неё. Поэтому локальные переменные не могут содержать значения между вызовами функций. Единственным исключением из этого правила являются переменные, объявленные со спецификатором static. Все функции в С находятся на одном уровне видимости. То есть невозможно определить функцию в функции.
Аргументы функции
Если функция использует аргументы, она должна объявлять переменные, получающие значения аргументов. Данные переменные называются формальными параметрами функции. Они ведут себя так же, как и локальные переменные. Объявление параметров происходит после имени функции, но перед открывающей скобкой функции.
Передача по значению и передача по указателю
Обычно функции могут передавать аргументы двумя способами. Первый называется передачей по значению. Данный метод копирует содержимое аргумента в формальный параметр функции. Изменения, сделанные в параметре, не влияют на значение переменной, используемой при вызове. Передача по указателю является вторым способом передачи аргументов. В данном методе копируется адрес аргумента. В функции адрес используется для доступа к настоящему аргументу, используемому при вызове. То есть, изменения, сделанные в параметре, влияют на содержимое переменной, используемой при вызове. Рассмотрим следующую функцию:
#include <stdio.h>
int sqr(int x);
int main(void) { int t=10;
printf(“%d %d”, sqr(t), t); return 0; } int sqr(int x) { x = x*x; return x; }
На экране появится 100 10.
|
||||
Последнее изменение этой страницы: 2016-08-15; просмотров: 367; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.147.57.239 (0.007 с.) |