Институт информационных технологий 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Институт информационных технологий



Институт информационных технологий

 

 

МЕТОДИЧЕСКОЕ ПОСОБИЕ

 

по программированию

 

для слушателей курсов

по переподготовке и получению высшего образования

 

ОСНОВЫ ПРОГРАММИРОВАНИЯ

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

 

 

Минск 2004


УДК 681.3.06 (075)

ББК 32.973 я 73

Л 12

 

Рецензент

Зав.кафедрой ЭИ БГУИР, канд.техн.наук В.И.Комличенко

Авторы:

А.Г.Корбит, Т.М.Кривоносова

 

Л 12     Методическое пособие по программированию для слушателей курсов по переподготовке и получению высшего образования. «Основы программирования на алгоритмическом языке Си». / А.Г.Корбит, Т.М.Кривоносова. - Мн.: БГУИР, 2004. -    c.48.

ISBN                            

 

 

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

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

 

 

УДК 681.3.06 (075)

ББК 32.973 я 73

 

Ó ИИТ БГУИР, 2004

СОДЕРЖАНИЕ

 

 

ЗАДАНИЕ 1. Линейные вычислительные процессы............  
ЗАДАНИЕ 2. Разветвляющиеся вычислительные процессы....  
ЗАДАНИЕ 3. Циклические вычислительные процессы.........  
ЗАДАНИЕ 4. Функции пользователя..........................   
ЗАДАНИЕ 5. Циклические процессы с использованием одномерных массивов......................................  
ЗАДАНИЕ 6. Циклические процессы с использованием многомерных массивов.....................................  
ЗАДАНИЕ 7. Строки и массивы указателей...................  
ЗАДАНИЕ 8. Структуры и файлы............................  
ЛИТЕРАТУРА.............................................  
ПРИЛОЖЕНИЕ............................................  

 

 


З А Д А Н И Е 1. Линейные вычислительные процессы

 

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

Алфавит языка Си

В языке Си используются наборы символов:

1) прописные и строчные буквы латинского алфавита;

2) арабские цифры;

3) специальные символы:

+ (плюс), - (минус), * (звездочка), / (дробная черта), = (равно), > (больше), < (меньше),; (точка с запятой), & (амперсант), [ ] (квадратные скобки), { } (фигурные скобки), () (круглые скобки), _ (знак подчеркивания), (пробел),. (точка),, (запятая),: (двоеточие), # (номер), % (процент), ~ (поразрядное отрицание),? (знак вопроса),! (восклицательный знак), \ (обратный слеш).

 

Классификация данных

В языке Cи применяются данные двух категорий: простые (скалярные) и сложные (составные) типы данных. К основным (базовым) типам данных относятся целый, вещественный и символьный типы. В свою очередь, данные целого типа могут быть короткими - short, длинными - long и беззнаковыми - unsigned. Приведем размеры и возможные диапазоны базовых типов данных:

Таблица 1

Наименование типа Тип данных К-во байт Диапазон значений
Символьный char 1 -128... 127 (0... 255)
Целый int 2 -32768... 32767
Короткий short 2(1) -32768... 32767 (-128...127)
Длинный long 4 -2147483648...2147483647
Беззнаковый целый unsigned int 2 0... 65535
Беззнаковый long unsigned long 4 0... 424967295
Вещественный float 4 3,14*10-38  ... 3,14*1038
Вещественный с двойной точностью double 8 1,7 *10-308 ...  1,7 *10308

 

Декларирование объектов

Объекты в программе необходимо декларировать. При декларировании объекты можно инициализировать (задавать начальные значения).

Например:               int  j=10, m=3, n;

                             float c=-1.3, l=-10.23, n;

При декларировании объектов используются их идентификаторы (ID), которые могут включать цифры, латинские прописные и строчные буквы, символ подчеркивания. Первый символ идентификатора не может быть цифрой. В языке Си прописные и строчные буквы отличаются, т.е. PI, Pi и pi – различные идентификаторы. Принято использовать в идентификаторах переменных строчные буквы, а в именованных константах – прописные.

Длина ID определяется реализацией транслятора Cи и редактора связей (компоновщика). Современная тенденция - снятие ограничений длины идентификатора.

Разделителями ID объектов являются: пробелы; символы табуляции, перевода строки и страницы; комментарии (играют роль пробелов).

