Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Изучение Си после Паскаля.rtf
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.01 Mб
Скачать

Работа с указателями: операции взятия адреса и разыменования адреса

В Си указатели объявляются так:

ТИП * ИМЯ_УКАЗАТЕЛЯ;

То есть, если c и d - указатели на целое, то в Паскале их объявят так:

a :^Integer; {Указатель на целое число}

b :^Integer; {Указатель на целое число}

а в Си так:

int *a; //Указатель на целое число

int *b; //Указатель на целое число

Рассмотрим следующий фрагмент программы:

1> var

2> x1, x2, y1, y2: integer;

3> begin

4> x1 := 13;

5> x2 := 3;

6> divide(x1, x2, @y1, @y2);

В строке 6 к переменным y1 и y2 применяются операции взятия адреса @, которые возвращают указатели на эти переменные (адреса переменных).

В Си операция взятия адреса обозначается знаком &. Аналогичный фрагмент программы на Си будет выглядеть так:

int x1 = 13;

int x2 = 3;

int y1, y2;

divide(x1, x2, &y1, &y2);

Рассмотрим реализацию на Паскале функции divide с использованием указателей:

1> procedure divide(a, b: integer; c, d: PInteger);

2> begin

3> c^ := a div b;

4> d^ := a mod b;

5> end;

В строках 3 и 4 к параметрам c и d, которые имеют тип указатель на целое, применяются операции разыменования адреса ^. Операция разыменования адреса может быть применена только к указателю. В результате выполнения этой операции получается переменная, адрес которой хранит этот указатель.

В результате выполнения строк 3 и 4 в переменные y1 и y2 будут занесены значения частного и остатка от деления соответственно.

В Си операция разыменования адреса обозначается знаком *. Процедура divide на Си будет выглядеть так:

void divide(int a, int b, int * c, int * d)

{

*c = a / b;

*d = a % b;

}

Полный текст примера на Си будет выглядеть так:

#include <stdio.h>

/*Процедура делит a на b.

В c заносится частное, в d – остаток от деления.*/

void divide(int a, int b, int * c, int * d)

{

*c = a / b;

*d = a % b;

}

int main()

{

int x1 = 13;

int x2 = 3;

int y1, y2;

divide(x1, x2, &y1, &y2);

printf("\n\n%d / %d = %d\n", x1, x2, y1);

printf("%d %% %d = %d\n", x1, x2, y2);

return 0;

}

Ввод в языке си Функция getch – ввод символа

Функция getch возвращает код нажатой клавиши. Эта функция не входит в стандарт Си, но во многих реализациях Си она есть. Есть она и в Borland C++ 3.

Функция getch имеет прототип (общий вид):

int getch();

Действие функции полностью эквивалентно действию функции readkey в Turbo Pascal’e.

Функция scanf - форматированный ввод

Функция SCANF аналогична по выполняемым действиям процедуре READ в Паскале.

В использовании функция SCANF аналогична функции PRINTF. Так же, как и в PRINTF, первым параметром SCANF является форматная строка, в которой при помощи спецификаторов преобразования указываются типы вводимых параметров (%d – десятичное int, %Lf – long double). Принципиальное отличие SCANF от PRINTF в использовании – то, что в PRINTF нужно передавать выводимые значения, а в SCANF - указатели на вводимые переменные.

Пример. Нужно для двух введенных целых чисел вывести на экран их среднее арифметическое.

#include <stdio.h>

int main()

{

int a, b;

float sr;

printf(“\n\nВведите a =”);

scanf(“%d”, &a); // %d - вводится параметр целого типа.

// В функции scanf параметр a должен измениться

// (его значение вводится с клавиатуры).

// Для того, чтобы обеспечить изменение a,

// в scanf передается указатель на a.

printf(“Введите b =”);

scanf(“%d”, &b);

sr = (a + b) / 2.0;

printf(“Среднее арифметическое = %f\n”, sr);

return 0;

}