Некоммерческое Акционерное общество

АЛМАТИНСКИЙ УНИВЕРСИТЕТ ЭНЕРГЕТИКИ И СВЯЗИ

Кафедра «Компьютерные технологии» 

 

 

ПРОГРАММИРОВАНИЕ НА АЛГОРИТМИЧЕСКИХ ЯЗЫКАХ

Часть 2

Методические  указания к лабораторным работам  для студентов всех видов обучения  специальности

 5В070400 - «Вычислительная техника и программное обеспечение»

 

 

                                       

Алматы, 2011 

СОСТАВИТЕЛИ: З.К.Куралбаев, З.А.Акижанова. «Программирование на алгоритмических языках». Часть 2. Методические  указания к лабораторным работам  для студентов всех видов обучения  специальности 5В070400 - «Вычислительная техника и программное обеспечение».– Алматы: АУЭС, 2011. – 31 с.

 

Методические указания предназначена студентам для выполнения в компьютерных классах лабораторных работ по дисциплине «Программирование на алгоритмических языках». Для каждой работы в соответствии с ее  темой приведены указания по составлению алгоритмов и программ на языке Си, необходимые студентам  при выполнении индивидуальных заданий. 

Методические указания предназначены для студентов всех видов обучения специальности 5В070400 - «Вычислительная техника и программное обеспечение».

Литература – 11 назв.

 

Рецензент: канд. техн. наук Е.Г. Сатимова

 

Печатается по  плану издания некоммерческого акционерного общества «Алматинский университет энергетики и связи» на 2011 г.

 

© НАО «Алматинский университет энергетики и связи», 2011 г.

 

Содержание 

Введение 

4

Лабораторная работа № 1.  Основы программирования простейших алгоритмов на языке Си                                                       

4

 

Лабораторная работа № 2. Программирование циклических алгоритмов на языке Си                                                                    

7

 

Лабораторная работа № 3.  Замены в тексте программы                

11

Лабораторная работа №4.  Указатели и операции над ними           

15

Лабораторная работа №5.  Программирование  на языке Си         

алгоритмов, связанных с одномерными массивами                          

19

 

Лабораторная работа №6. Указатели элементов массива                  

22

Лабораторная работа №7. Программирование многомерных массивов                                                                                          

25

Лабораторная работа №8.  Обработка текстов на языке Си

28

Список литературы                                                                              

32

                                                                                          

Введение

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

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

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

1) Наименование лабораторной работы и постановка индивидуального задания.

2) Алгоритм задания.

3) Основные обозначения.

4) Текст программы  (листинг).

5) Решение задания (результат).

6) Анализ результата и выводы.

 

Лабораторная работа №1. Основы программирования простейших алгоритмов на языке Си

 

Цель работы: ознакомить студентов  с основами языка Си и дать  навыки программирования простейших (линейных и разветвляющихся) алгоритмов.

 

Контрольные вопросы:

1) С помощью какой препроцессорной команды  осуществляется включение в текст программы библиотечные функции ввода-вывода?

2)  Из каких частей состоит программа на языке Си?

3)  Для чего ставится метка перед оператором?

         4)  В каких случаях используется оператор  условного перехода?

5) Для чего нужен пустой оператор?

6)   Как называется главная функция в программе на языке Си?

7)  Что такое тело функции?

8) Какая функция используется для вывода результата выполнения программы на языке Си?   

9) Для чего используется директива  #include?

10) Какая функция используется  в программе на языке Си для ввода данных с клавиатуры?

 

Методические указания и упражнения

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

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

#include<stdio.h>

#include< math.h >

void main()

{    double a,b,c,p,s;

      printf(“\n a=”);   scanf(“%lf”, &a”);

      printf(“\n b=”);   scanf(“%lf”,&b);

      printf(“\n c=”);   scanf(“%lf”, &c;

      p=(a+b+c)/2;   s= sqrt (p*(p-a)*(p-b)*(p-c)); printf(“\n ploshad: s=%f”, s);

}

Для ввода значений параметров a,b,c в программе использован  модификатор l.  Необходимо ввести значения этих параметров и получить результат вычисления.  Следует обратить внимание, что при вводе значений длин сторон треуогольника необходимо следить за выполнением свойства треугольника, что сумма двух сторон должна быть больше длины третьей стороны.

В данной программе кроме директивы #include<stdio.h> использована директива #include<math.h>. Потому что в программе используется математическая функция для вычисления квадратного корня sqrt().

Пример 2. Решение квадратного уравнения. В качестве примера реализации разветвляющегося алгоритма рассматривается процесс решения квадратного уравнения :

         #include<stdio.h>

         #include<math.h>

         void main()

{     double a,b,c,d,x1,x2;

       printf("\n a=");   scanf("%lf",&a);  printf("\n b=");   scanf("%lf",&b);

       printf("\n c=");    scanf("%lf",&c);    d=b*b-4*a*c;

  if(d>=0.0)

       {    x1=(-b+sqrt(d))/(2*a);   x2=(-b-sqrt(d))/(2*a);

             printf("\n Korni: x1=%e,x2=%e",x1,x2);    }

    else    printf("\n Deistvitelnych kornei net.");    }

Следует заметить, что иногда целесообразно использовать double вместо float.

Задания для самостоятельного выполнения:

№ 1. Написать программу, которая по дате определяет день недели, на который приходится эта дата. Вычисление производится по формуле:

 .

 

Остаток от деления А на число 7 определяет день недели (1-понедельник, 2-вторник, 3- среда, 4-четверг, 5-пятница, 6- суббота, 0-воскресенье).

kun   -  число;

aj   -  номер месяца , считать 1-март, 2- апрель,…февраль-12;

jyl  -  номер года в столетии;

juz  -  количество столетий.

Например, 1 сентября 2011 года; здесь kun=1, aj=7, jyl=11, juz=20. Тогда 

Остаток от деления 774 на 7 будет равен 4- четверг.

№ 2.  Написать программу, которая по коду товара и его количеству вычисляет его стоимость. Пример:

Товар

Код товара

Цена (тенге)

Помидоры

1

150

Капуста

2

45

Перец

3

100

Пусть код=1, вес=0.750кг, тогда стоимость=112.5 тенге.

№ 3.  Написать программу, которая для введенного значения радиуса круга и коэффициенту (числа 1, 2,…6) вычисляет площадь круга и длину окружности для этого радиуса или для радиуса, увеличенного в заданное количество раз (использовать оператор switch).

№ 4.  Составить программу, которая по двум введенным числам a и b и целому числу - коду  k  позволяет производить следующие  вычисления:  при  k=1- площадь прямоугольника со сторонами  a и b;  при  k=2 - площадь прямоугольного треугольника с катетами a и b;  при  k=3 – расстояние от начала координат до точки с координатами x= a и y=b; в остальных случаях печатает сообщение «код неверный».

№ 5.Написать программу, которая для введенного значения числа а и коду вычисляет площадь круга (код=1),  длину окружности (код=2), объем шара (код=3),  площадь квадрата (код=4). Заданное число а является радиусом или длиной стороны фигуры.

№ 6. Написать программу, которая по введенному номеру формулы вычисляет значение функции для заданных  a и b.

№ 7.  Написать программу, которая по введенному номеру года нашей эры выводит название года по старояпонскому календарю. В старояпонском календаре цикл состоял из 60 лет и делился на пять подциклов по 12 лет. Подциклы обозначались цветами (зеленый, красный, желтый, белый и черный).  Внутри  подцикла годы носили названия животных: крысы, коровы, тигра, зайца, дракона, змеи, лошади, овцы, обезьяны, курицы, собаки и свиньи (1984 - год зеленой крысы – был началом очередного цикла).

№ 8.    Написать программу, которая по введенному числу  от 20 до 99 выводит число в виде текста. Например, а=51,  выводит значение  в виде «пятьдесят один».

№ 9. Написать программу, которая по введенному числу  от  11 до 19, или от 111 до 119,  или от 211 до 219, … или от 911 до 919  выводит число в виде текста. Например, а=512,  выводит значение  в виде «пятьсот двенадцать».

 

Лабораторная работа №2.   Программирование циклических алгоритмов на языке Си

 

На языке Си также существуют операторы, обеспечивающие реализацию циклов, которые подобны операторам языка Паскаль. На языке Си используются операторы while, for, do.

 

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

 

Контрольные вопросы:

1) Назовите порядок записи операторов языка Си, предназначенные для организации циклов.