Комментарий - любая последовательность символов, начинающаяся парой символов /* и заканчивающаяся парой символов */ или начинающаяся символами // и до конца текущей строки.

 

Структура программы

Программа, написанная на языке Си, состоит из директив препроцессора, объявлений глобальных переменных, одной или нескольких функций, среди которых одна главная (main) функция управляет работой всей программы.

Общая структура функции:

< класс_памяти > < тип > < имя функции >(объявление параметров)

{                             - начало функции

           < определение локальных объектов >

           < операции и операторы >

}                              - конец функции

Кратко рассмотрим основные части общей структуры программы.

Перед компиляцией программы на языке Си автоматически выполняется предва­ри­те­ль­ная (препроцессорная) обработка текста программы. С помощью директив препро­цес­сора задаются необходимые действия по преобразованию текста программы перед компиляцией.

Директивы записываются по следующим правилам:

- все препроцессорные директивы начинаются с символа #;

- все директивы начинаются с первой позиции;

- сразу за символом # должно следовать наименование директивы, указывающее текущую операцию препроцессора.

Наиболее распространены директивы # include и # define.

Директива # include используется для подключения к программе заголовочных файлов (обычных текстов) с декларацией стандартных библиотечных функций. При заключении имени файла в угловые скобки < > поиск данного файла производится в стандартной директории с этими файлами. Если же имя файла заключено в двойные кавычки ” ”, то поиск данного файла осуществляется в текущем директории.

Например:                  

#include <stdio.h> - подключение файла с объявлением стандартных

функций файлового ввода-вывода;

#include <conio.h> - функции работы с консолью;

#include <graphics.h> - графические функции;

#include <math.h>    - математические функции.

Директива # define (определить) создает макроконстанту и ее действие распро­страняется на весь файл, например:             

# define PI  3.1415927

В ходе препроцессорной обработки программы идентификатор PI заменяется значе­нием 3,1415927.

Пример программы:

# include < stdio.h >                                 

# include < conio.h >                             // Директивы препроцессора     

# define PI 3.1415927

void main (void)                 // Заголовок главной функции

{                                                  // Начало функции

int num;                                // Декларирование переменной num

num = 13;                              // Операция присваивания

clrscr ();                                 // Очистка экрана

printf (" \n Число pi = %9.7f \n %d - это опасное число \n”, PI, num); 

}                                           // Конец функции

Директивы препроцессора include подключают заголовочные файлы, содержащие декларации функций ввода-вывода (stdio.h - для функции printf) и работы с консолью (conio.h - для функции clrscr); директива define создает макроконстанту PI и по всему тексту программы заменяет ее значением 3,1415927. В главной функции main декларируется переменная целого типа num, которой далее присваивается значение 13. Функция printf выводит на экран информацию:

Число pi = 3.1415927

13 – это опасное число

Как видно, функция main представляет собой набор операций и операторов, каждый из которых оканчивается символом; (точка с запятой). В тексте использованы комментарии после пары символов //.

 

Операция присваивания

Операция присваивания имеет две формы записи, полная форма:

имя переменной = выражение;

в которой сначала вычисляется выражение, а затем результат присва­ива­ется имени_переменной, например: y = (x +2) / (3* x) - 5;

С помощью одного оператора можно присвоить одно значение несколь­ким перемен­ным, например: x = y = z = 0;   (x, y, z = 0)

или z = (x = y)*5;   - сначала переменной x присваивается значение переменной y, далее вычисляется выражение x *5, и результат присваивается переменной z.

Сокращенная форма:

имя переменной <операция> = выражениe;

где операция – одна из арифметических операций (+, -, *, /, %), например:       x *= 5;   «x = x*5;     

s += 7;   «s = s+7;     

y /= x+3;     «y = y/(x+3); 

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

В языке Си существуют операции уменьшения (--) и увеличения (++) значения переменной на 1. Операции могут быть префиксные (++i и --i) и постфиксные (i++ и i--). При использовании данной операции в выражении в случае префиксной операции сначала выполняется сама операция (изменяется значение i), и только потом вычисляется выражение. В случае постфиксной операции – операция применяется после вычисления выражения, например:           

b = 7;

n = 1;

1) c=b*++n; «n = n+1, c = b*n «c = 14

2) c=b*n++; «c = b*n, n = n+1 «c = 7

                

