Демонстрационный пример. Указатели и массивы

Решение задач на языке программирования C

Этот пример поможет закрепить понимание, как работать с указателем на массив. В выводе программы обратите внимание, адреса различаются между собой на 4 байта, т.е. переменная типа int занимает 4 байта. Также из примера можно удостовериться, что элементы массива располагаются в памяти последовательно друг за другом.

& - операция взятия адреса переменной;
* - операция извлечения значения по указанному адресу; применяется к переменным, содержащим адрес (т.е. к указателям).

Когда переменная-указатель объявляется (например, int *q), перед ее именем также ставится знак *. Однако в данном контексте он просто сообщает, что данная переменная - это указатель, и знак * не имеет отношения к извлечению значения.

#include <stdio.h>
 
main () {
	// объявление массива и его инициализация
	int arr[10] = {101, 102, 103, 104, 105, 106, 107, 108, 109, 110};
	int *p, *q; // указатели на тип int
	int i;
 
	printf("Массив: ");
	for (i = 0; i < 10; i++)
		printf(" [%d]=%d|", i, arr[i]);
	printf("\n\n");
 
// 1 ----------------------------------------------------------------------
	p = &arr[0];
	printf("Адрес 1-го элемента массива (p): %p\n", p);
	printf("Значение 1-го элемента массива (*p): %d\n", *p);
 
	q = p + 1;
	printf("Адрес 2-го элемента массива (q): %p\n", q);
	printf("Значение 2-го элемента массива (*q): %d\n", *q);
 
	q = q + 2;
	printf("Адрес 4-го элемента массива (q): %p\n", q);
	printf("Значение 4-го элемента массива (*q): %d\n", *q);
	printf("\n");
 
// 2 ---------------------------------------------------------------------
	// имя массива является указателем не его первый элемент
	printf("Адрес 1-го элемента массива (arr): %p\n", arr);
	printf("Значение 1-го элемента массива (*arr): %d\n", *arr);
	// Поэтому ...
	p = arr + 2; // то же самое, что p = &arr[0] + 2
	printf("Адрес 3-го элемента массива (arr + 2): %p\n", p);
	printf("Значение 3-го элемента массива (*(arr+2)): %d\n", *p);
	printf("Адрес 6-го элемента массива (p + 3): %p\n", p+3);
	printf("Значение 6-го элемента массива (*(p+3)): %d\n", *(p+3));
	printf("\n");
 
// 3 --------------------------------------------------------------------
	// указатель можно употреблять в выражениях с индексом
	p = arr;
	printf("Значение 10-го элемента массива (p[9]): %d\n", p[9]);
	printf("\n");
 
// 4 --------------------------------------------------------------------
	p = arr; // arr++ использовать нельзя, a p++ можно
	for (i = 0; i < 10; i++, p++)
		printf("%2d-й: %p    %d\n", i+1, p, *p);
}

Вывод программы:

Массив:  [0]=101| [1]=102| [2]=103| [3]=104| [4]=105| [5]=106| [6]=107| [7]=108| [8]=109| [9]=110|

Адрес 1-го элемента массива (p): 0x7fff5c4c0d60
Значение 1-го элемента массива (*p): 101
Адрес 2-го элемента массива (q): 0x7fff5c4c0d64
Значение 2-го элемента массива (*q): 102
Адрес 4-го элемента массива (q): 0x7fff5c4c0d6c
Значение 4-го элемента массива (*q): 104

Адрес 1-го элемента массива (arr): 0x7fff5c4c0d60
Значение 1-го элемента массива (*arr): 101
Адрес 3-го элемента массива (arr + 2): 0x7fff5c4c0d68
Значение 3-го элемента массива (*(arr+2)): 103
Адрес 6-го элемента массива (p + 3): 0x7fff5c4c0d74
Значение 6-го элемента массива (*(p+3)): 106

Значение 10-го элемента массива (p[9]): 110

 1-й: 0x7fff5c4c0d60    101
 2-й: 0x7fff5c4c0d64    102
 3-й: 0x7fff5c4c0d68    103
 4-й: 0x7fff5c4c0d6c    104
 5-й: 0x7fff5c4c0d70    105
 6-й: 0x7fff5c4c0d74    106
 7-й: 0x7fff5c4c0d78    107
 8-й: 0x7fff5c4c0d7c    108
 9-й: 0x7fff5c4c0d80    109
10-й: 0x7fff5c4c0d84    110