2)  Для чего нужна главная функция?

3)  Какая запись показана в выражении условия?

4) Какого типа переменные используются в качестве счетчика цикла?

5) Какая операция называется унарной?

 

Методические указания и упражнения

Оператор цикла while  имеет следующую структуру:

while (выражение условия)

тело цикла

Для того, чтобы показать порядок использования оператора цикла while, рассматривается  следующий  пример.

Пример 1. Бесконечная сумма. Вычислить следующую  сумму с заданной  точностью (ε>0):     b = .

Перед составлением программы необходимо ввести обозначение: r – текущее  слагаемое, оно вычисляеся по формуле r=r*x/k; его начальное значение равно 1 для k=0, поэтому сумма перед началом цикла b=1, а   r=x. В операторе while записывается условие выполнения цикла.  Текст программы для решения данной задачи записывается в следующем виде:

#include <stdio.h>

void main()

{ int k;  double eps, b=1.0, r,x;

   printf("\n Vvedite znachenie x=");  scanf(" %lf", &x);

   { printf("\n Vvedite tochnost eps=");   scanf("%lf", &eps);   }

   k=2;   r=x;    

  while (r > eps || r < -eps)  { b=b+r;   r=r*x/k;   k++;   }

   printf("Rezultat: %f\n",b);     printf("Pogreshnost: %f\n", r);

   printf("Chislo chlenov rjda: %d\n",k);

   }

Особенностью  оператора цикла do  является то, что  условие звершения цикла записывается за телом цикла:

do

тело цикла

while (условное выражение);

Пример  2. Написать программу  для   вычисления суммы, приведенной в примере 1,  с помощью оператора do:

#include <stdio.h>

void main()

{       int k;  double eps,  b=1.0, r,x;

         printf("\n Vvedite znachenie x=");  scanf(" %lf", &x);

         printf("\n Vvedite tochnost eps=");  scanf("%lf", &eps);

         k=1;    r=1.0;   

       do  {   r=r*x/k;   b=b+r;   k++;   }while(r>=eps || r<=-eps);         printf("Rezultat: %f\n",b);

  printf("Pogreshnost: %f\n", r);   printf("Chislo chlenov rjda: %d\n",k);

}

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

 Оператор цикла for имеет следующий формат:

for (выражение 1; условное выражение 2; выражение 3)

тело цикла

Пример 3. Текст программы для вычисления той же суммы, рассмотренной в предыдущих примерах, с использованием оператора цикла for  имеет следующий вид:

#include <stdio.h>

void main()

{  int k;  double eps,  b=1.0,  r, x;

    printf("\n Vvedite znachenie x="); scanf(" %lf", &x);

    printf("\n Vvedite tochnost eps="); scanf("%lf", &eps);

    for (k=1, r=1.0; r>eps || r<-eps; k++)   {   r=r*x/k;   b=b+r;  }

    printf("Rezultat: %f\n",b);   printf("Pogreshnost: %f\n", r);

    printf("Chislo chlenov rjda: %d\n",k);

}

Пример  4. Дано вещественное число x. Выислить следующую конечную сумму:         S = x -  +  - +  -  + .

Перед составлением программы необходимо ввести обозначения:  k – счетчик цикла, n –  наибольшее значение счетчика цикла, S – вычисляемая сума,  p – очередное слагаемое.  Текст программы будет следующий:

#include<stdio.h>

void main()

{float x,s,p;  int k,n;

  printf("\nVvedite n=");scanf("%d",&n); printf("\n Vvedite x=");   scanf("%f", &x);

  p=x;  s=x;

  for (k=1; k<=n; k++)   {    p=(-p)*x*x/(2*k*(2*k+1));  s+=p;   }

  printf("\ns=%f",s);

  }

Задания для самостоятельного выполнения:

№1-4 Вычислить точное значениe функции для 10 различных значений х (где |x|<1) в заданном интервале [a,b] и вычислить с использованием разложения функции в степенной ряд. Сумму степенного ряда найти двумя способами: для заданного количества элементов ряда n (10<=n<=20) и для заданной точности ε.  Функция выбирается по варианту. Составить таблицу:

х

Точное значение функции