Пример программы для вычисления выражения     ,

(при x = 2,444; y = 0,00869; z=-130, должно быть получено: -0.49871):

#include <stdio.h>

#include <conio.h>

#include <math.h>

void main(void) {

    double rezult,dop,a,b,c;

        printf(“\n Введите x, y, z: “);

              scanf(“%lf %lf %lf”, &x, &y, &z);

dop = fabs(y-x);

         a = pow(x,y+1)+exp(y-1);

         b = 1+x*fabs(y-tan(z));

         c = 0.5*pow(dop,2)-pow(dop,3)/3;

         rezult = a/b*(1+dop)+c;

        printf("\n Ответ: rezult=%lf, Press any key...", rezult);

getch();                            // Задержка до нажатия клавиши

}

Варианты заданий

Составить программу для расчета значений z 1 и z 2 (результаты должны совпадать).

1. .

2. .

3.  .

4.  .

5.  .

6. .

7.  .

8. .

9. .

10. .

11.  .

12.  .

13.  .

14.  .

15.  .

 

 

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

1. Какие типы переменных применяются в языке Си?

2. Какие формы записи операции присваивания применяются в языке Си, приведите примеры?

3. Чем отличаются инфиксная и постфиксная формы операции присваивания, приведите примеры?

4. Перечислите основные отличия функций printf и scanf.

5. Перечислите основные форматы ввода/вывода данных в Си.


ЗАДАНИЕ 2. Разветвляющиеся вычислительные процессы

 

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

Операторы перехода

Оператор безусловного перехода

                  goto метка;

Управление передается оператору с данной меткой:       

метка: оператор;

В языке Си метка не декларируется.

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

Общая форма записи:

if (условие) оператор _1;

else оператор _2;

Например: if(x>y) max = x;

                                              else max = y;

Если оператор _1 или оператор _2 содержат два и более операторов, то они заключаются в фигурные скобки { }, т.е. применяется составной оператор, называемый - блок. Оператор if проверяет истинность или ложность условия. Если условие истинно (не равно 0), то выполняется оператор _1, иначе (ложно - равно 0), выполняется оператор _2.

Вторая часть оператора (else оператор _2;) может отсутствовать, такую форму называют сокращенной. Тогда в случае ложности условия управление передается на следующий за if оператор.

Если оператор _1 и оператор _2 в свою очередь являются операторами if, то такой оператор называют вложенным. При этом ключевое слово else  принадлежит ближайшему предшествующему if.

Общий вид вложенного оператора if:   

if (условие _1) оператор _1;

else if (условие _2) оператор _2;

else оператор _3;

В языке Си используют операции отношений:

  < (меньше), <= (меньше или равно), > (больше), >= (больше или равно), != (не равно), = = (равно). Пары символов разделять нельзя.

Общий вид операции отношения:

выражение _1 < знак_операции > выражение _2

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

В условных выражениях могут логические операции (приведем их в порядке убывания приоритета):

! (отрицание или логическое НЕТ), && (конъюнкция или логическое И), || (дизъюнкция или логическое ИЛИ).

