void main(void)

       {  int i, j, n, m, a[50][50];

        puts(“\n Input n, m:”); 

  scanf(“%d %d”,&n,&m);

  printf(“\n Array a \n”);

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

                for(j=0; j<m; j++)

{

                a[i][j]=rnd*10-5;         // диапазон от –5 до 5

               printf(“%d%c“, a[i][j], (j= =m-1)?’\n’:’ ‘);

               }

               getch();

}

7.3. Строки

В алгоритмическом языке PASCAL существует отдельный тип данных – строка, который объявляется с атрибутом string. В языке Borland C++ отдельного типа данных «строки символов» нет. Работа со строками реализована путем использования одномерных массивов типа char, т. е. строка символов – это одномерный массив типа char, заканчивающийся нулевым байтом. Нулевой байт – это байт, каждый бит которого равен нулю, при этом для нулевого байта определена символьная константа ґ\0ґ (признак окончания строки или нуль-терминатор). Поэтому, если строка должна содержать k символов, то в описании массива необходимо указать k+1 элемент.

Например, описание: char a[7], означает, что строка содержит шесть символов, а последний байт отведен под нулевой.

НЕ нашли? Не то? Что вы ищете?

Строковая константа в языке С – это набор символов, заключенных в двойные кавычки. Например: “Лабораторная работа по строкам”. В конце строковой константы явно указывать символ ґ \0 ґ не нужно, так как это сделает компилятор языка С.

Строки можно инициализировать при декларировании, например:

       char S1[10]=”123456789”, S2[]=”12345”;

в последнем случае размер строки будет установлен по количеству символов.

Для ввода строки с клавиатуры дисплея используются две стандартные библи­отечные функции, прототипы которых приведены в файле stdio. h.

Функция scanf( ) вводит значения для строковых переменных  спецификатором ввода %S. Но надо помнить, что функция scanf( ) вводит символы до появления первого символа “пробел”.

Библиотечная функция gets( ), обеспечивает ввод строки с пробелами внутри этой строки. При этом ввод строки символов завершается нажатием клавиши ENTER.

Обе функции автоматически ставят в конец строки нулевой байт. И, кроме того, так как строка – это символьный массив, а имя массива – это указатель на его начало в памяти, то символ «&» перед именами строковых объектов при использовании этих функций указывать не надо.

Вывод строк производится функциями printf( ) или puts( ). Обе функции выводят символьный массив до первого нулевого байта. Функция printf( ) не переводит курсор после вывода на начало новой строки, программист должен предусмотреть такой перевод в строке формата. Функция puts( ) автоматически переводит курсор после вывода строковой информации в начало новой строки.

Остальные операции над строками выполняются с использованием стандартных функций. Декларации функций для работы со строками размещены в  файле string. h. Вот некоторые из наиболее часто используемых:

Функция strcpy(S1, S2) - копирует содержимое строки S2 в строку S1. Функция strcat(S1, S2) - присоединяет строку S2 к строке S1 и помещает ее в массив, где находилась строка S1, при этом строка S2 не изменяется. Нулевой байт, который завершал строку S1, заменяется первым символом строки S2.

3.Функция strcmp(S1, S2) сравнивает строки S1 и S2 и возвращает значение =0, если строки равны, т. е. содержит одно и то же число одинаковых символов; значение <0, если S1<S2;значение >0, если S1>S2.

4. Функция strlen(S) возвращает длину строки, при этом завершающий нулевой байт не учитывается.

Пример работы со строковыми данными

В программе  значение строки вводится с клавиатуры, затем введенная строка распечатывается в обратном порядке.

#include <stdio. h>

#include <string. h>

#include <conio. h>

void main(void)

{

  char s[100];         // объявление символьного массива

  int i, k;

  puts(" Введите исходную строку");

  gets(s);

  k=strlen(s);

  puts("  РЕЗУЛЬТАТЫ РАБОТЫ ПРОГРАММЫ \n");

  for (i=k; i>=0; i--)

  printf("%c",s[i]);  /* вывод элементов массива в обратном порядке */

  printf("\n Press any key...");

  getch();

}

Практическое занятие № 8

Тема. Указатели

Цель: Ознакомиться с основными понятиями, такими как указатели, рассмотреть операции над указателями, указатели на указатели, массивы указателей 

Краткие теоретические сведения по теме

