Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Proga_otvety.docx
Скачиваний:
2
Добавлен:
03.08.2019
Размер:
72.02 Кб
Скачать

Создание нового массива из отрицательных элементов исходного:

#include <stdio.h>

main()

{

int i; // временные переменные

int array[10]; // это сам массив

int size = 10; // это размер массива (от 0)

int nw_array[10]; // это будущий массив.

int nw_size = 0; // его размер пока не известен. обнуляем.

// -------------------------------------

// ввод элементов:

// -------------------------------------

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

{

printf( "\n array[%d]: ", i );

scanf( "%d", &array[i] );

}

// -------------------------------------

// Создаем массив из отриц. эл-тов

// -------------------------------------

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

if( array[i] < 0 )

{

nw_array[nw_size] = array[i];

nw_size++;

}

// -------------------------------------

// На экран его!

// -------------------------------------

if( nw_size )

puts( "array have no elements below zero" );

else // К.О. кстати, это не обязательно, т.к. цикл тогда просто не выполнится.

{

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

printf( "\n %d", nw_array[i] );

}

getch();

return 0;

}

19. Сортировка элементов одномерного массива.

#include <stdio.h>

main()

{

int i,j,t; // временные переменные

int forsort[10]; // это сам массив

int size=10; // это размер массива

// -------------------------------------

// ввод элементов:

// -------------------------------------

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

{

printf( "n forsort[%d]: ", i );

scanf( "%d", &forsort[i] );

}

// -------------------------------------

// сортировка:

// -------------------------------------

for( i=0; i<size-1; i++ )

{

for( j=i+1; j<size; j++ )

{

if( forsort[i] > forsort[j] )

{

t = forsort[i];

forsort[i] = forsort[j];

forsort[j] = t;

}

}

}

// -------------------------------------

// выводим сие чудо:

// -------------------------------------

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

printf( "n%d", forsort[i] );

getch(); // чтоб успеть все это прочитать ^^^

return 0; /* а это потому что мейн целый ( main() <=> int main() ) и

он по-хорошему должен что-то возвращать целое. например,

ноль. а можно написать void main() и ничего не возвращать.

*/

}

20. Указатели.

Указатель - это переменная, содержащая адрес другой пе-

ременной. указатели очень широко используются в языке "C".

Это происходит отчасти потому, что иногда они дают единст-

венную возможность выразить нужное действие, а отчасти пото-

му, что они обычно ведут к более компактным и эффективным

программам, чем те, которые могут быть получены другими спо-

собами.

Описание указателя переменной:

признаками переменной-указателя являются две составляющие:

1. тип объекта данных, для доступа к которому используется указатель.

2. * перед именем переменной.

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

#include <alloc.h>

а вот пример динамического выделения памяти:

int *p1;

p1 = (int*)malloc( sizeof(int) );

21. Операции над указателями.

  • присваивание

  • операция сравнения, сложения, вычитания.

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

22-23)Связь одномерных-двумерного массивов с указателями.

Между указателями и массивами существует определенная связь. Предположим, имеется массив из 100 целых чисел. Запишем двумя способами программу суммирования элементов этого массива:

long array[100];

long sum = 0;

for (int i = 0; i < 100; i++)

sum += array[i];

То же самое можно сделать с помощью указателей:

long array[100];

long sum = 0;

for (long* ptr = &array[0];

ptr < &array[99] + 1; ptr++)

sum += *ptr;

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

for (long* ptr = array;

ptr < &array[99] + 1; ptr++)

sum += *ptr;

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

При использовании многомерных массивов указатели позволяют обращаться к срезам или подмассивам. Если мы объявим трехмерный массив exmpl:

long exmpl[5][6][7]

то выражение вида exmpl[1][1][2] – это целое число, exmpl[1][1] – вектор целых чисел (адрес первого элемента вектора, т.е. имеет тип *long), exmpl[1] – двухмерная матрица или указатель на вектор (тип (*long)[7]). Таким образом, задавая не все индексы массива, мы получаем указатели на массивы меньшей размерности.

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

Так как указатели сами являются переменными, то вы впол-

не могли бы ожидать использования массива указателей. Это

действительно так.

Мы нуж-

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

удобно и эффективно обрабатывать строки текста переменной

длины.

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

сортировке сроки хранятся одна за другой в длинном символь-

ном массиве (управляемом, например, функцией ALLOC), то к

каждой строке можно обратиться с помощью указателя на ее

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

25. Строки символов.

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

э т о с т р о к а \0

То, что идет после нулевого байта \0 можно не заполнять. При использовании строки функцией типа printf() текст после нуль-байта и сам нуль-байт выводиться не будут.

Строки обычно запоминаются одним из трех способов.

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

Например:

puts( "ололо" );

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

Например:

char str[] = "ололо";

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

Например:

char *str = NULL;

str = malloc( 6*sizeof(char) ); // ололо = 5 букв по одному байту + 1 байт

strcpy(str, "ололо");

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

#include <string.h>

важные функции, которые я бы отметил:

1) strlen( строка )

эта функция вернет длину строки в символах (без нулевого байта). таким образом, strlen("hello") вернет 5.

2) strcpy( destination, source )

Оператор присваивания для строк не определен. Если c1 и c2 - символьные массивы, вы не сможете скопировать один в другой так:

c1 = c2; // так нельзя

Чтобы скопировать одну строку в другую, вместо использования оператора присваивания вызовите функцию копирования строк strcpy().