Например:               (0<x)&&(x<=100)

                       ((!x)&&(y>0)||((z==1)&&(k>0))

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

Тернарная условная операция? имеет форму:

условие? выражение _1: выражение _2;

результат которой выражение _1, если условие истинно, иначе – выражение _2. Например, найти наибольшее из двух чисел: max = a>b? a: b;

Оператор выбора switch

Общая форма оператора выбора:

switch (выражение) {

         case const_1: операторы;   break;

                                  …

case const_N: операторы; break;

default: операторы;

              }

где const_1…const_N - целые или символьные константы; default - выполняется, если результат выражения не совпал ни с одной константой; может отсутствовать; break - оператор завершения работы switch. После выполнения одной из ветвей case все остальные ветви будут опущены. Если оператор break не записан, то выполняются операторы следующей ветви case. Оператор switch проверяет, совпадает ли значение выражения с одним из значений, приведенных ниже констант. При совпадении выполняются операторы, стоящие после совпавшей константы.

Например:  

switсh(i) {

case 1: f = pow(x,2); break;

case 2: f = fabs(x);   break;

default: printf(“Ошибка!”); exit(1);

     }

f=f+5;

       

Пример: вычислить значение функции

   

вывести сообщение о том, по какой ветви происходило вычисление:

#include <conio.h>

#include <stdio.h>

#include <math.h>

#include <stdlib.h>

void main(void) {

double x, y, f;                  

puts("Введите значения x и y");

scanf("%lf %lf",&x,&y);        

if ((x>0)&&(y<0)) {

    f = (x + tan(3*y))/(5-2*x);

    puts("F=(x+tg3y)/(5-2x)");

}

else if ((x<0)&&(y>0)) {

    f = (pow(x,2./3) > cos(y*y))? pow(x,2./3): cos(y*y);                    puts("F=max(pow(x,2/3),cos(y*y))");

}

else if ((x>0)&&(y>0)) {

    f = (0.5*x-2*pow(sin(y),2) < exp(y))? 0.5*x-2*pow(sin(y),2): exp(y);           puts("F=min(0.5x-2*pow(sin(y),2),exp(y))");

}

else {

puts("Функция F не определена!");

    exit(1);       // Принудительное завершение программы

}

printf ("ОТВЕТ: F = %lf ",f);          

}

        

Варианты заданий

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

,  где  

             где  

          где

                 где

        где

              где

         где

       где

                  где

               где

                     где

,        где

, где

,            где

,               где

 

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

1. Какие операции используются для составления условных выражений?

2. Какие формы записи операторов if применяются в языке Си?

3. Чем отличается оператор if от оператора switch?

4. Как работает тернарная условная операция?

5. Можно ли вкладывать операторы if друг в друга?


ЗАДАНИЕ 3. Циклические вычислительные процессы

 

Цель работы: изучить приемы составления циклических алгоритмов, правила использования операторов for, while, do – while.

 

Оператор цикла for

Основная форма оператора цикла for имеет вид:

for (выражение _1; выражение _2; выражение _3) оператор;

где выражение _1 – начальное значения параметра цикла;

выражение _2 – проверка условия на продолжение цикла;

выражение _3 – изменение параметра цикла (коррекция);

оператор – простой или составной оператор языка Си.

Схема работы оператора следующая: только один раз вначале вычисляется выражение_1, затем проверяется выражение_2, и если оно - «истина», то выполня­ет­ся циклический участок программы, затем производится коррекция параметра, и так до тех пор, пока выражение_2 не примет значение «ложь».

Например: for (k=1; k<5; k++) printf(“\n %d”, k);

в результате - печатаются в столбик цифры от 1 до 4.

В качестве параметра цикла можно использовать переменную любого базового типа.

Например, вывод на экран букв латинского алфавита:             

for(ch=’a’; ch<=’z’; ch++) printf(“ %c”,ch);                     

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

Выйти из цикла досрочно можно следующими способами:

- по дополнительному условию;

- используя операторы:

break; - выход из цикла, в котором он находится, упра­вле­ние передается на первый после цикла выполняемый оператор;

exit (int Kod);- выход из программы;

return;     - выход из функции;

- с помощью оператора безусловного перехода goto.

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

Передавать управление извне внутрь цикла запрещается.

Любое из выражений цикла for в круглых скобках может отсутствовать, но символ «;» опускать нельзя.

Например: int i = 0;

for(; i < 3; i++) puts(“ Hello!”);

 

Do

оператор;

while (условие);

где оператор – это простой, составной или пустой оператор.

Оператор dowhile – оператор цикла с постусловием, т.е. сначала выполняется оператор, а затем проверяется условие на истинность. Так как в цикле do–while условие проверяется в конце цикла, то цикл будет выполнен хотя бы один раз.

В циклах типа while и do–while допустимы те же способы досрочного выхода из цикла и досрочное завершение текущего шага цикла, как и в операторе for, но в последнем случае в отличие от цикла for управление передается на проверку условия.

Для предотвращения бесконечного цикла (while и do–while) нужно предусмотреть изменение переменных, входящих в условие.

Примеры бесконечных циклов:

1) for(;;) оператор;

2) while(любое_число_не_0) оператор; // Всегда истинно!

3) do

              оператор;

    while(любое_число_не_0);                 // Всегда истинно!

Среди таких операторов цикла обязательно должно быть условие выхода.

Вложенные циклы

В случае вложенных циклов один цикл находится внутри другого, например:     for(i = nn; i < nk; i++)

                       for(j = mn; j < mk; j++)

оператор;

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

Пример:    

