Мегаобучалка Главная | О нас | Обратная связь


Выражения с указателями



2016-09-16 538 Обсуждений (0)
Выражения с указателями 0.00 из 5.00 0 оценок




 

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

 

{ int i=123 *pi1=&i, *pi2;

 

// присваиваем указателю pi2 значение указателя pi1

pi2=pi1;

 

//выведем значения указателей:

printf(“ %p %p”, pi1, pi2);

 

}

В результате мы получим одно и то же значение адреса.

 

Указатели могут встречаться в выражениях, например:

 

int x=5, y, *px=&x;

 

y = *px + 5; // y получит значение 10

 

Приоритет у унарной операции разадресации * выше, чем у бинарных арифметических операций, поэтому при вычислении выражения *px + 5 вначале будет извлечено содержимое по адресу, хранящемуся в р ( то есть получено значение 5), а затем будет выполнена бинарная операция сложения.

 

Операции с указателями

 

С указателями можно использовать только следующие операции:

 

++ инкремента

- - декремента

+, - сложения и вычитания

Если к указателю применяются операции ++ или --, то указатель увеличивается или уменьшается на размер объекта, который он адресует:

 

тип *ptr;

 

ptr ++ = значение ptr + sizeof (тип)

 

ptr -- = значение ptr - sizeof (тип)

 

Например:

 

int i, *pi = &i;

 

float a, *pa =&a;

 

pi++; //значение указателя pi увеличивается на 2 байта, так как он адресует объект

//типа int, указатель сдвигается вправо на 2 байта

 

pa++; // значение указателя pa увеличивается на 4 байта, так как он адресует объект

//типа float, указатель сдвигается вправо на 4 байта

 

Одним из операндов операции сложения может быть указатель, другим должно быть целое число. Целое число складывается с указателем следующим образом:

 

тип *ptr;

 

int n;

 

ptr + n = значение ptr + n*размер типа

 

Например,

 

float a, *pa = &a;

 

pa = pa+3; // значение указателя pa будет увеличено на 12 байт (сдвиг указателя вправо)

 

Левым операндом операции вычитания может быть указатель, а правым операндом должно быть целое число:

 

тип *ptr;

 

int n;

 

ptr - n = значение ptr - n*размер типа

 

Например:

 

int i, *pi = &i;

 

pi=pi-5; // уменьшение значения указателя на 10 байт (сдвиг указателя влево)

 

 

Пример 3.Использование указателей в выражениях

 

#include <stdio.h>

 

void main (void)

 

 

{

int x=5,y,*px=&x; //указатель px инициализирован адресом переменной x

 

 

y=*px+5;

printf("y=%d значение указателя=%p\n",y,px);

 

y=*px++; //изменение значения указателя после его использования

printf("y=%d значение указателя=%p\n",y,px);

 

px=&x;

y=(*px)++; //изменение содержимого по адресу, хранящемуся в px

 

printf("y=%d значение указателя=%p значение, адресуемое указателем *px= %d\n",y,px,*px);

 

y=++*px; //изменение содержимого по адресу px на единицу

printf("y=%d значение указателя=%p\n",y,px);

 

}

 

Результаты работы этой программы имеют вид:

 

y=10 значение указателя=1561:1000

 

y=5 значение указателя=1561:1002

y=5 значение указателя=1561:1000 значение, адресуемое указателем*px= 6

y=7 значение указателя=1561:1000

 

 

УКАЗАТЕЛИ И МАССИВЫ

 

Между указателями и массивами существует прямая связь. Когда объявляется массив, например:

 

int arr [5];

 

то идентификатор массива arr определяется как константный указатель на первый (с индексом 0) элемент массива. Это означает, что имя массива содержит адрес элемента массива с индексом 0:

 

arr = &arr[0];

Так как идентификатор массива содержит адрес, то можно, например, записать:

 

int arr[ 5]; //объявление массива целых

 

int *parr; //объявление указателя на данное целого типа

 

parr = arr; // присваивавание указателю адреса первого элемента массива, то же, что

// и parr = &arr[0];

 

Связь между именем массива arr и указателем parr можно изобразить следующим образом:

 
 

 


arr[0] arr[1] arr[2] arr[3] arr[4]

 

Адрес элемента массива с индексом i может быть записан как

&arr[i], что эквивалентно записи parr+i

 

Значение элемента массива с индексом i может быть записано как

arr[i], что эквивалентно записи *(parr+i) или *(arr+i)

 