8.1. Указатели и операции над адресами

       Обращение к  объектам  любого типа как операндам операций в языке Borland C++ может проводиться:

- по имени, как мы до сих пор делали;

- по указателю (косвенная адресация).

Указатель – это переменная, которая может содержать адрес некоторого объекта в памяти компьютера, например адрес другой переменной. И через указатель, установленный на переменную можно обращаться к участку оперативной памяти, отведенной компилятором под ее значения.

Указатель объявляется следующим образом:

тип *идентификатор;

Например: int *a, *d;

float *f;

Здесь объявлены указатели a, d, которые можно инициализировать адресами целочисленных переменных и указатель f, который можно инициализировать адресами вещественных переменных.

С указателями связаны две унарные операции:  & и *. Операция & означает «взять адрес» операнда (т. е. установить указатель на операнд). Данная операция допустима только над переменными. Операция * имеет смысл: «значение, расположенное по указанному адресу» и работает следующим образом:

- Определяется местоположение в оперативной памяти переменной типа указатель.

- Извлекается информация из этого участка памяти и трактуется как адрес переменной с типом, указанным в объявлении указателя.

- Производится обращение к участку памяти по выделенному адресу для проведения некоторых действий.

Пример 1:

int x,                 /* переменная типа int */

  *y;                /* указатель на элемент данных типа int */

y=&x;        /* y - адрес переменной x */

                 *y=1;        /* косвенная адресация указателем поля x

/* “по указанному адресу записать 1”, т. е. x=1;  */

  Пример 2:

int i, j=8, k=5, *y;

  y=&i;

  *y=2;                 /* i=2  */

  y=&j;                /* переустановили указатель на переменную j */

  *y+=i;                 /* j+=i,  т. е.  j=j+1 -> j=j+2=10 */

  y=&k;                /*переустановили указатель на переменную k */

  k+=*y;                /* k+=k, k=k+k = 10 */

  (*y)++;         /* k++,  k=k+1 = 10+1 = 11  */

Говорят, что использование указателя означает отказ от именования (разыменование)  адресуемого им объекта.

Отказ от именования объектов при наличии возможности доступа по указателю приближает язык Borland C++ по гибкости отображения «объект-память» к языку ассемблера.

       При вычислении адресов объектов следует учитывать, что идентификатор  массива  и  функции именует переместимую адресную константу (термин ассемблера), или константу типа указатель (термин языка Borland C++). Такую константу можно присвоить переменной типа указатель, но нельзя подвергать преобразованиям:

  int x[100], *y;

y=x;                 // присваивание константы переменной

...

x=y;                 // Ошибка: в левой части - указатель-константа

Указателю-переменной можно присвоить значение другого указателя либо выражения типа указатель с использованием, при необходимости операции приведения типа (приведение необязательно, если один из указателей имеет тип "void *").

  int i, *x;

  char *y;

  x=&i;         /* x  -> поле объекта int */

  y=(char *)x;         /* y  -> поле объекта char */

  y=(char *)&i;  /* y -> поле объекта char */

Рассмотрим фрагмент программы:

int a=5, *p, *p1, *p2;

p=&a;  p2=p1=p;

       ++p1; p2+=2;

printf(“a=%d, p=%d, p=%p, p1=%p, p2=%p.\n”,a, p,p, p1,p2);

Результат выполнения:

a=5, *p=5, p=FFC8, p1=FFCC, p2=FFD0.

Конкретные значения адресов зависят от ряда причин: архитектура компьютера, тип и размер оперативной памяти и т. д.

8.2. Операции над указателями (адресная арифметика)

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

  p # ie,  ##p,  p##,  p# = ie,

где p - указатель, ie - целочисленное выражение, # - символ операции '+' или '-'.

Значением таких выражений является увеличенное или уменьшенное значение указателя на величину ie*sizeof(*p). Следует помнить, что операции с указателями выполняются в единицах памяти того типа объекта, на который ссылается этот указатель.

Текущее значение указателя всегда ссылается на позицию некоторого объекта в памяти с учетом правил выравнивания для соответствующего типа данных. Таким образом, значение p#ie указывает на объект того же типа, расположенный в памяти со смещением на ie*sizeof(*p) позиций.

Разрешается сравнивать указатели и вычислять разность двух указателей. При сравнении могут проверяться отношения любого вида (">",">=","<","<=","==","!="). Наиболее важными видами проверок являются  отношения равенства или неравенства.

Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26