Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Тема11_Указатели.doc
Скачиваний:
1
Добавлен:
03.09.2019
Размер:
113.15 Кб
Скачать

Указатели и массивы

Имя массива является указателем на его первый элемент, поэтому обратиться к первому элементу можно так *mas и эта запись эквивалента mas[0]. Для обращение к элементу с индексом I можно воспользоваться записью *(mas+i) и это будет эквивалентно mas[i].

int mas[] = {10,20,30,40,50};

printf("%9s%9s%9s\n", "Индекс", "Значение", "Адрес");

for (int i=0; i<5; i++) {

printf("%9d%9d%9d\n", i, mas[i], &mas[i]);

}

int mas[] = {10,20,30,40,50};

printf("%9s%9s%9s\n", "Индекс", "Значение", "Адрес");

for (int i=0; i<5; i++) {

printf("%9d%9d%9d\n", i, *(mas+i), mas+i);

}

Передача массивов в качестве аргументов функций

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

int getSum(int* numbers, int size) {

int result = 0;

for (int i=0; i<size; i++) {

result += numbers[i];

}

return result;

}

int myNumbers[] = {1,2,3,4,5,6,7,8};

printf("%d\n", getSum(myNumbers, 8));

36.

Поскольку все корректные строки завершаются нуль-символом, то передавать в функцию аргументом размер массива не нужно. Функция, принимающая строку в качестве аргумента, может иметь такой вид:

int vowels(char* word) {

int result = 0;

for (int i=0; i<strlen(word); i++) {

if (isVowel(word[i])) {

result++;

}

}

return result;

}

Динамическое распределение памяти

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

Данную проблему можно решить путем выделения памяти с запасом. Например, зная, что длина слов, с которыми предстоит работа, не превышает 10, то выделить память нужно под них, а по факту использовать меньше.

int* ptr;

int size;

printf("Введите размер: ");

scanf("%d",&size);

ptr = new int[size];

for (int i=0; i<size; i++) {

*(ptr+i) = rand();

}

for (int i=0; i<size; i++) {

printf("%-7d\n", ptr[i]);

}

Почему в scanf() ставится амперсанд

void set7(int x) {

x=7;

}

int main() {

int x=10;

set7(x);

printf("%d", x);

}

void set7(int* ptr) {

*ptr=7;

}

int main() {

int x=10;

set7(&x);

printf("%d", x);

putchar('\n');

}

Передача аргументов по значению и по ссылке

Представьте себе ситуацию, когда необходимо передать некоторый предмет, скажем, книгу своему коллеге по работе. Сделать это можно двумя способами: либо передать эту книгу лично из рук в руки, либо положить это книгу в ящик стола и сообщить коллеге, что книга находится там. В первом случае книга передается фактически, а во втором вы «передаете» ссылку на книгу вместо самой книги. Результат по большому счету одинаков в обоих случаях: предмет доставлен адресату. Тем не менее, удобство и эффективность этих двух способов существенным образом зависит от того, насколько далеко друг от друга находятся взаимодействующие стороны, насколько велик и тяжел передаваемый предмет и т.д.

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

Структуры и указатели

Структура – это тип данных, хотя и составной:

struct worker {

char name[20];

int age;

};

Можно создать массив, элементами которого являются структуры:

worker workers[] = {

{"John", 30},

{"Maria", 33},

{"Jim", 23}

};

Можно также объявить указатель на структуру:

worker* ptr;

и присвоить ему указатель на массив:

ptr = worker;

обратиться к полю структуры

for (int i=0; i<3; i++) {

printf("%s\t%d\n", (*ptr).name, (*ptr).age);

printf("%s\t%d\n\n", ptr->name, ptr->age);

ptr++;

}

}