Все индексные выражения вида arr[i] компилятор преобразует к адресному представлению в соответствии с правилами выполнения операции сложения указателя с целой величиной:

 

arr[i]=*(arr+i) =* (arr + i* sizeof(int))

 

ВАЖНО.

Указатель – это переменная, и ее значение можно изменять в программе, например, можно записать:

 

parr++;

 

Операция parr++ означает сдвиг указателя на следующий элемент массива arr++, то есть на 2 байта. Если, например, до выполнения операции parr++ указатель был установлен на первый элемент массива, то в результате выполнения этой операции он окажется установленным на второй элемент:

 

 
 

 


arr[0] arr[1] arr[2] arr[3] arr[4]

 

 

Имя массива – константа. Значение адреса, которое хранит имя массива, изменять нельзя, поэтому ошибочной является следующая запись:

 

arr++;

 

 

Пример 4. Программа, в которой демонстрируется использование указателей на массив.

 

#include <stdio.h>

#include <conio.h>

#include <stdlib.h>

#include <time.h>

 

#define N 100 //максимально допустимое количество элементов в массиве

 

int main(void)

{

int a[N]; /* резервирование памяти под N элементов массива */

int i; //переменная, управляющая циклом

int *pa=a; //объявление указателя на данное целого типа

//и инициализация указателя адресом массива а

 

clrscr();

randomize();

//цикл заполнения массива случайными числами

for(i=0; i<N; i++)

*(pa+i) = random(101)-50; // присваивание элементу массива значения случайного

// числа из диапазона от -50 до 50

 

//цикл вывода элементов массива

printf("\n\n Массив выведен по 10 элементов в строке \n\n");

 

for(i=0; i<N; i++)

{

printf("%6d ", *(pa+i)); // вывод массива

if(i%10==9)

printf("\n");

}

getch();

 

return 0;

}

 

 

Пример 4. Программа, в которой организован ввод элементов массива в диалоговом режиме и вывод полученного массива. Используется указатель на массив.

 

#include <stdio.h>

#include <conio.h>

 

void main(void)

{

int i;

int a[10]; //объявление массива целых из десяти элементов

int *pa = a; //объявление указателя на данное целого типа и инициализация указателя

// адресом массива

clrscr();

 

//цикл ввода элементов массива в диалоговом режиме

for(i=0; i<10; i++)

{

printf("\nВведите элемент массива с индексом %d ",i);

scanf("%d", pa+i); //функция scanf получает адрес элемента массива

}

 

printf("\n\n Вы ввели массив \n\n");

 

for(i=0; i<10; i++)

printf("%4d ", *(pa+i)); // вывод массива

 

getch();

 

}

 

 

Пример 5.Программа, в которой используются указатели на строки.

 

#include <stdio.h>

 

void main(void)

{

char s[]="строка как массив";

char *ps=s; //указатель ps инициализирован значением адреса строки s

char *ps1,*ps2,*ps3; //объявление указателей на строки

 

//присвоение указателю ps1 адреса строковой константы

ps1="В языке си в одну\n"

"строку можно записать\n"

"целое стихотворение\n";

 

//присвоение указателю ps2 адреса строковой константы

ps2="предложение не будет\

перенесено на следующую строку";

 

//присвоение указателю ps3 адреса строковой константы

ps3="одна"

" строка";

 

//цикл вычисления длины строки s, адрес которой хранит указатель ps

// выполнять, пока не найден конец строки

while(*ps!='\0')

ps++;

 

printf("длина строки= %d\n",ps-s);

 

puts(ps1);

puts(ps2);

puts(ps3);

}

 

 



2016-09-16 538 Обсуждений (0)
Выражения с указателями 0.00 из 5.00 0 оценок









Обсуждение в статье: Выражения с указателями

Обсуждений еще не было, будьте первым... ↓↓↓

Отправить сообщение

Популярное:
Почему двоичная система счисления так распространена?: Каждая цифра должна быть как-то представлена на физическом носителе...
Личность ребенка как объект и субъект в образовательной технологии: В настоящее время в России идет становление новой системы образования, ориентированного на вхождение...
Модели организации как закрытой, открытой, частично открытой системы: Закрытая система имеет жесткие фиксированные границы, ее действия относительно независимы...



©2015-2024 megaobuchalka.ru Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. (538)

Почему 1285321 студент выбрали МегаОбучалку...

Система поиска информации

Мобильная версия сайта

Удобная навигация

Нет шокирующей рекламы



(0.008 сек.)