int i,j;

 for(i=1;i<10;i++)    {            // Печать таблицы умножения

for(j=1;j<4;j++) printf(“\n %d*%d=%2d”, i, j, i*j);

printf(“\n”);

}

 

Пример: вычислить , на печать выводить промежуточные и окончательный результаты:

#include <stdio.h>

#include <conio.h>

void main(void) {

float s;

int k,N;

    puts(“ Введите N”);

    scanf(“%d”,&N);

for (s=0, k=1; k <= N; k++) { // В заголовке цикла можно выпол-

// нять и двойное присваивание

    s += 1.0/k;

    printf(" \n k = %d s = %f ", k, s);

    }

printf("\n ОТВЕТ: s = %f ",s);

}

 

Варианты заданий

Значение аргумента x изменяется от a до b с шагом h. Для каждого x найти значения функции Y(x), суммы S(x) и |Y(x)-S(x)| и вывести в виде таблицы. Значения a,b,h и n вводятся с клавиатуры. Так как значение S(x) является рядом разложения функции Y(x). Значения S и Y для данного аргумента x должны совпадать в целой части и в первых двух-четырех позициях после десятичной точки.

Работу программы проверить для a=0,1; b=1,0; h=0,1; n выбрать максимально возможным!

1. .

2.  .

3.  .

4.  .

5.  .

6. .

7. .

8.  .

9.  .

    10.  .

    11.  .

12.  .

13.  .

14.  .

    15.  .

        

 

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

1. Какой процесс называется “циклическим”?

2. Чем отличаются операторы while и do - while?

3. Объясните работу оператора for.

4. Поясните понятие “вложенный цикл”?

5. Какие переходы допустимы между вложенными циклами?

 


ЗАДАНИЕ 4. Функции пользователя

 

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

 

Область действия переменных

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

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

Глобальные переменные объявляются вне какой-либо функции. Глобальные переменные могут быть использованы в любом месте программы, но перед их первым использованием они должны быть объявлены и инициализированы. Область действия глобальных переменных - вся программа с момента их объявления.

В языке Си каждая переменная принадлежит к одному из четырех классов памяти – автоматическая (auto), внешняя (extern), статическая (static), регистровая (register). Тип памяти указывается ключевым словом (auto, extern, static, register), стоящим перед спецификацией типа переменной. Например, register int a;

По умолчанию переменная относится к классу auto и будет размещена в стеке.

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

При необходимости функцию можно использовать для изменения передаваемых ей аргументов. В этом случае в качестве аргумента сле­дует в вызываемую функцию передавать не значение переменной, а ее адрес. А для обращения к значению аргумента-оригинала исполь­зо­вать операцию «*».

Фрагмент программы, использующей функцию, в которой меняются местами значения аргументов x и y:

...

void z1(int*, int*);                    // Описание прототипа

void main(void) {

int a=2, b=3;

printf(“\n a=%d, b=%d”, a, b);

z1(&a, &b);                         // Обращение к функции

printf(“\n a = %d, b = %d”, a, b);

}

void z1(int *x, int*y) {                       // Описание (реализация) функции

    int t;

t = *x;

*x = *y;

*y = t;

return;

}

При таком способе передачи аргументов их значения будут изменены, т.е. на экран монитора будет выведено:

a = 2, b = 3

a = 3, b = 2

Функции могут вызывать сами себя - рекурсивные функции.

Пример рекурсивной функции – вычисление факториала n!:

    int fac (int n) {

int b;

     if (n= =1) return 1;

        b = fac (n-1)*n;

     return b;

    }

Вызов функции в рекурсии не создает новую копию функции, а создает новые копии локальных переменных и параметров. Из рекурсивной функции необходимо предусмотреть выход.

На функцию можно создать указатель, например, указатель р на функцию, возвращающую значение типа type и имеющую параметры типа type 1, type 2, объявляется следующим образом:

              type (* p)(type 1, typ e2);          

Варианты заданий

В задании Лабораторной работы 3, вычисление Y(x) и S(x) реализовать в виде функций.

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

Работу программы проверить для a=0,1; b=0,8; h=0,1; n выбрать в зависимости от варианта задания (с факториалом, без факториала).

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

1. Чем функция пользователя отличается от стандартной функции?

2. Способы передачи аргументов в функцию.

3. Поясните понятие “локальные” и “глобальные” переменные.