Приближенное значение функции для n элементов ряда

Приближенное значение функции для точности ε

 

 

 

 

 

1) ;

2) ;

3) ;

4) .

№5 Приближенно  вычислить интеграл по формуле прямоугольников  для заданного значения n. Данные вывести в виде таблицы (xi, f(xi)). Вычислить  Формула прямоугольников имеет вид:

 .

№6 Даны вещественные числа c, d, x  и целое число n, (c< d). Вычислить для заданного значения n интеграл по формуле трапеций. Вычислить   Формула трапеций имеет вид:

 .

 №7 Вычислить и вывести значения функции для аргумента x в интервале (a,b) с шагом h:

 .

№8 При вводе последовательности положительных целых чисел производится подсчет суммы. Ввод прекращается при вводе любого отрицательного числа.

№9-10 Вычислить значениe функции для 10 различных значений х (где |x|<1) в заданном интервале [a,b] и вычислить с использованием разложения функции в степенной ряд. Сумму степенного ряда найти двумя способами: для заданного количества элементов ряда n (10<=n<=20) и для заданной точности ε, для бесконечного ряда.  Функция выбирается по варианту. Составить таблицу:

х

Приближенное значение функции для n элементов ряда

Приближенное значение функции для точности ε

 

 

 

 

9)    ,                                     10)   .

 

Лабораторная работа № 3.  Замены в тексте программы

 

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

 

Контрольные вопросы:

1) Что такое препроцессор?

2) Назовите  основные функции препроцессора.

3)  Какая директива препроцессора используется для замены текста?

4) Для чего необходима замена идентификаторов другими символами?

5)  До какого места текста ограничено действие  директивы?

6)  при каких случаях не выполняется замена?

7)  Кто создает нестандартные заголовочные файлы?

8) С помощью какой препроцессорной  директивы вводится текст из файла?

9)  Какое значение принимает  идентификатор С при выполнении директивы #undef С?

10) Если в программе используется математическая функция,  то какая директива должна быть обязательной?

 

Методические указания и упражнения

Иногда возникает  необходимость замены идентификатора другими символами. Например, когда рассматривалась  поименованная константа была использована такая возможность.  Для замены идентификатора последовательностью символов используется следующая  директива:

#define идентификатор  строка _замещения

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

Если в строке замещения  команды  #define  в качетсве отдельной лексемы  встречается препроцессорный идентификатор, ранее определенный  другой директивой #define, то выполняется  цепочка последовательных  подстановок.  Препроцессор последовательно, строку за строкой, просматривает текст. Если встретиться директива  #define, то вставляет текст из указанного файла.  В результате выполнения всех директив из текста удаляются  все директивы и будет получен текст, удобный для компиляции. Итак, с помощью директивы  #define  текст программы на языке Си  будет подготовлен для компиляции.

 Имеются ограничения при замене, в следующих случаях замена не может быть осуществлена:

-  внутри комментариев;

-  внутри строковых констант;

-  внутри символьных контстант и идентификаторов.

Одним словом, препроцессорная замена не производится в текстах, ограниченных кавычками (“ и ”), апострофами (‘ и ’)  и разделителями  (/* и  */).

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

Пример 1.  Даны натуральное число n  и вещественное число x. Вычислить следующую сумму:    sinx + sin2x + sin3x + . . .+sinnx.

Алгоритм данной задачи очень простой и введены обозначения: s –сумма, а  очередное слагаемое  p. Текст программы для вычисления данной суммы имеет вид:

#include<stdio.h>

#include<math.h>

#define begin {  #define   end }

#define n 10

#define x 0.5

void main()

        begin   double s,p;  int k;

               for(s =0.0, p =1.0, k=1; k<=n; k++)

                   begin   p*=sin(x);  s+=p;   end

               printf("\nSumma s=%lf",s);

       end

В данной программе  с помощью  #define  можно изменить значения  n  и  x, определить сумму для различных случаев.

Если в программе требуется часто выдавать на печать или вывести на экран дисплея значение некоторой переменной величины, кроме этого обеспечивать текстом комментария, то целесообразно использовать сокращенный вид оператора вывода.

Пример 2. Для того чтобы показать эту возможность рассматривается программа вычисления следующей простой суммы:

s = .

Здесь  n  и  x  заданы; каждое следующее слагаемое обозначено p=xk .  Оно определяется умножением предыдущего слагаемого  на  x. 

Здесь директива  #define BAS  printf("\n Summa=%lf",s); позволяет заменить функцию  printf("\n Summa=%lf",s); командой BAS.

Текст программы имеет вид:

#include<stdio.h>

#define BAS  printf("\n Summa=%lf",s);

void main()

{    int n,k;   double x,s,p;

      printf("\n Vvedite n=");   scanf("%d",&n);

      printf("\nVvedite x=");    scanf("%lf",&x);

      s=0.0; k=1; p=1.0;

        do   {   p=p*x;   s=s+p;   k=k+1;    }       while(k<=n);    BAS;

  }

После выполнения программы  значение  суммы  s выводится на экран командой  BAS;.  Необходимо выполнить программу и получить результат ее выполнения.  

Для того чтобы запретить замену можно использовать команду:                     #undef идентификатор

Ввод типов данных. С помощью директивы    #define  программист может ввести собственные базовые (основные)  или  производные типы. Например,  следующая  директива

#define REAL Long double

вводит  для типа Long double новый тип REAL.  После этого объекты вещественного типа могут быть описаны с помощью  REAL.

Замена выражений.  Следующее микроподстановка  с параметром

#define имя(список _параметров) строка_замены

Имеет большие возможности. Здесь имя –  имя макроса,  список_параметров –  список  идентификаторов, разделенных запятыми.  Между именем и скобкой не должен быть пробел.

Классический пример макроподстановки:  по директиве

#define ABS(X) ( X<0?–(X):X),

если X<0, то  X  принимает отрицательное значение, то ABS(X)=-X, а в противном случае   ABS(X)=X. С помощью такого макроподстановки можно ввести в программу выражение абсолютной величины.

 Например,  конструкция   ABS(E-Z)    заменяется следующим выражением: (E-Z<0?–(E-Z):E-Z).  В результате будет определено абсолютное значение выражнения  E-Z.

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

Пример 3.  Вычислить следующую бесконечную сумму с заданной точностью ε>0:       .

