Ошибки программирования циклов 


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



ЗНАЕТЕ ЛИ ВЫ?

Ошибки программирования циклов



int x = 5;

while (x > 0); //точка с запятой является пустым оператором, он и будет телом цикла

x--;

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

Нужно следить за корректностью условий выхода из циклов. Например, в С++ цикл

do { операторы } while (условие)

завершается, когда условие становится ложным.

В Pascal соответствующий цикл с постусловием

repeat операторы until условие

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

В цикле for неверное условие выхода из цикла может повлечь за собой ошибки, например:

int arr[10];

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

arr[i] = i * i;

arr[9] не обработается! Ошибка «по привычке» при переходе с языка Pascal / Delphi, где явно указывается конечное значение: for i:= 0 to 9 do...

Указатели должны быть инициализированы

Всякий раз, когда вы используете  указатель, вы должны быть способны ответить на вопрос:

 куда он указывает? Если вы не можете ответить на этот вопрос, вероятнее всего,этот указатель не указывает никуда. Этот тип ошибки при работе под DOS может привести к нарушению работы системы, а при работе под Windows - к сбою выполняемой программы.

#include <string.h>

int main() {

char *st; // указатель на символ или символьный массив

strcpy (st, “abc”); // куда указывает st?

return 0;

}

Правильный вариант 1:

#include <string.h>

int main() {

char  st [20]; // st - указатель на символьный массив

strcpy (st, “abc”); // st указывает на начало символьного массива

return 0;

}

Правильный вариант 2:

#include <string.h>

#include <stdlib.h>

int main() {

char  *st = malloc (20); /* st - указатель на символьный массив, размещенный в

                                                 динамической памяти */

strcpy (st, “abc”); // st указывает на начало символьного массива

free (st); // не забудьте освободить память

return 0;

}

4.8. Сравнение строк с использованием ==, <=, >=, <, >

Никогда не  используйте операции ==, <=, >=, <, > для сравнения строк в С! Строки – символьные массивы. Имя символьного массива, как и любого другого массива – это указатель на начало массива. Сравнивая строки с помощью операций ==, <=, >=, <, >,

вы сравниваете указатели.

char st1[] = “abc”;

char st2[] = “abc”;

if (st1 == st2)

printf (“Строки равны\n”);

else printf (“Строки не равны\n”);

Этот код выведет «Строки не равны», т.к. сравниваются значения указателей st1 и st2, а не содержимое строк. Корректный способ сравнить две строки – использование функции strcmp(). Не забудьте при этом #include <string.h>.

if (strcmp(st1, st2) == 0)

printf (“Строки равны\n”);

else printf (“Строки не равны\n”);

Строки, не завершенные нуль – символом

Язык С работает со строками, оканчивающимися нуль – символом ‘\0’ == 0. Если он отсутствует, обработка строки может продолжаться сколь угодно долго, пока не встретится нулевой байт в памяти.

Оставляйте место для нуль – символа

Частая ошибка – забыть выделить пространство для дополнительного нуль – символа. Символьный массив

cha r str [30];

может вместить строку длиной не более 29 символов данных.

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

char *copy_str = malloc (strlen (orig_str) + 1);// не забудьте +1

strcpy (copy_str, orig_str);

Sizeof ()

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

Примеры.

int  *arr = (int *)malloc (20 * sizeof (int));

/* выделяется память под 20 значений типа int */

double x = 1;

char *ptr = (char *) &x;

for (int i = sizeof (x) – 1; i >= 0; --i) {

printf (“ “);

for (int j = 7; j >= 0; --j)

             printf (“%i”, (*(ptr+i) & (1 << j))? 1: 0);

}

/* Вывод внутреннего представления переменной   x типа double. Здесь sizeof() используется для определения количества байт, занимаемых переменной x.

На экран в данном примере будет выведено

00111111 11110000 00000000 00000000 00000000 00000000 00000000 00000000

*/

Void main()

Вообще говоря, следующие два варианта объявления функции main () являются рабочими:

· int main(){

      ....

      return 0;

}

· void main(){

      ....

      return 0;

}

Тем не менее, следует пользоваться только первым вариантом. Это связано с тем, что число, которое возвращает функция main(), является кодом возврата в операционную систему. В случае объявления void main() стандарт С89 не предусматривает определенного кода возврата. Иными словами, в этом случае программа вернет в операционную систему произвольное число в зависимости от компилятора.

 

5.1.2.2.1. Запуск программы. Функция, вызывающая запуск программы, называется main() (главная). Реализация не объявляет прототип для этой функции. Он должен быть определен путем возврата целого типа int без параметров:            int main (void) {...} либо с двумя параметрами (здесь они называются argc и argv, хотя можно использовать любые имена в том порядке, как они размещены в функции, в которой объявлены):   int main(int argc, char *argv[]){...} либо некоторым другим определенным в реализации способом. 5.1.2.2.3. Завершение программы. Если возвращаемый главной функцией тип является типом, совместимым с int, то возврат в главную функцию эквивалентен вызову функции выхода со значением, возвращенным главной функцией в качестве ее аргумента; при достижении скобки }, которая завершает главную функцию, возвращается значение 0. Если возвращаемый тип несовместим с типом int, состояние завершения, возвращаемое в хост – среду, является неспецифицированным.  

P.S.

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

 

 

   

 

 

 

 

 

 



Поделиться:


Последнее изменение этой страницы: 2021-03-09; просмотров: 186; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

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