4. Для чего применяется оператор return?

5. Поясните понятие «класс памяти» функции.


ЗАДАНИЕ 5. Циклические процессы с использованием одномерных массивов и функций пользователя

 

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

 

Операция sizeof

Для определения размера памяти, необходимого для размещения объектов, в языке Си используется унарная операция sizeof (параметр), параметр – тип или ID объекта (кроме ID функции); результат - размер памяти в байтах, отводимый под объект. Если указан идентификатор сложного объекта (массив, структура, объединение), то результат - размер всего объекта. Например:

    sizeof(int)                 результат: 2 байта;

    int b[5]; sizeof(b)                       10 байт;

    int c[3][4]; sizeof(c)                     24 байта.

Связь указателей и массивов

Указатели и массивы тесно связаны между собой. ID массива является указателем на его первый элемент, т.е. для массива int v [10] v и v [0] имеют одинаковые значения, т.к. адрес первого (с индексом 0) элемента массива - это адрес начала последовательно расположенных его элементов. Рассмотрим обращение к элементам массива на примере: пусть объявлены - массив из 100 значений float и указатель на объект типа float:

float p[100];              

float *q;       

int i; 

если выполнить операцию q = p; то обращения к элементу массива p: p[i], *(q+i) и *(p+i) эквивалентны.

Таким образом, для любых указателей можно использовать две эквивалентные формы выражений для доступа к элементам массива: q[i] и *(q+i). Первая форма удобнее для читаемости текста, вторая - эффективнее по быстродействию программы.

 

Варианты заданий

В одномерном массиве, состоящем из n вводимых с клавиатуры целых элементов, вычислить:

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

сумму элементов массива, расположенных между первым и последним нулевыми элементами.

сумму элементов массива, расположенных до последнего положительного элемента.

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

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

сумму элементов массива, расположенных между первым и вторым отрицательными элементами.

сумму элементов массива, расположенных до минимального элемента.

сумму целых частей элементов массива, расположенных после последнего отрицательного элемента.

сумму элементов массива, расположенных после последнего элемента, равного нулю.

сумму модулей элементов массива, расположенных после минимального по модулю элемента.

сумму элементов массива, расположенных после минимального элемента.

сумму элементов массива, расположенных после первого положительного элемента.

сумму модулей элементов массива, расположенных после первого отрицательного элемента.

сумму модулей элементов массива, расположенных после первого элемента, рав­ного нулю.

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

 

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

1. Укажите типы массивов, применяемых в языке Си.

2. Формы (способы) работы с элементами массива.

    3. Что такое указатель?

    4. Операция sizeof.

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

 


ЗАДАНИЕ 6. Циклические процессы с использованием

Указатели на указатели

Связь указателей и массивов с одним измерением справедливо и для массивов с большим числом измерений. Например, если двухмерный массив float name [5][10]; рассматривать как массив пяти массивов размерностью по десять элементов каждый, то очевидна схема его размещения в памяти - последовательное размещение «строк» элементов. Обращению к элементам name [i][j] соответствует эквива­лентное выражение *(*(name+i)+j), а объявление этого массива указателем будет:

float **name;

Варианты заданий

Во всех заданиях предусмотреть динамический захват памяти, решение оформить в виде отдельной функции. На печать в виде таблиц вывести исходную и преобразованную матрицы (двухмерные динамические массивы). Исходная матрица формируется с клавиатуры

1. В вещественной матрице размером NxN найти максимальный и минимальный элементы. Переставить строки, в которых они находятся. Если они находятся в одной строке, выдать об этом сообщение.

2. Квадратную вещественную матрицу А размером N возвести в K-ю степень, т.е. вычислить: А1=А, А2=А·А, А32·А и т.д.

3. Дана вещественная матрица размером NxM. Переставляя ее строки и столбцы, добиться того, чтобы наибольший элемент (один из них) оказался в верхнем левом углу.

4. Дана вещественная матрица размером NxM. Упорядочить ее строки по возрастанию наибольших элементов в строках матрицы.

5. Задан массив размером NxN, состоящий из 0 и 1. Повернуть элементы массива на 900 по часовой стрелке.

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

7. Дана вещественная матрица размером N, все элементы которой различны. Найти скал



Поделиться:


Последнее изменение этой страницы: 2020-11-28; просмотров: 46; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.12.36.30 (0.352 с.)