Вычисление производится до тех пор, пока очередное слагаемое  не будет по абсолютной величине меньше чем ε, т.е. до выполнения следующего условия:    ‌‌‌‌‌ < ε.

Программа решения данной задачи будет иметь следующий вид:

#include<stdio.h>

#define eps 0.001

#define REAL  double

#define ABS(x) (x<0?-(x):x)

#define BAS printf("\nSummas=%lf,Slagaemoe p=%lf",s,p)

void main()

{

int k=2;    REAL s, p;     s=0.0;   p=0.5;

printf("\n \nRezultat: \n");

while(ABS(p)>eps)

{  s=s+p;  BAS;   p=1.0/k/(k+1.0);    k++;     }

 }

 

Задания для самостоятельного выполнения:

Решить задачи лабораторной работы №2 со следующими изменениями:  вводить константы и выводить промежуточные и окончательные результаты с помощью директив препроцессора.

 

Лабораторная работа №4.  Указатели и операции над ними

 

Цель работы: ознакомить с указателями и  научить пользоваться ими.

 

Контрольные вопросы:

1) Что такое код операции?

2) Что такое команда на машинном языке?

3) Что такое адрес объекта?

4) Как записывается адрес объекта?

5) Какой адрес указывается указателем NULL?

6) Как описывается указатель?

7) Как можно определить значение объекта,  на который имеется ссылка указателя?

8) Как определяется адрес указателя?

9)  Можно ли сложить указатели одного типа?

10) Какой объем памяти занимает адрес, в котором хранится целочисленная переменная?

 

Методические указания и упражнения

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

 Пусть рассматриваются некоторые основные операции над указателями.

 Операция присваивания. Порядок записи операции известен:  в левой части  знака операции = записывается имя указателя, а в правой части -  указатель, либо константа NULL, либо имя объекта  того же типа, что и указатель слева.

Получение значения объекта, на которого  указателем выполнена ссылка.   Следующее выражение  *имя_ указателя   позволяет получить значение переменной по адресу, определенному указателем. Если в данном примере было определено значение переменной date (2007 ),  а затем ее адрес  присвоен указателям  m   и   k,  то значением  *k  или  *m  будет 2007. Отсюда следует,что имя переменной date,  разыменования *k и *m указателей  k  и m   обеспечивают доступ  к одному и тому же участку памяти, выделенному для значения переменной date.  Любая из следующих операций  *k= выражение, *m =выражение, date= выражение изменяют содержимого одного и того же участка памяти компьютера.  

Определение адреса указателя.   Переменная типа указатель имеет имя, собственный адрес в памяти и значение. Значение указателя можно использовать. Например, можно его печатать, присваивать другому указателю.  Адрес указателя можно получить с помощью унарной операции &. Следующее выражение  &имя_указателя определяет адрес указателя.  Значение, находящееся в данной области памяти, считается значением укзателя.  

Для получения  значения (адреса) указателя  используется  функция  printf(), в форматной строке которой записана спецификация %p.

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

Пример 1. В следующей программе показаны применение операции присваивания над указателями, получения адресов указателей и адресов объектов  date, k, m:

#include<stdio.h>

 void main()

{

     printf("\n Rezultaty: ");

     char *c;   c="Almaty";  int date=2007;

     int  *k, *m; /* operator opisanij ukasatelei */

     m=&date; /* operator prisvaivanij */

     k=m;     /* operator prisvaivanij */

      c=NULL;  /* operator prisvaivanij */

printf("\n Znachenij objektov ukasatelei: *k=%d,*m=%d",*k,*m);

   /* operator vyvoda */

printf("\n Adresa ukasatelei: &*k=%p, &*m=%p, &*c=%p", *k,*m,*c);         /* operator vyvoda */

printf("\n Adresa objektov: &date=%p, &k=%p, &m=%p", &date, &k, &m);         /* operator vyvoda */

}

Рекомендуется анализировать результат выполнения программы.

Унарные операции для изменения значений указателей.  Над указателями можно выполнять унарные операции.  С помощью унарных операций ‘++’ и  ‘--’  можно изменить значения переменных типа указателя в зависимости  от типа данных, связанных с ними.  Это зависит от объема памяти, занимающей объектом. Если указатель связан с типом  char (1 байт),    то в результате выполнения унарных операций   ‘++’  и ‘--’  его значение изменяется на  единицу.  Если  указатель связан с типом int,  то на  2, а если     float или  long,  то на 4.

Аддитивные   операции. Имеются определенные особенности  аддитивных операций над укзателями.  Две переменные типа указатель нельзя  суммировать. Указателю можно прибавить  целую величину.  В данном случае вычисляемое  значение зависит не только от  значения прибавляемой целой величины, но и от типа  объекта с которым связан указатель. Если указатель относится типу long,  то после прибавления единицы его значение увеличивается на 4, или осуществляется переход к следующему адресу объекта типа  long.  Операция вычитания выполняется только для указателей одного типа.  С помощью этой операции можно определить расстояние между двумя объектами одного типа.

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

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

Пример 2.  В данной программе вводятся значения трех переменных целого типа x,y,a.  Выводятся на экран  адреса указателей этих переменных и разности этих указателей. Текст программы  имеет следующий вид:

#include<stdio.h>

#include<stddef.h>

void main()/*prostaj programma*/

{

int x,y,a;   int *i,*k,*m;     ptrdiff_t j,n,p;

printf("\n Vvedite x=");   scanf("%d",&x);

printf("\n Vvedite y=");   scanf("%d",&y);

printf("\n Vvedite a=");    scanf("%d",&a);

i=&x;  k=&y;  m=&a;

printf("\n Adresa ukasatelei: &i=%p &k=%p &m=%p",&i,&k,&m);

j=i-k;  n=i-m;   p=m-k;

printf("\n j=%d",(int)j);  printf("\n n=%d",(int)n);   printf("\n p=%d",(int)p);

  }

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

 

Задания для самостоятельного выполнения:

Указания к выполнению работы:

1)    Адрес переменной var1 определяется с помощью операции определения адреса &:  &var1- адрес переменной в памяти компьютера.

2)    Указатель на переменную, пусть имеется переменная типа указателя, тогда значение этой переменной определяется с помощью операции определения адреса:  ukvar1=&var1.