strcpy(c1,c2); // четкий и верный годный вариант

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

26. Использование указателей для адресации строк символов.

Указатели для для адресации строк символов используются, чтобы динамически выделить память под строку, в зависимости от её длины. При этом важно не забыть, что строка, в отличии от простого массива символов, имеет нуль-байт на конце, под который тоже нужно выделить байт, а, вернее, sizeof(char);

Ну вот придумал пример:

char *str = NULL; // если не установить адрес на нулл, то может не сработать

int i;

int j=10;

str = malloc( sizeof(char)*(j+1) ); // выделяем память под j символов и нулевой байт

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

{

str[i] = getch(); // записываем поочередно все это в память

}

str[i] = '\0'; // и нуль-байт. теперь это строка.

puts( str ); // выводим на экран

27. Функции. Объявление и описание.

Принцип программирования основан на использовании функций. Выполенение прграммы начинается с выполнения главной функции - main().

Функция - самостоятельная единица программы, спроектированная для решения конкретной задачи, сущность которой формулируется простым предложением. (прим. а вот с этим я бы поспорил: ну-ка сформулируйте простым предложением функцию мейн из второй-третьей программы. так что нифига, это просто рекоммендация.)

Достоинства функции:

- позволяет избежать повторного программирования.

- одну и ту же функцию можно использовать в нескольких программах.

- использование функций облегчает чтение кода и внесение изменений.

Прежде чем вызвать функцию нужно написать ее прототип (описание функции).

Вообще говоря, есть два пути:

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

2) написать всю функцию перед мейном, а на прототип - вообще забить.

К.О.: Но на деле получается так, что если у вас нет кучи вложенных функций, то прототипы вообще не нужны. В обратном случае прототипы понадобятся вне зависимости, перед мейном написаны сами функции или нет.

void f( int ); // это прототип

void main( void )

{

int l = 2;

f( l );

}

// -----------------------------

void f( int x ) // это функция

{

printf( "%d", x );

}

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

Пример 1.

#include <stdio.h>

/* прототип функции. в принципе, можно было не думать, а просто

скопировать "int quad( int p )" и поставить точку с запятой в конце,

но четкий вариант - еще убрать имена параметров: */

int quad( int );

void main()

{

int x, y; // есть целые х и y

x = 2; // x у нас равен двойке

y = quad( x ); // после вызова нашей функции y становится равным тому, что она возвращает

printf( "%d\n", y ); // выводим y - он равен четверке

y = quad( y ); // вызываем функцию от y - четыре в квадрате - 16

printf( "%d\n", y ); // выводим y, на экране видно 16

printf( "%d\n", quad(15) ); // выводим на экран квадрат 15, т.е. 225

if( quad(x) == quad(y) ) // использование в проверке

{

puts( "квадрат x = квадрату y" );

}

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

функции в цикле for(). В итоге получаем список квадратов чисел от

1 до 32. так-то. */

for( x=1; x<=32; x++ )

printf( "y = %d\n", quad(x) );

getch();

}

int quad( int p )

{

int t;

t = p * p;

return t;

}

28. Функции без аргументов.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

29. Использование указателей в качестве параметров функций.

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

void f( int*, int* )

void main( )

{

int x = 5, y = 10;

printf( "x = %d, y = %d \n", x, y );

f( &x, &y )

printf( "x = %d, y = %d \n", x, y );

}

void f( int *y, int *x )

{

int t;

t = *y;

// ололо здесь какая-то байда с параметрами, я ее не записал)

// ну, допустим (на самом деле это не так уж и важно):

t++;

*x = 100500;

}

Если в качестве параметров функции используется массив, то внутрь попадает начальный адрес массива. (К.О.: адрес первого элемента этого массива)

void f( int *, int );

// in the begining...

30. Функции для строк.

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

#include <string.h>

1) strlen( строка )

эта функция вернет длину строки в символах (без нулевого байта). таким образом, strlen("hello") вернет 5.

2) strcpy( destination, source )

Оператор присваивания для строк не определен. Если c1 и c2 - символьные массивы, вы не сможете скопировать один в другой так:

c1 = c2; // так нельзя

Чтобы скопировать одну строку в другую, вместо использования оператора присваивания вызовите функцию копирования строк strcpy().

strcpy(c1,c2); // четкий и верный годный вариант

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

31. Причины появления ошибок в программах.

1)неверное понимание поставленной задачи, приводит к решению другой задачи.

2)Неверная разработка спецификаций алгоритма может привести к правильному результату лишь для некоторых подмножестввсех данных.

3)неверное понимание используемых средств языка программирования может ввести ошибку при разработке код. алгоритма.

4)При вводе программы в компьютер можно ввести ошибки типа “опечатки”.

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

32. Тесты. Отладка программ.

33. Проверка программ «вручную». Анализ программ.

34. Проверка программ «вручную». Прокрутка.

Основные методы выявления ошибок является тестирование и отладка.

Тестирование: выявление ошибки

Отладка: устранение ошибки

Тестирование есть компьютерное и ручное.

Ручное(анализ)-проверка алгоритма по тексту без использования компьютера.

Анализ выполняется в несколько этапов:

1)проверка описания данных

2)Проверка правильности обработки данных

3)проверка вычислит функций

4)проверка логики (циклы!!!)

5)проверка интерфейса между функциями

6)проверка ввод\вывод

7)проверка помеха-защита

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]