- •Лабораторный практикум Дисциплина «Информатика»
- •230400 «Информационные системы и технологии»
- •1.1. Порядок создания программы
- •1.2. Ввод и выполнение программы
- •1.3. Модификация программы
- •1.4. Пошаговое выполнение программы
- •1.5. Сообщения компилятора и компоновщика
- •1.6. Действия в случае ошибки выполнения
- •1.6. Помощь справочной службы
- •1. Вычисление площади и периметра геометрической фигуры
- •2. Вычисления по формулам с вещественными числами
- •3. Арифметические операции для целочисленных данных
- •4. Циклы с заданным числом повторений
- •5. Алгоритмы с разветвлениями
- •6. Циклы с условием
- •7. Последовательная обработка данных
- •8. Поразрядные операции
8. Поразрядные операции
Цель работы: изучение поразрядных операций для решения задач обработки целочисленных данных на уровне битов, выработка умений тестирования и отладки программ с поразрядными операциями.
/* Программа 8 демонстрирует использование поразрядных операций для работы с целыми числами на уровне битов: постановка и сброс флагов, работа с 16-ми цифрами и кодами символов. */
#include <stdio.h>
#include <conio.h>
void long_bits (unsigned long L ); // Выводит на экран 2-ый код 16-го числа L
void main( void )
{ unsigned long L;
clrscr();
< Вывод шапки программы, см. программу 1 или 2 >
// Установка флага в k-ый разряд числа, k=0..31
L = 0;
long k = 3;
L = L | ( 1L<< k ); // L = 8 для флага в позиции 3
printf( "\n Установка флага в %d разряд числа L = 0: L = %lX", k, L);
// Сброс флага из k-го разряда числа, k=0..31
L = 0xFFFFFFFF;
L = L & ~( 1L<< k );
printf("\nСброс флага в %d разряде числа L=0xFFFFFFFF: L=%lX", k, L);
getch();
// Образуем символ из старшей и младшей 16-х цифр числа L
L=0x42345678; // код ch=0x48
printf("\n Cимвол из старшей и младшей 16-х цифр числа L=%lX", L);
char ch;
ch=((L & 0xF0000000) >> 24); // ch = 0x40
ch=ch | (L & 0xF); // ch=0x48
printf("\nL=%lX, 16-ый код ch=%X, символ ch=%c ", L, ch, ch);
getch();
printf("\n\n Введите long-число в 16-м коде для перевода в 2-ый код: " );
scanf("%lx", &L);
long_bits( L );
getch();
// Пример использования операции XOR для кодирования и декодирования // int-числа d символом ch:
ch='a';
int d=12345;
printf("\n\n Число d=%d закодировано символом \'%c\' операцией XOR: ",
d, ch);
d=(d & 0xFF) ^ ch | (d & 0xFF00) ^ (int(ch) << 8);
printf("\n\t код d=%d", d);
d=(d & 0xFF) ^ ch | (d & 0xFF00) ^ (int(ch) << 8);
printf("\n Декодируем аналогичными действиями: d=%d", d);
getch();
}
void long_bits( long L )
{ unsigned long m=1;
printf(" Число %lX в 16-м коде имеет 2-е представление:\n\t", L);
for(int k=31; k>=0; k--)
{ if( (m << k) & L ) printf("1");
else printf( "0" );
if( k%4 == 0 ) printf( " " ); // группы битов 16-х цифр разделяем пробелом
}
}
Вопросы и упражнения:
-
Перечислите и поясните на примерах поразрядные операции, укажите их приоритет.
-
Вычислите значение выражения с поразрядными операциями: ~0xB ^ 6 | 0xD & 7
-
Составьте функцию для определения, встречается ли в числе L код заданного символа ch.
-
Напишите функцию кодирования long-числа L заданной 16-ой цифрой Z путём выполнения операции Z XOR xi, i=1, 2, …, 8, xi – группы из 4-х битов числа L.
Работа 9. Обработка массивов
Цель работы: изучение приёмов обработки одномерных массивов данных, выработка умений алгоритмизации и программирования задач с массивами, отладки и тестирования программ с массивами.
/*Программа 9. Программа демонстрирует типовые процедуры обработки массивов: ввод, вывод, анализ и обработка данных массива.*/
#include <stdio.h>
#include <math.h>
void in_arr( float *arr, int n ); // ввод с клавиатуры n элементов массива
void out_arr( float *arr, int n ); // вывод на экран n элементов массива
int array_processing(double *arr, int n, double *psum, double *pprod);
/* Определение суммы s, произведения p и количества k "+"-ых элементов массива, расположенных после первого “–“-го элемента. Размер массива n <= 50.
ТЕСТ: x = { 1, 2, -1, 2, -2, 3, -3 }, n=7. Результаты: s=5, p=6, k=2.
psum, pprod, – переменные-указатели. C указателями связаны две специальные операции: & и *. Операция &x означает "взять адрес" переменной x, операция *px – "значение, расположенное по адресу px".
*/
float max2(float *arr, int n); // поиск в массиве максимальной по модулю // разности двух чисел. ТЕСТ: x = { 1, 5, 3, 0, -1, 2, 4}, n = 7, результат: = 6 .
int max_eqw(float *arr, int n); // определение максимального числа равных // соседних чисел. ТЕСТ: x = { 3, 1, 3, 0, 1, 1, 1, 1, 2}, n = 9, результат: 4 .
main()
{ float x[50], p, s;
int i, k, n;
printf("\n Введите размер массива n: ");
scanf("%d", &n);
in_arr( x, n );
printf(" \n Исходный массив размером %d: \n", n);
out_arr( x, n ) ;
k = array_processing( x, n, &s, &p);
printf("\n В массиве после первого \”-\“-го числа %d чисел x[i]>0, \
их сумма = %.3f, произведение = %.3f ", k, s, p);
printf("\n Максимальная по модулю разность двух чисел = %.3f ", max2(x, n));
printf("\n Макс-е число равных соседних чисел = %.3f ", max_eqw (x, n));
} // Конец main()
/* В комментариях функций in_arr() и out_arr() записаны операторы с элементами массива, обращение к которым выполняется по указателю без операции индексации arr [ i ] */.
void in_arr( float *arr, int n )
{ printf("\n Введите %d элементов массива: ", n);
for ( int i = 0; i < n; i++)
scanf( "%e", &arr[i] ); // scanf( "%e", arr++ );
}
void out_arr( float *arr, int n )
{ for ( int i = 0; i < n; i++)
{ printf( " %.3f ", x[i] ); // printf( " %.3f ", *x++ );
if ( (i+1) % 8 == 0 ) // вывод массива по 8 чисел в строке:
printf("\n");
}
}
int array_processing(double *arr, int n, double *psum, double *pprod)
{ int i;
*psum = 0; *pprod = 1; k = 0, m = -1; // инициализация
for ( m = 0; m < n; m++ )
if (arr[m] < 0) break;
for ( i = m+1; i < n; i++ )
if (arr[i] > 0)
{ *psum += arr[i];
*pprod *= arr[i];
k += 1;
}
return k;
}
float max2( float *arr, int n )
{ float k; int k, m = 0;
for(int i = 0; i < n-1; i++)
for( k = i+1; k < n; k++)
if( fabs( x[i]-x[k] ) > m) m = fabs( x[i] - x[k] );
return m;
}
int max_eqw( float *arr, int n )
{ int i, k=0, m=0;
for(i=0; i<n-1; i++)
if( x[i] == x[i+1] ) m++;
else if( m > k ) k = m, m = 0;
return k+1;
}
Вопросы и упражнения
-
Как организован одномерный массив в программе: тип элементов массива, их расположение в памяти компьютера?
-
Как объявить массив в программе?
-
Какое значение имеет объект программы имя массива? Можно ли изменить это значение?
-
Как обратиться по указателю к элементу arr[i] массива?
-
Есть ли ошибка в списке инициализации массива: int х[3] = {1, 2, 3, 4}; ?
-
Напишите операторы вывода элементов одномерного массива по заданному условию: а) каждого k-го элемента, б) m последних элементов, в) только отрицательных или только положительных элементов.
-
Напишите функции: а) поиск минимального (максимального) элемента массива, б) поиск двух наибольших (наименьших) чисел в массиве.
-
Выполните упражнение 6 c выбором элементов массива по указателямю.
-
Определите значение m как результат операторов:
int m = 0, n = 10; // x[10] = { 1, 2, 2, 3, 4, 4, 5, 6, 6, 7 }
for( int i = 0; i < n - i; i++) m
if( x[i] != x[i+1] ) m++; else m - -;
Работа 10. Обработка матриц
Цель работы: изучение приёмов обработки двумерных массивов данных, выработка умений алгоритмизации и программирования задач с двумерными массивами, отладки и тестирования программ с массивами.
/* Программа 10 меняет знак у "-"-ых элементов матрицы размером n х n ниже главной диагонали, n <= 10.
*/
#include <stdio.h>
#include <conio.h>
void in_matr(int x[ ][10], int n); // ввод матрицы размером n х n с консоли
void in_matr_rand(int x[ ][10], int n); // заполнение матрицы размером n х n
// случайными числами из интервала [-10, 10]
void out_matr(int x[ ][10], int n); // вывод матрицы размером n х n на экран
void processing(int x[ ][10], int n); // изменение знака у «-»-ых элементов
// матрицы ниже главной диагонали
Int main()
{ int n, x[10][10];
char ch;
// Вв/выв исходных данных:
// Не совмещайте ввод данных и их обработку !!! (Почему ?)
printf("Введите размер матрицы n <=10:”);
scanf("%d", &n);
printf("\n Ввод матрицы с консоли - 'c' или random() - 'r'? - ");
scanf("%c%c", &ch, &ch);
if((ch=='c') || (ch=='C')) in_matr( x, n);
else { randomize(); in_matr_rand( x, n); }
printf("\n Исходная матрица %d*%d \n", n, n);
out_matr( x, n );
processing(x, n);
printf("\n Обработанная матрица: \n");
out_matr( x, n );
getch();
return 0;
}
void in_matr(int x[ ][10], int n)
{ int I, j;
printf("\n Введите элементы матрицы n х n: \n");
scanf("%d", &n);
for ( i = 0; i < n; i++)
for ( j = 0; j < n; j++)
scanf("%d", &x[i][j]);
}
void out_matr(int x[ ][10], int n)
{ int i, j;
for ( i = 0; i < n; i++ )
{
for (j = 0; j < n; j++ )
printf("%d\t", x[i][j]);
printf("\n");
}
}
void processing(int x[ ][10], n) // Обработка матрицы:
{ int i, j;
for ( i = 1; i < n; i++)
for ( j = 0; j < i; j++)
if ( x[i][j] < 0 ) x[i][j] = -x[i][j];
}
void in_matr_rand(int x[][10], int n)
{ int i, j;
for ( i = 0; i < n; i++)
for ( j = 0; j < n; j++)
x[i][j]) = random(21) - 10;
}
Вопросы и упражнения
-
Как располагаются в памяти компьютера элементы двумерного массива?
-
Дополните программу 10 функцией out_matr_ptr( ) и протестируйте её.
void out_matr_ptr(int x[ ][10], int n)
{ int i, j, *pm;
pm=&x[0][0];
printf("\n Вывод матрицы по указателю: \n");
for ( i = 0; i < n*n; i++ )
{ printf("%5d", *pm++);
if((i+1)%n == 0) printf("\n");
}
}
-
Какое значение имеет объект программы имя двумерного массива?
-
Какое значение имеет объект программы x[k], если в программе объявлен массив int x[10][10]? Можно ли в программе использовать объект x[k]? Если «да», то для в каких случаях?
-
Как обратиться по указателю к элементу матрицы matr [i] [j]?
-
Напишите операторы вывода элементов двумерного массива по заданному условию: а) элементов k-й строки, б) элементов k-го столбца, в) элементов правой и левой диагоналей, г) элементов выше правой диагонали, д) элементов ниже левой диагонали.
-
Напишите функции: а) поиск столбца с минимальной суммой элементов, б) поиск строки с наибольшим числом «+»-ых элементов.
-
Выполните упражнения 6-а и 6-б с указателями, не используя индексацию для выбора элементов матрицы.
Работа 11. Сортировка массивов
Цель работы: изучение приёмов сортировки одномерных массивов данных, выработка умений алгоритмизации и программирования задач сортировки массивов, отладки и тестирования программ с массивами.
/* Программа 9. Программа демонстрирует типовые процедуры сортировки массивов по заданным условиям: удаление элементов, сортировка по возрастанию значений чисел, перемещение элементов. Задачи решаются без использования дополнительных массивов.
*/
#include <stdio.h>
#include <conio.h>
main()
{ int i, j, k, n;
int x[50];
printf("\n Введите размер массива n: \n");
scanf("%d", &n);
in_arr( x, n );
printf(" \n Исходный массив размером %d: \n", n);
out_arr( x, n );
// Удаление из массива нулевых элементов
k = array_del_0( x, n );
printf("\n\n Массив после удаления k = %d нулевых элементов: \n", k);
out_arr( x, n );
// Сортировка массива по возрастанию чисел методом пузырька
n = 10;
randomize();
for(i = 0; i < n; i++)
x[i] = random(20);
printf("\n\n Исходный массив: \n");
out_arr( x, n );
printf("\n Массив после сортировки методом пузырька: \n");
sort_bubble( x, n );
out_arr( x, n );
// Перемещение элементов x[i] < 0 в массиве после первого элемента x[k] < 0
n = 10;
for(i = 0; i < n; i++)
x[i] = random(20) - 10;
printf("\n\n Исходный массив: \n");
out_arr( x, n );
printf("\n В массиве x[i] < 0 перемещены после 1-го элемента x[k] < 0: \n");
move_negative_numbers( x, n );
out_arr( x, n );
getch();
return 0;
}
// Ввод n чисел массива arr[ ]
void in_arr( int *arr, int n )
{ printf("\n Введите %d чисел массива: ", n);
for ( int i = 0; i < n; i++)
scanf( "%d", arr++ ); // ввод по указателю
}
// Вывод n элементов массива arr[ ]
void out_arr( int *arr, int n )
{ for ( int i = 0; i < n; i++)
{ printf( " %d ", *arr++ ); // вывод по указателю и переход
// на следующий элемент массива
if ( (i+1) % 10 == 0 ) // вывод по 10 чисел в строке:
printf("\n");
}
}
// Удаление из массива нулевых элементов
// ТЕСТ: n = 5, x = 1, 0, 3, 0, 4 ==> n = 3, x = 1, 3, 4
int array_del_0(int *arr, int &n)
{ int i, j, k;
for (i = 0, k = 0; i < n; i++)
if (arr[i] == 0) k++;
else { j = i - k;
arr[j] = arr[i];
}
n = n - k; // размер массива после удаления нулевых элементов
return k; // количество удалённых нулевых элементов
}
// Сортировка массива по возрастанию чисел методом пузырька
// ТЕСТ: n = 5, x = 6, 2, 1, 4, 3 ==> x = 1, 2, 3, 4, 6
void sort_bubble( int *x, int n )
{ int i, k, w;
for( k = 1; k < n; k++) // перебор всех неупорядоченных частей
// массива размером n-k+1
for( i = 0; i < n-k; i++) // перестановка максимального числа из
// неупорядоченной части массива размером n-k+1 в конец этой части
if( x[i] > x[i+1] ) // перестановка большего числа вправо
{ w = x[i];
x[i] = x[i+1];
x[i+1] = w;
}
}
// перемещение "-"-ых элементов в массиве после первого "-"-го элемента
// ТЕСТ: n = 6, x = 1, -2, 3, -4, -5, 6 ==> x = 1, -2, -4, -5, 3, 6
void move_negative_numbers( int *x, int n )
{ int i, k = n, w;
for(i = 0; i < n - 2; i++) // поиск 1-го "-"го элемента
if( x[i] < 0 ) { k = i + 1; break; }
if( k == n ) return; // "-"х чисел в массиве нет или перестановка
// не требуется
for( i = k; i < n; i++) // перемещение "-"-х элементов после 1-го
// "-"-го элемента
if( x[i] < 0 )
{ w = x[i];
x[i] = x[k];
x[k] = w;
k++;
};
}
Вопросы и упражнения
-
На какой элемент массива указывает индекс k в функции move_negative_numbers( ) ?
-
Составьте алгоритм удаления из массива элемента хi , заданного индексом i.
-
Составьте алгоритм удаления из массива элемента, заданного значением этого элемента.
-
Составьте алгоритм, по которому можно поменять местами первый и последний положительные элементы в массиве.
-
Составьте алгоритм сортировки массива методом выбора: находится минимальный элемент массива и меняется местами с первым элементом, далее процедура повторяется для неупорядоченной части массива.
-
Напишите функции для алгоритмов упражнений 2-5.
Работа 12. Сортировка матриц
Цель работы: изучение приёмов сортировки двумерных массивов данных, выработка умений алгоритмизации и программирования задач сортировки массивов, отладки и тестирования программ с массивами.
/* Программа 12. Программа демонстрирует типовые процедуры сортировки двумерных массивов по заданным условиям: поиск строки матрицы, сортировка столбцов по возрастанию значений чисел заданной строки, перемещение строк или столбцов. Задачи решаются без использования дополнительных массивов.
*/
// Прототипы функций программы:
void in_matr(int x[ ][10], int m, int n); // ввод матрицы размером m *n
// с клавиатуры
void in_matr_rand(int x[ ][10], int m, int n); // заполнение матрицы размером
// m*n случайными числами из интервала [-10, 10].
void out_matr(int x[ ][10], int m, int n); // вывод матрицы размером m*n
// на экран.
void processing(int x[ ][10], int *y, int m, int n); // функция заменяет // в матрице размером m*n строки, не содержащие "+"-ых элементов, // элементами массива y[ ].
void sort_columns(int x[ ][10], int m, int n); // располагает столбцы матрицы
// размером m*n в порядке возрастания элементов первой строки.
void rows_move(int x[ ][10], int m, int n); // перемещение строк с первым 0-м
// элементом на место последних строк матрицы.
#include <stdio.h>
#include <conio.h>
void main( )
{ int m, n, x[10][10], y[10] = {10, 9, 8, 7, 6, 5, 4, 3, 2, 1};
char ch;
printf(" *** Matrix Sort *** ");
printf("\n\n Введите размеры матрицы m<=10, n<=10: ");
scanf("%d %d", &m, &n);
printf("\n Ввод матрицы с клавиатуры - 'c' или заполнение ");
printf(" случайными числами - 'r'? - ");
scanf("%c%c", &ch, &ch);
if((ch=='c') || (ch=='C')) in_matr( x, m, n);
else { randomize(); in_matr_rand( x, m, n);}
printf("\n Исходная матрица: %d*%d \n", m, n);
out_matr( x, m, n );
processing(x, y, m, n);
printf("\n Замена строк с отрицательными элементами числами \
заданного массива: \n");
out_matr( x, m, n );
sort_columns(x, m, n);
printf("\n Сортировака столбцов матрицы в порядке возрастания \
элементов первой строки: \n");
out_matr( x, m, n );
printf("\n перемещение строк с первым 0-м элементом на место \
последних строк матрицы: \n");
rows_move( x, m, n );
out_matr( x, m, n );
getch();
return 0;
}
/* Коды функций in_matr( ), in_matr_rand( ) и out_matr( ) приведены в программе 10 (с. 46). Модификацию функций для матрицы размером m х n выполните самостоятельно.
Функция processing( ) заменяет в матрице размером m х n строки с "-"-ми элементами числами массива y[ ].
ТЕСТ: m = 4, n = 4, y[ ] = { 10, 9, 8, 7 },
-1 -1 -1 -1 10 9 8 7
x = -2 2 -2 -2 => -2 2 -2 -2
-3 -3 -3 -3 10 9 8 7
4 -4 4 4 4 -4 4 4
*/
void processing( int x[ ][10], int *y, int m, int n )
{ int i, j, k;
for ( i = 0; i < m; i++ ) // проверка всех строк
{ j = -1;
do // поиск в строке 'i' элемента x[i][j] >= 0
{ j++;
if( x[i][j] >= 0 && j != n) break; // то элемент найден
if( j == n ) // строка 'i' с "-"-ми элементами
for ( k=0; k<n; k++) x[i][k] = y[k];
}
while ( j != n );
}
/* Функция rows_move( ) перемещает строки с первым 0-м элементом на место последних строк матрицы размером m*n.
ТЕСТ: m = 4, n = 4,
0 1 1 1 4 4 4 4
x = 2 2 2 2 => 2 2 2 2
0 3 3 3 0 3 3 3
4 4 4 4 0 1 1 1
*/
void rows_move(int x[ ][10], int m, int n)
{ int ii = 0, // номер строки с первым нулевым элементом
kk = n-1, // номер строки с первым ненулевым элементом
// от последней строки
i, j, k, w;
while( ii < kk )
{ for ( i = ii; i < m-1; i++) // поиск строки с первым нулевым элементом
if( x[i][0] == 0 ) break;
ii = i;
for ( k = kk; k > ii; k- -) // поиск строки с первым ненулевым элементом
if( x[k][0] != 0 ) break; // от последней строки
kk = k;
if( ii < kk ) // меняем строки ii и kk местами
for ( j = 0; i < n; j++) // столбцы j и k
{ w = x[ii][j];
x[ii][j] = x[kk][j];
x[kk][j] = w;
}
ii++, kk--;
}
}
/* Функция sort_columns( ) располагает столбцы матрицы размером m*n
в порядке возрастания элементов первой строки.
ТЕСТ: m = 4, n = 4,
3 1 2 0 0 1 2 3
x = 3 1 2 0 => 0 1 2 3
3 1 2 1 1 1 2 3
3 1 2 2 2 1 2 3
*/
void sort_columns(int x[ ][10], int m, int n)
{ int i, j, k, z;
for ( j = 0; j < n-1; j++)
for ( k = j+1; k < n; k++)
if ( x[0][j] > x[0][k] ) // меняем местами
for ( i = 0; i < m; i++) // столбцы j и k
{ z = x[i][j];
x[i][j] = x[i][k];
x[i][k] = z;
}
}
Вопросы и упражнения
-
Сколько циклов нужно для просмотра всех элементов n-мерного массива?
-
Запишите циклы для инвертирования матрицы m х n (замена строк столбцами).
-
Поясните следующий фрагмент программы для обработки матрицы а размером n x n:
for( j = 0; j < n; j++ )
for( i = n-1; i > j; i-- ) а[i][j] = а[ i - j ] [ n-1 - j ]
-
Составьте функцию для удаления: а) k- го столбца матрицы; б) k-ой строки матрицы.
-
Поясните алгоритм сортировки в функции sort_columns(). Модифицируйте функцию для сортировки по методу «пузырька».
-
Как выполнить перемещение строк в функции rows_move( ) сохранив последовательность строк с ненулевым первым элементом относительно друг друга?
Список литературы
-
Березин, Борис Иванович. Начальный курс С и С++ / Березин, Борис Иванович, Березин, Сергей Борисович. - М.: ДИАЛОГ-МИФИ, 1999, 2001, 2000, 2003. - 288c. - Библиогр.: с. 284. - ISBN 5-86404-075-4.
-
Давыдов, Владимир Григорьевич. Программирование и основы алгоритмизации: Учеб. пособие / Давыдов, Владимир Григорьевич. - М.: Высш. школа, 2003. - 447c.: ил. - Библиогр.: с. 442. - ISBN 5-06-004432-7.
-
Крячков, Антон Викторович. Программирование на C и C++: Практикум: Учеб. пособие для студ. вузов / Крячков, Антон Викторович, Сухинина, Ирина Вадимовна, Томшин, Владимир Константинович; Под ред. В. К. Томшина. - М.: Радио и связь, 1997. - 344c.: ил. - Библиогр.: с. 329. - ISBN 5-256-01250-9.
-
Павловская, Татьяна Александровна. С. С++. Программирование на языке высокого уровня: Учеб. / Павловская, Татьяна Александровна. - СПб.: Питер, 2003, 2004. - 461c.: ил. - ISBN 5-94723-568-4.
-
Подбельский, Вадим Валерьевич. Программирование на языке Си: Учеб. пособие / Подбельский, Вадим Валерьевич, Фомин, Сергей Сергеевич. - М.: Финансы и статистика, 1999, 2000, 2001, 2003. - 600c.: ил. - ISBN 5-279-02180-.
-
Топп, Уильям. Структуры данных в С++ / Топп, Уильям, Форд, Уильям. - М.: БИНОМ, 1999. - 816c.: ил. - ISBN 5-7989-0017-7.