3)    Для обращения к переменной через указатель применяется операция косвенной адресации *. Значение переменной var1 можно изменить как обычно: var1= var1+5; или с помощью указателя: *ukvar1=*ukvar1+5;

Пример:

int  var1;

int   *ukvar1;   //указатель на переменную типа  int

ukvar1=&var1;// Адрес переменной

cout<<”указатель=”<< ukvar1<<   //Вывод адреса переменной

                ”\nПеременная  имеет значение  var1=”<< *ukvar1;//Вывод значения переменной

 

 

 

 

 

 

Ссылка- это измененный указатель, который используется как псевдоним переменной.

Пример:

# include  <iostream.h>

int main()

{int  var1;

int  &ssylkavar1 ;   //ссылка на переменную типа  int

var1=5;

&ssylkavar1=var1;// инициализация ссылки,

                             //теперь ссылка-псевдоним переменной

cout<<”значение переменной=”<< var1<<   //Вывод 5

 ssylkavar1= ssylkavar1+4;

cout<<”новое значение переменной=”<< var1;//Вывод 9

cout<<”новое значение через ссылку=”<<  ssylkavar1;//Вывод 9

return 0;

}

 

 

 

 

 

 

 

 

4)    Как производится передача параметра в функцию с помощью параметра-ссылки:

# include  <iostream.h>

void func1(int &svar1);   //прототип функции

int main() {int  var1=5;    //объявление переменной и инициализация

cout<<”значение переменной=”<< var1<<   //Вывод 5

func1(var1);  

cout<<”новое значение переменной=”<< var1;//Вывод 9

return 0;

}

void func1(int &svar1)  // функция

{      svar1= svar1+4;      }

 

 

 

 

 

 

 

 

Решить  задачу из лабораторной работы № 1:

-  с использованием указателей на переменные;

- задачу с использованием ссылок на переменные;

- задачу с использованием функций для вычисления изменений переменных, используя  параметр-ссылку.

 

Лабораторная работа №5.  Программирование  на языке Си

алгоритмов, связанных с одномерными массивами 

 

Цель работы: ознакомить студентов  с программированием  на языке Си алгоритмов, связанных с одномерными массивами.

 

Контрольные вопросы:

1) Назовите различия в описании массивов на языках Си и Паскаль.

2) Можно ли  заменить ноль в индексе первого элемента массива на другое?

3)  Какие отличия имеются в обозначении элемента массива на языках Си и Паскаль?

4)  Что такое массив массива?

5)  Как задается количество элементов массива?

 

Методические указания и упражнения

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

Пример 1.  Вычислить сумму и среднее арифметическое элементов одномерного массива.

Пусть введены  обозначения: элементы массива  x[i], i=0,1,2,..., n-1, их сумма s и среднее арифметическое  d. Программа данной задачи имеет следующий текст:

#include<stdio.h>

void main()              /*vychislenie summy i srednego*/

{int n,i,j;

float s, d ,x[100];

while(1)

{printf("\n Vvedite znachenie n=");   scanf("%d", &n);

if(n>0 && n<=100) break;

printf("\n Oshibka! Neobchodimo 0<n<101");} /* Konez zikla vvoda znachenij n*/

printf("\n Vvedite znachenij elementov:\n  ");

for (b=0.0,i=0; i<n; i++)

  {  printf("x[%d] =", i);      scanf("%f",&x[i]);

  s+= x[i];  /* Vychislenie summy */  }

  d=s/n;  /* Vychislenie srednego */

  printf("\n Summa = %f, Srednee = %f",s,d);  }

Здесь имеется оператор while(1)   означает, что с помощью  оператора  break можно выйти из цикла при задании правильного значения n  (0<n<101).

Пример 2. Определить наименьший элемент и его номер одномерного массива.

Вводятся обозначения: a[i] – элемент массива, x – наименьший элемент массива, k – номер наименьшего элемента. Текст программы будет иметь вид:

#include<stdio.h>/* Opredelenie naimenshego elementa massiva */

void main()

{    int i, k ,n;  float a[100], x;

while(1)

{printf("\n Vvedite znachenie n=");  scanf("%d", &n);

if(n>0 && n<100)break;   printf("\n Oshibka! Neobchodimo 0<n<100!");}

printf("\n Vvedite znachenij elementov:\n");

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

{     printf("a[%d]=",i);  scanf("%f", & a[i]);    }

x=a[0];     for( i=0; i<n; i++)

if (x>a[i])      {   x=a[i]; k=i;    }

printf("Naimenshi element x=%f\ nEgo nomer k= %d\n", x,k);}

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

Пример 3. Теперь необходимо составить программу для сортировки массива, когда требуется расположить элементы массива по возрастанию их значений. Дан массив из   n элементов:   a[0],a[1],a[2], . . . , a[n-1]. Требуется составить массив из этих элементов по возрастанию их значений. Программа для решения этой задачи имеет следующий вид:

/* Uporjdochenie massiva */

#include<stdio.h>

main()

{  int n,i,j;   double a[100],b;     while(1)

{   printf("\nVvedite kolichestvo elementov n=");   scanf("%d",&n);

        if(n>1 && n<100) break;

printf("Oshibka! Neobchodimo 1<n<100!");      }

 printf("\n Vvedite znachenij elementov massiva:\n");

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

 {      printf("a[%d]=",j+1);     scanf("%lf", &a[j]);      }

          for(i=0; i<n-1; i++)     for(j=i+1; j<n; j++)

   if(a[i]>a[j])     {     b=a[i];     a[i]=a[j];   a[j]=b;      }

     printf("\n Uporjdochenni massiv: \n");

     for(j=0;j<n; j++)  printf("a[%d]=%5.1f\n",j+1,a[j]);

    }

В данной программе, в  функци printf("a[%d]=%f\n",j+1,a[j]); вместо j записано j+1 для того, чтобы первый номер элемента стала 1 вместо 0.

Здесь может быть задан вопрос: что необходимо сделать для того, чтобы элементы  массива распологались по возрастанию их значений? 

Если требуется  присваивать начальные значения элементов массива в начале программы, то эта операция называется инициализацией. В этом случае можно не показывать количество элементов массива.

 

Задания для самостоятельного выполнения:

№1 Даны целое число n>1 и вещественные числа . Вычислить  и   .

