Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели



страница4/8
Дата29.04.2013
Размер0.57 Mb.
ТипПрактикум
1   2   3   4   5   6   7   8

s[i] = c;

if (c == '\n') {

s[i] = c;

++i;

}

s[i] = '\0';

return(i);

}

copy(s1, s2) /* copy s1 to s2;

assume s2 big enough */

char s1[], s2[];

{

int i;

i = 0;

while ((s2[i] = s1[i] != '\0')

++i;

}

Функция main и getline общаются как через пару аргументов, так и через возвращаемое значение. Аргументы getline описаны в строках char s[]; int lim; которые указывают, что первый аргумент является массивом, а второй – целым.

Длина массива s не указана, так как она определена в main .Функция getline использует оператор return для передачи значения назад в вызывающую программу точно так же, как это делала функция power. Одни функции возвращают некоторое нужное значение; другие, подобно copy, используются из–за их действия и не возвращают никакого значения.

Чтобы пометить конец строки символов, функция getline помещает в конец создаваемого ей массива символ \0 (/нулевой символ, значение которого равно нулю). Это соглашение используется также компилятором с языка "C": когда в "C" - программе встречается строчная константа типа "hello\n" . тo компилятор создает массив символов, содержащий символы этой строки, и заканчивает его символом \0, с тем чтобы функции, подобные printf, могли афиксировать конец массива:

----------------------------------

| h | e | l | l | o | \n | \0 |

----------------------------------
Спецификация формата %s указывает, что printf ожидает строку, представленную в такой форме. Проанализировав функцию copy, Вы обнаружите, что и она опирается на тот факт, что ее входной аргумент оканчивается символом \0, и копирует этот символ в выходной аргумент s2. Все это подразумевает, что символ \0 не является частью нормального текста.

Между прочим, стоит отметить, что даже в такой маленькой программе, как эта, возникает несколько неприятных организационных проблем. Например, что должна делать main, если она встретит строку, превышающую ее максимально возможный размер? Функция getline поступает разумно: при заполнении массива она прекращает дальнейшее извлечение символов, даже если не встречает символа новой строки. Проверив полученную длину и последний символ, функция main может установить, не была ли эта строка слишком длинной, и поступить затем, как она сочтет нужным. Ради краткости мы опустили эту проблему.
Пользователь функции getline никак не может заранее узнать, насколько длинной окажется вводимая строка. Поэтому в getline включен контроль переполнения.
в то же время пользователь функции copy уже знает /или может узнать/, каков размер строк, так что мы предпочли не включать в эту функцию дополнительный контроль.

В заключении приведем еще несколько полезных программ.

На втором занятии требуется проверить и .....

Пример 8. Программа, определяющая номер позиции, начиная с которой вторая строка является подстрокой первой строки.

/* index */

#include "string.h"

main ()

{

char *t1, *t2;

int l, l1, l2, i, j;

printf ("Программа, определяющая номер позиции,\n");

printf ("начиная с которой вторая\n");

printf ("строка является подстрокой первой строки.\n");

printf ("введите 1-ю строку\n"); gets (t1);

printf ("введите 2-ю строку\n"); gets (t2);

l1=strlen(t1);

l2=strlen(t2);

for ( i=0; i

for ( j=0; j

if ( j == l2 ) /* нашли совпадение ? */

{

printf ("позиция %d", i);

exit (0);

}

printf ("не является под строкой");

exit (1);

}
Пример 9. Программа сравнения двух символьных строк на совпадение.

/* string compare */

main ()

{

char s1 [100], s2 [100];

int i;

printf ("Программа сравнения двух символьных строк на совпадение.\n");

printf ("введите 1-ю строку\n"); gets (s1);

printf ("введите 2-ю строку\n"); gets (s2);

for ( i=0; s1[i] && s2[i] && s1[i] == s2[i]; ++i )

;

if ( s1[i] == s2[i] )

printf ("совпадают");

else

printf ("не совпадают");

}

Пример 10. Программа, печатающая строку в обратном направлении.

*/

/* string inverse */

void strinv (s) /* функция инверсии строки */

char *s;

{

char *p = s;

while ( *p ) /* поиск конца строки */

p++;

p --; /* последний ненулевой */

while ( s < p )

{

char x = *s; *s = *p; /* меняются равноотстоящие */

*p = x; p--; s++; /* от концов символы */

}

}

void main ()

{

char *q;

printf ("Программа, печатающая строку в обратном направлении.\n");

q = "пример другой строки";

printf ("%s\n", q);

strinv (q);

printf ("%s\n", q);

}

Пример 11. Программа для определения являются ли символы цифрами или прописными буквами.

/* isdigit , isupper */
int isdigit ( x ) /* аргумент цифра? */

char x;

{

return (x>='0' && x<='9') ? 1 : 0 ;

}

int isupper ( x ) /* аргумент прописная латинская буква? */

char x;

{

return (x>='A' && x<='Z') ? 1 : 0 ;

}

main ()

{

printf ("Программа для определения являются ли символы цифрами или\n");

printf ("прописными буквами.\n");

printf ("символ e %s\nсимвол 3 %s\nсимвол Z %s\nсимвол a %s",

( isdigit('e')?"цифра":"не цифра"),

( isdigit('3')?"цифра":"не цифра"),

( isupper('Z')?"прописная":"строчная"),

( isupper('a')?"прописная":"строчная"));

}

Пример 12. Программа, содержащая несколько функций для обработки строк:

strcpy – копирование строки в другую,

strlen – определение длины,

strcat – присоединение одной строки к другой,

strcmp – лексикографическое сравнение строк.

/* strings manipulation */
void strcpy (s,t) /* копирование строки */

char *s, *t;

{

while ( *s++ = *t++ )

;

}

int strlen (s) /* длина строки */

char *s;

{

char *p = s;

while ( *p ) /* while ( *p++ ) */

p++; /* ; */

return (p-s); /* return p-s-1; */

}

void strcat (s,t) /* присоединение строки */

char *s, *t;

{

while ( *s ) /* поиск конца строки s */

s++;

while ( *s++ = *t++ ); /* копирование */

}

int strcmp (s,t) /* сравнение строк */

char *s, *t;

{

for ( ; *s == *t; s++, t++ ) /* = 0 строки совпадают */

if ( *s == '\0' ) /* < 0 s < t | лексикогра */

return (0); /* > 0 s > t | фически */

return (*s-*t);

}

main ()

{

char *p, *q; int l = 0, m = 0;

printf ("Программа, содержащая несколько функций для обработки строк:\n");

printf ("strcpy – копирование строки в другую,\n");

printf ("strlen – определение длины,\n");

printf ("strcat – присоединение одной строки к другой,\n");

printf ("strcmp – лексикографическое сравнение строк.\n");

p = "string 1";

printf ("строка p =%s\n", p);

strcpy (q,p);

printf ("строка q после копирования =%s\n", q);

l = strlen (q);

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

p = "string 2";

printf ("строка p =%s\n", p);

strcat (q,p);

printf ("строка q после соединения с p=%s\n", q);

l = strlen (q);

printf ("длина q %d\n", l);

printf ("строки p и q %s", (strcmp (q,p)?"не совпадают":"равны"));

}

Задание

1. Напишите программу для подсчета пробелов, табуляций и новых строк.

2. Напишите программу, которая копирует ввод на вывод, за- меняя при этом каждую последовательность из одного или более пробелов на один пробел.

3. Как бы Вы стали проверять программу подсчета слов? Какие имеются ограничения ?

4. Напишите программу, которая будет печатать слова из файла ввода, причем по одному на строку.

5. Переделайте программу подсчета слов, используя лучшее определение "слова"; считайте, например словом последовательность букв, цифр и апострофов, начинающуюся с буквы.

6. Напишите программу, печатающую гистограмму длин слов из файла ввода. Самое легкое – начертить гистограмму горизонтально; вертикальная ориентация требует больших усилий.

7. Переделайте ведущую часть программы поиска самой длинной строки таким образом, чтобы она правильно печатала длины сколь угодно длинных вводимых строк и возможно больший текст.

8. Напишите программу печати всех строк длиннее 80 символов.

9. Напишите программу, которая будет удалять из каждой строки стоящие в конце пробелы и табуляции, а также строки, целиком состоящие из пробелов.

10. Напишите функцию reverse(s), которая распологает символьную строку s в обратном порядке. С ее помощью напишите программу, которая обратит каждую строку из файла ввода.

11. Напишите программу удаления из "C"–программы всех комментариев. Не забывайте аккуратно обращаться с "закавыченными" строками и символьными константами.

  1. Напишите программу проверки "C"-программы на элементарные синтаксические ошибки, такие как несоответствие круглых, квадратных и фигурных скобок. Не забудьте о кавычках, как одиночных, так и двойных, и о комментариях. (Эта программа весьма сложна, если Вы будете писать ее для самого общего случая).


Лабораторная работа № 10

Массивы и указатели

Массив - это объект, состоящий из элементов одного типа и расположенных в памяти подряд. Синтаксис определения одномерного массива следующий:

Тип Имя_массива [константа или константное выражение];

Имя массива - идентификатор, выражение в квадратных скобках определяет количество элементов массива и поэтому обязано быть целого типа. Массив должен быть определен до его использования, так как компилятору нужно “знать” какую область памяти выделить для хранения элементов массива. Исключение составляют динамически размещаемые в памяти массивы. Описание массива без указания размера может также использоваться в списке формальных параметров определения функции и в спецификациях параметров прототипа функции. В этом случае его размер определяется по размеру массива в вызывающей функции.

Нумерация элементов массива начинается с нуля. Номер элемента массива обычно называют индексом. При определении массива может выполняться инициализация его элементов. Если она явно не производится, то компилятор неявно присваивает всем неинициализированным элементам массива нулевые значения. Например, предложение: float A[5]; определяет массив, состоящий из 5 вещественных переменных типа float. Все элементы этого массива компилятор обнулит.

Имя массива является указателем-константой, значением которой служит адрес элемента с индексом 0. Перемещение указателя от одного элемента к другому выполняется в порядке увеличения его индекса, и обратиться к какому либо элементу массива можно по этому индексу. При этом запись имя_массива [индекс] является на самом деле выражением. Например, A[i] означает *(A+i).

Обратите внимание на разный смысл, который имеют квадратные скобки [] при определении массива и при обращении к элементу массива. В операторе описания типа квадратные скобки [] служат модификаторами типа, которые определяют размеры и размерность массива. В остальных случаях [] - это бинарная операция над именем массива и индексом, которая возвращает значение объекта, расположенного по адресу, равному сумме адреса нулевого элемента и смещения, вычисляемого как i*sizeof(тип элементов массива A). Так как сложение - коммутативная операция, выражения *(A+i) и *(i+A) являются эквивалентными. А это означает, что A[i] именует тот же объект, что и i[A]. Таким образом, обратиться к элементу массива можно либо явно с использованием операции разыменования, либо неявно с использованием операции индексирования. Следующая программа [2] иллюстрирует обе возможности.
Пример 1.

/*Program 9.1*/

#include

void main()

{

float A[5] = { 10., 20., 30., 40. } ; // (1)

int i = 1; // (2)

printf(“\n A[i] = %2f”, A[i] ); // (3)

printf(“\n *(A+i) = %2f”, *(A+i) ); // (4)

printf(“\n *(i+A) = %2f”, *(i+A) ); // (5)

printf(“\n i[A] = %2f”, i[A] ); // (6)

printf(“\n A[0] = %2f 0[A] = %2f”, A[0], 0[A] ); // (7) printf(“\n A[1] = %2f 1[A] = %2f”, A[1], 1[A] ); // (8)

printf(“\n A[2] = %2f 2[A] = %2f”, A[2], 2[A] ); // (9)

printf(“\n A[3] = %2f 3[A] = %2f”, A[3], 3[A] ); // (10)

printf(“\n A[4] = %2f 4[A] = %2f”, A[4], 4[A] ); // (11)

printf(“\n *(A + i++) = %2f”, *(A + i++) ); // (12)

printf(“\n *(++i + A) = %2f”, *(++i + A) ); // (13)

printf(“\n *(i-- + A) = %2f”, *(i-- + A) ); // (14)

printf(“\n i--[A] = %2f”, i--[A] ); // (15)

printf(“\n--i[A] = %2f”, --i[A] ); // (16)

}
В строке (1) определяется массив A, состоящий из 5 простых переменных типа float. Первый элемент массива A[0] инициализируется значением 10. Второй элемент A[1] - значением 20, третий A[2] - значением 30., четвертый A[3] - значением 40. . Наконец, последний пятый элемент массива явно не инициализируется, поэтому компилятор занесет в него значение 0. В строке (15) в соответствии с приоритетом выполнения операций в выражении i--[A] сначала вычисляется i[A] , а затем i-- . В строке (16) в выражении --i[A] сначала вычисляется i[A], а затем результат уменьшается на единицу. (Смотри задание 20 лабораторной работы N6.3.)

Так как имя массива - это указатель-константа, то значение имени невозможно изменить. Например, выражение *(++A) - ошибочно.

Операция sizeof, примененная к имени массива, возвращает размер области памяти, занимаемый всем масивом, т.е. число равное числу элементов массива, умноженному на sizeof(тип элемента массива). Например, для массива A, описанного выше, операция sizeof(A) возвратит 20 (байт). Следовательно, отношение sizeof(имя) / sizeof(тип элементов ) равно числу элементов в массиве.
Пример 2.
1   2   3   4   5   6   7   8

Похожие:

Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconЛабораторная работа №1 36 Лабораторная работа №2 47 введение данное учебно-методическое пособие представляет собой сборник лабораторных работ
Предлагаемый лабораторный практикум является руководством для выполнения лабораторных работ. Практикум охватывает основные темы дисциплины....
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconЛабораторная работа по теме: «Одномерные массивы»
Дан массив целых чисел. Найти максимальный элемент массива и его порядковый номер
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconЛабораторная работа №1 Работа в Oracle Database Express Edition 1 Лабораторная работа №6
Лабораторная работа Выполнение расчетов с использованием программирования в среде Visual Basic for Applications
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconПрактикум по курсу Информатика (раздел Работа с пакетами прикладных программ) для студентов заочной формы обучения
Лабораторная работа №6. Обобщение данных. Создание таблицы подстановки. Подведение итогов 28
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconК ф. м н. А. О. Беляков. Список публикаций
Замечания к статье Л. Д. Акуленко и С. В. Нестерова "Устойчивость равновесия маятника переменной длины". Пмм. 2009. Т. 73. Вып. С....
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconРабочая учебная программа «История и культура страны изучаемого языка»
Форма контроля: 1 курс, второй семестр – зачет; 2 курс, третий семестр – экзамен
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconРабочая учебная программа «История и культура страны изучаемого языка»
Форма контроля: 1 курс, второй семестр – зачет; 2 курс, третий семестр – экзамен
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconПрактикум по гидробиологии Выписка из учебного плана. Форма обучения: очная Курс: IV семестр: VII
Реквизиты составителя. Доцент кафедры зоологии, к б н. Анастасия Михайловна Ларионова
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconЛабораторная работа «Одномерные массивы»
Цели: формирование практических умений и навыков составления блок-схем и записи на языке программирования Паскаль алгоритмов заполнения,...
Практикум по пмм ( 2 курс, 3 семестр ) Волгоград, 1998 Лабораторная работа №1 Массивы и указатели iconПрактикум по герпетологии Выписка из учебного плана. Форма обучения: очная Курс: IV семестр: VIII
Реквизиты составителя. Старший преподаватель кафедры зоологии Василий Егорович Колодезников
Разместите кнопку на своём сайте:
ru.convdocs.org


База данных защищена авторским правом ©ru.convdocs.org 2016
обратиться к администрации
ru.convdocs.org