№2 Вводится некоторая последовательность положительных чисел, конец ввода происходит при вводе отрицательного числа, которое не считается. Вычислим количество положительных чисел и обозначим как n. Вычислить сумму: .

№3 Даны не меньше трех различных целых положительных чисел, конец ввода происходит при вводе числа 0. Определить три наибольших числа среди них.

№4 Даны различные целые числа , конец ввода происходит при вводе числа 0. Определить, сколько раз в последовательности происходит изменение знака (например, -1, 5,10,2,-3,-7 изменение знака 2 раза).

№5 Дана последовательность различных целых положительных чисел (>0), конец ввода происходит при вводе числа 0. Определить, сколько чисел превышает среднее арифметическое значение, вывести их на экран с указанием номера элемента в массиве.

№6 Создать массив из n целых чисел, используя датчик случайных чисел. Найти элементы со  значением 0 и запомнить их номера в новом массиве. Например, массив (5,7,2,0,3,0,4), ему соответствует  другой массив (4, 6), который показывает индексы элементов со значением 0.

№7  Создать массив из n целых чисел, используя датчик случайных чисел. Удалить элемент с заданным индексом k.

№8 Ввести массив из n целых чисел. Найти элементы с отрицательным значением и вставить после него новый элемент со значением 9999, таким образом увеличивая размер массива.

№9 Ввести массив из n целых чисел. Найти элементы с четным индексом и заменить его значение на число, равное сумме самого элемента и его индекса.

№10 Ввести массив из n целых чисел. Найти первый элемент с отрицательным значением. Отсортировать все остальные элементы после него по возрастанию.

 

 Лабораторная работа №6. Указатели элементов массива

 

Цель работы: научить использованию указателей при работе с массивами.

 

Контрольные вопросы:

1) Каким образом тип массива определяет объем памяти, выделяемой каждому его элементу?

2) Как определяется адрес первого элемента массива?

3) Как можно определить указателей элементов массива?

4) Как определяется адрес любого элемента массива?

5) Какова роль типа массива при определении адреса его элемента?

 

Методические указания и упражнения

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

тип имя _массива [количество элементов];

Здесь тип определяет объем памяти, выделяемой для одного элемента массива.   А имя _массива играет роль указателя области памяти, где  будут храниться  элементы массива.  Итак, адрес первого элемента массива (индекс  равен 0)    является имя массива:

& имя _массива

Адреса остальных элементов массива определяются добавлением к данному адресу целых чисел.  Значения этих чисел зависят от   типа массива.

Пример 1. Пусть дан массив z[] типа char, длина которого, т.е. количество элементов равно 7. Известно, что для каждого символа типа сhar  выделяется 1 байт объем памяти.  Учитывая этот факт, в следующем фрагменте программы показано изменение указателя при переходе от одного элемента к другому:

#include<stdio.h>

 void main()

{      char z[7],*c;

        printf("\n Adresa elementov massiva:\n");

       for(c=z; c<=&z[7]; c++)  printf("%6p",c);

  }

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

Пусть теперь рассматривается массив типа  int a[]. В этом случае предыдущая программа будет иметь вид:

#include<stdio.h>

    void main()

    {       int a[7],*b;

             printf("\n Adresa elementov massiva:\n");

             for(b=a; b<=&a[7];b++)       printf("%6p", b);

    }

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

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

Пример 2. Определить адреса элементов массивов различных типов: символьных, целочисленных и вещественных. Текст программы имеет вид:

#include<stdio.h>

void main()

{

char z[5]; int m[5]; float a[5];   char *uz; int *um; float *ua;

printf("\n  Simvoldych massiv elementterinin adresteri: \n");

for(uz = z; uz<=&z[4]; uz++)                    

printf("%10p", uz);  printf("\n Butin massiv elementterinin adresteri:\n");

for(um=m; um<=&m[4]; um++)

printf("%10p",um);  printf("\n Nachty massiv elementterinin adresteri:\n");

for(ua=a; ua<=&a[4]; ua++)

printf("%10p", ua);

  }

В данной программе начальным значением указателя   uz  будет имя массива без индекса z, а адрес последнего элемента будет следующий адрес  &z[4].  Для других массивов будет аналогичная ситуация. Предлагается выполнить данную программу и анализировать полученные результаты.

Следует предупредить, что имя массива не является переменной типа указатель. Оно является целой константой. Нельзя применить операции ‘++’  и ‘--’ для имени массива. Его нельзя записывать в левой части оператора присваивания.

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

Пример  3.  В данном примере рассматриваются  массив и два указателя. Требуется вывсти на экран дисплея адреса указателей и элементов массива, а также значения элементов массива. Текст программы следующий:

#include<stdio.h>

float x[]={10.0, 20.0, 30.0, 40.0, 50.0};

void main()

{  float *u1,*u2;   int i;

    printf("\n Adresa ukasatelei: &u1=%p &u2=%p",  &u1, &u2);

    printf("\n Adresa elementov massiva: \n");

    for(i=0; i<5; i++) {if(i==3) printf("\n");printf("&x[%d] = %p", i,&x[i]);}

    printf("\n Znachenij elementov massiva: \n");

    for(i=0; i<5; i++)  {if(i==3) printf("\n");   printf("x[%d] = %5.1f",i,x[i]);}

 }

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

 

Задания для самостоятельного выполнения:

Решить задачу из лабораторной работы №5, с помощью указателей на одномерный массив.

 

Лабораторная работа №7.  Программирование многомерных

 массивов

 

Цель работы: изучить особенности программирования многомерных массивов в языке Си.

 

Контрольные вопросы:

1) Как можно записывать элементов двумерного массива в виде одномерного массива?

2) Какой спецификатор должен быть записан в форматной строке  функции printf() при выводе значений указателя?

3)  Может ли быть указателем  имя массива?

4)  Можно ли использовать операции ‘++’ и ‘--’  в имени массива?

5)  Для чего должны освободить часть памяти ри выполнении программы ?

 

Методические указания и упражнения  

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

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

double A[3][2]={{5,4},{8,2},{10,5}};

Здесь:

A[0][0]=5; A[0][1]=4; A[1][0]=8; A[1][1]=2; A[2][0]=10;  A[2][1]=5.

Это может быть записано в следующем виде:

double A[3][2]={5,4,8,2,10,5};

Размерность массивов в языке  Си  не ограничена, ее наибольшее значение определено препроцессорной константой в заголовочном файле стандартной библиотеки. В практических вычислениях, встречающихся в инженерных и экономических расчетах, в основном используются только одно - и двумерные массивы.  Трех – и многомерные массивы  в практических вычислениях встречаются очень редко и правила работы с ними аналогичны правилам работы с двумерными массивами. Поэтому можно ограничиться  двумерными массивами. 

Учитывая некоторые преимущества использования указателей, здесь приведены некоторые сведения о массивах указателей для многомерных массивов. 

Массив указателей может быть введен одним из трех следующих определений:

1)     тип*имя_массива [размер];

2)     тип*имя_массива;

3)     тип*имя_массива[размер]= инициализатор;

Здесь:

а) тип  может быть базовым или одним из  производных;

б) имя_массива –идентификатор, выбранный программистом;

в) размер – постоянная величина, определяемая во время трансляции;

г) инициализатор – значения типа  тип*, записанные в фигурных скобках.

Например,       int *uk[5];    int *ua[]={a[0],a[3], a[2],a[5]};

                                  int *ub[5]={b[0],b[1],b[2],b[3],b[4]};

пусть рассматривается  матрица, у которой длина каждой строки разная. Такие матрицы могут часто встречаться на практике.  Например, во время работы с базами данных. Если не использовать указателей, то приходится привести такую матрицу в четырехугольную, заменив недостающие элементы нулями.  Это приводит к использованию дополнительных ячеек памяти.

Для демонстрации сказанного рассматривается следующий пример.

Пример 1. Дана двумерная матрица  a;  количество ее строк  равно  n, а количество элементов в каждой строке m разное. Элементы матрицы вводятся «построчно».  Требуется упорядочить элементов строк по возрастанию. Вводятся следующие обозначения:

a – указатель массива;  m – указатель длины массива;

z[ ] -  вспомогательный массив.

Текст программы для решения поставленной задачи следующий:

#include<stdio.h>

#include<alloc.h>

void main()

{    double ** a;   int n,i,j,k;   double y,x;   int * m;

      printf("\n\n Vvedite kolichestvo strok n=");    scanf("%d",&n);

      a=(double**)calloc(n,sizeof(double*)); m=(int*)malloc(sizeof(int)*n);

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

      {    printf("\n Vvedite dlinu stroki m[%d]=",i);  scanf("%d",&m[i]);

            a[i]=(double*)calloc(m[i], sizeof(double));

            for(j=0; j<m[i]; j++)

           { printf("a[%d][%d]=",i,j);     scanf("%le", &y);    a[i][j]=y;}

      }

      double z[10];

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

      { for(j=0; j<m[i]; j++)      z[j]=a[i][j];

        for (j=0; j<m[i]-1; j++)    

         {x=z[j]; for (k=j+1; k<m[i]; k++) if(x>z[k]) {x=z[k]; z[k]=z[j];z[j]=x;}

         }        

        for(j=0; j<m[i]; j++)       a[i][j]=z[j];

     }         printf("\n Rezultat:");

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

    {      printf("\n Stroka %d, elementov %d:\n",i,m[i]);

    for(j=0; j<m[i]; j++)   printf("\t%4.1f",a[i][j]);     free(a[i]);

    }    free(a);    free(m);

    }

 

Задания для самостоятельного выполнения:

№1-№3 Дана квадратная матрица порядка n. Вычислить сумму элементов из заштрихованной области для одного из рисунков по заданию преподавателя:

 

 

 

№4 Ввести элементы двумерного массива по строкам и вычислить среднее значение элементов каждого столбца.

№5 Написать программу, которая проверяет, представляют ли элементы одномерного массива убывающую последовательность.

№6 Элемент матрицы называется седловой точкой, если он является наименьшим в своей строке и наибольшим в своем столбце,  или если он является наибольшим в своей строке и наименьшим в своем столбце. Для матрицы размера n x m напечатать индексы всех седловых точек.

№7 Составить симметричную матрицу порядка n.  Для этого заполнить элементы, находящиеся на и над  главной диагональю, а остальные элементы создать программно, вывести матрицу на экран.

№8 Дана матрица порядка n.  Найти скалярное произведение строки с наибольшим элементом на столбец с наименьшим элементом.

№9 Транспонировать квадратную матрицу.

№10 Дана квадратная матрица А порядка n. Вычислить элементы  вектора-столбца, значения которых   показывают, есть ли в соответствующей строке матрицы А хотя бы один отрицательный элемент, тогда элемент вектора =1, иначе =0.

 

Лабораторная работа №8.  Обработка текстов на языке Си 

 

Цель работы: изучить программированию работы с текстами.

 

Контрольные вопросы:

1) Как можно составить массив символов?

2) В чем разница массива символов от строки?

3) Какую функцию выполняет sizeof()?

4) Какие имеются отличия в описаниях массивов на языках Си Паскаль?

5) Как распологаются элементы массива в памяти компьютера?

         6) Какую операцию нужно выполнять для определения адреса последнего элемента массива?

7) Какую операцию нужно выполнять для того, чтобы на языке Си индекс первого элемента массива был  1?

8) Что такое инициализация массива?

 

Методические указания и упражнения

Для описания текстовой информации на языке Си используются символы, символьные переменные и строки. В отличие от языка Паскаль и других алгоритмических языков, здесь строки не рассматриваются как отдельный тип, а описываются как массив символов типа  char.

Известно, что каждый символ занимает один байт памяти и имеет соответствующий код согласно стандарта  ASCII.  Для букв латинского алфавита и десятичных цифр внутренние коды имеют определенный порядок. Такое положение облегчает работу программиста.

Для описания символьных данных введен базовый тип. Описание символьных данных может быть записано в следующем виде:

char перечень_имен_переменных;

Для определения кода символа можно использовать функцию printf(). Программисту  необязательно знать код символа. Для использования символа желательно использовать символьную константу или заключить символ в апострофы. Например,  ‘a’, ‘b’, ‘c’  и  т.д.

Для вывода и ввода символьных данных можно использовать библиотечные функции printf() и  scanf().  Спецификацией этой функции будет  %c. Например,  с помощью функции scanf(“%c”, &a); вводится значение символа а из адреса &a.

Кроме этих двух функций, могут быть использованы специальные функции ввода и вывода  getchar()  и  putchar(X).  Функция getchar() обеспечивает чтение отдельного символа, вводимого с помощью клавиатуры.   Вводимые данные начинают читаться после нажатия клавишы  (<Enter>). Функция putchar(X) выводит на экран  символьное значение  X.

Внутри компьютера символы размещены в определенном порядке. Поэтому их можно рассматривать как целые числа.  При составлении слов или других конструкций из символов (букв, знаков и других) их рассматривают как массивы, строки и строчные константы рассматриваются как последовательность символов или массив символов типа char[].  В функциях ввода scanf()  и вывода printf()  для символьных строк используется спецификация %s. Поэтому  при рассмотрении их необходимо использовать операции над масивами типа  char.

Строки имеют некоторые особенности. Например, нельзя присваивать значения символьным массивам с помощью оператора присваивания. Для этого используется метод инициализации или функция ввода.  Следующая программа может демонстрировать это утверждение.

Пример 1. Пусть требуется составить текст  «Almaty-Astana».  Для этого можно использовать следующую программу:

#include<stdio.h>

main()

{      int uzyn;    char aripter[]={'A','l','m','a','t','y','-','A','s','t','a','n','a'};

        printf("\n Natije:");

        uzyn=sizeof(aripter)/sizeof(char);        printf("\n %s", aripter); }

Здесь функция  sizeof()  определяет длину аргумента. Тогда  оператор присваивания  uzyn=sizeof(aripter)/sizeof(char); определяет количество элементов массива или количество повторений  цикла. Спецификатор %c  в функции  printf("%c",aripter[k]);  показывает, что выводимые данные относятся типу char. В описании массива символов не указывается предельное значение индекса или квадратные скобки будут пустыми  (char aripter[]).

Массив символов образует строку. Текст, записанный внутри кавычек, называется строчной константой.  Например, “Almaty-Astana” или “Almaty-bas chala, Astana-jas chala” и  т.д.

Строчные константы могут быть определены как массивы символов, например,   char aripter[]=“Almaty-Astana”;

Здесь компилятор  выделяет для 13 символов 14 байт.  Потому что последний 14-ый байт предназначен для нулевого байта (терминального нуля). Терминальный  нуль показывает конец массива символов. Массив символов, оканчивающий терминальным нулем, называется строка языка Си.

Так как  строки рассматриваются как массивы, поэтому применение указателей не вызывает трудности. Поэтому  пусть рассматриваются два определения:

1) Для записи строки в массив можно использовать следующее описание:   char A[30];  После этого  массив  A[30] занимает автоматически  определенную память. Поэтому  можно записывать функцию:  scanf(“%s”,A);

2) Описание указателя строки: char* B;  После такого описания строке не выделяется память. В таких случаях существуют разные способы ввода данных. Во-первых, переменной B можно присвоить адрес ранее определенного массива. Во-вторых, указателю B с помощью функции распределения динамической памяти можно соотвествовать определенную область амяти. Например,     оператор   B=(char*)malloc(80); связывает указатель B с памятью 80 байт.

Пример 2.  В следующей программе  определен одномерный массив  указателей типа char* и с помощью инициализации свзан с множестом строк. Имеется возможность использовать  функцию вывода  printf() и спецификацию %s для использования указателя строки в качестве параметра.

#include<stdio.h>

void main()

{char*abai[]={"Bilim","tappai","machtanba,","Oryn","tappai","baptanba." };

int k,n;    n=sizeof(abai)/sizeof(abai[0]);

printf("\n Elementter sany n=%d.", n);   printf("\n");

printf("\n Programmanyn oryndаlu natijesi:");

for ( k=0; k<n; k++)   printf("\n%s ",abai[k]);}

 

 

Задания для самостоятельного выполнения:

№1 Ввести целое десятичное число и систему счисления (от 2 до 9). Преобразовать его в число в заданной системе счисления (например,число 67 в двоичной системе счисления = 1000011).

№2 Решить пример, заданный в виде текста: «вычислить 45+3-5=».

№3 Дана строка символов. Определить является ли она записью числа, кратного 2.

№4-7 Дан текст. Слова разделены одним или несколькими пробелами. Выполнить одно из заданий:

а) найти все слова, начинающиеся на заданную букву, подсчитать их количество;

б) найти слова, содержащие наибольшее количество гласных букв a,e,u,o;

в) вывести повторяющиеся слова (встречаются два или больше раз);

г) определить, есть ли в тексте заданное слово, и сколько раз оно встречается.

№8 Решить пример (операции суммирования и вычитания вещественных чисел), заданный в виде текста без пробелов, например:    «45.3-6.1+2=».

№9 Заданы десятичные числа, разделенные одним или больше пробелов. Сравним рядом стоящие два числа и поменять местами, чтобы большее число встало после меньшего. Например, «124 96  80 150», станет как текст «80 96 124 150».

№10 Дан текст из строчных латинских букв, за которыми следует точка. Напечатать в алфавитном порядке все буквы, которые входят в текст по одному разу.

 

Список литературы 

1. Абрамов С.А., Гнездилова Г.Г., Капустина Е.Н., Селюн М.И. Задачи по программированию. – М.: Наука. Гл. ред. физ.-мат. лит, 1988.  - 224 с.

2. Аляев Ю.А., Козлов д.А. Алгоритмизация и языки программирования Pascal, C++, Visual Basic: Учебно-справочное пособие.- М.: Финансы и статистика, 2004.-320 с.

3. Культин Н. C/C++  в задачах и примерах. – СПб.: БХВ-Петербург, 2008. – 288 с.: ил.

4.Құралбаев З. Алгоритмдеу және программалау тілдері. Алматы, 2008.- 353 бет.

5. Мартынов Н.Н. Информатика: С для начинающих. – М.: КУДИЦ-ОБРАЗ, 2006.-304 с.

6. Никлаус Вирт. Алгоритмы и стуктуры данных.- Досса: Хамарайан, 1997.- 360 с.

7. Подбельский В.В., Фомин С.С. Программирование на языке Си: учеб. пособие. – 2-е доп. изд. – М.: Финансы  и статистика, 2007.- 600 с.: ил.

8. Уэйт М., Прата С., Мартин Д. Язык Си. Руководство для начинающих: Пер. с англ. – М.: Мир, 1988. – 512 с., илл.

 

Сводный план издания  2011 г., поз. 258