Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

книги / Язык Си

..pdf
Скачиваний:
6
Добавлен:
20.11.2023
Размер:
7.64 Mб
Скачать

Телом цикла поj является только

p r i n t f ("%3d*%d=%2d", i , j , i *j ) ;

Строка printf("\n"); относится к циклу по /, но не по j, по­ скольку, если в тело цикла входит более одной лексемы, заканчи­ вающейся точкой с запятой, тело цикла нужно заключить в фигур­ ные скобки (как это сделано для тела цикла по /).

При каждом вхождении в цикл по j один раз будет выпол­ няться инициализация j = 1. Всего данная инициализация выпол­ нится 9 раз, поскольку параметр / меняется от 1 до 9 включительно.

Инициализация для цикла по / выполнится только 1 раз (/ =1), поскольку это внешний цикл и он не является телом других циклов.

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

Пример. Напечатать числа в виде таблицы.

6

5

4

3

2

1

 

 

 

 

5

4

3

2

1

 

 

 

 

 

4

3

2

1

 

 

 

 

 

 

3

2

1

 

 

 

 

 

 

 

2

1

 

 

 

 

 

 

 

 

1

 

 

 

 

 

 

 

 

 

Обозначим номер ряда перемен­

 

 

 

 

ной i,

а номер столбца - переменной j.

 

 

 

 

Ряды будем нумеровать в обратном

6

5

4

3 2 1

порядке: верхний ряд имеет номер 6,

следующий -

номер 5 и т.д. Таким об­

//Ъ

4

3

2 1

разом, переменная / будет меняться от

i - 4

3

2

1

6 до 1 включительно, а переменная j в

'х 3

2

1

 

каждой строке будет меняться от / (см. рисунок справа) до 1 включительно.

#include<conio.h>

#include<stdio.h>

main()

{int i/j/S;

for(i=6;i>0;i— )

{ for(j=i;j>0;j— )

printf(n%2d",j);

printf("\n");

}

getch();

return 0;

Нарисуйте блок-схему для данной задачи.

Подведем небольшой итог. В любом цикле необходимо нали­ чие параметра, по которому будет определяться, когда завершится цикл. Следовательно, этот параметр должен иметь начальное зна­ чение и где-то его менять, иначе цикл зависнет. В операторах while и do-while инициализация параметра происходит вне цикла, а из­ менение параметра - внутри цикла, тогда как оператор for уже имеет для этого разделы в своем заголовке (не надо «ползать» по телу цикла и искать, где параметр меняет свое значение). Таким образом, в программировании на языке Си оператор for получил наибольшую популярность из-за того, что он более удобен в ис­ пользовании.

Еще раз отметим, что while, do-while иfor приводят к одним и тем же результатам. Каким оператором цикла пользоваться в той или иной ситуации, решает сам программист.

РЕШЕНИЕ ЗАДАЧ

 

 

X X

X

Задача 1. Вычислить сумму ряда х + — + — +... + — .

F

3 5

11

JC3

Видно, что начиная с члена — и до конца ряда знаменатель 3

совпадает со степенью числителя у каждого члена. Таким образом, для их обозначения достаточно одной переменной, например, /. Эта переменная будет меняться от 1 до 11 с шагом 2. Для подсчета суммы используем переменную s и поместим в нее начальное зна­ чение не 0, а х, т.е. уже просуммируем первый член ряда.

#include<stdio.h>

#include<conio.h>

#include<math.h> main()

{float x,s; int n=ll,x;

puts("Введите x:"); scanf("%f",&x);

s=x;

//учли в

сумме первый

член ряда,

i=3;

//поэтому

начинаем со

второго члена

while(i<=n)

//прибавляем текущий член

{s+=pow(х,i)/i;

i+=2;

 

//ряда к общей сумме

//переходам на новый

член ряда

}

printf("Сумма ряда = %f",s);

getch(); return 0;

}

Задача 2. Найти факториал заданного числа п!.

Вспомним, что п\ это 1 • 2 • 3 • • и . Таким образом, мы должны организовать цикл по накоплению произведения от 1 до п включи­ тельно. Для подсчета накопленного произведения введем пере­ менную Р и зададим ей начальное значение 1. Также нужно преду­ смотреть, что факториал отрицательного числа не существует, а факториал 0! равен 1. Для этого используем оператор условия if-else.

#include<conio.h>

#include<stdio.h> main()

{int n, P, in­

puts ("Введите целое число"); scanf("%d",&n) ;

if(n<0)

printf("Факториала нет"); else if(n==0 || n==l) printf("Факториал = 1"); else

{i=l; //первый член ряда, с которого стартуем Р=1; //начальное значение накопленного

//произведения

while(i<=n) //пока не достигнут конец ряда, {P*=i; //накапливаем произведение,

i++; //переходим на новый член ряда

//печатаем результат printf("Факториал = %d",P);

}

getch() ;

return 0;

}

Задача 3. Вычислить суммуряда

1

х + —X

5

л + ...+ X10

3

4

12

Посмотрим внимательно на ряд. От члена к члену числитель последовательно увеличивается на 1 и к тому же совпадает с но­ мером члена ряда. Введем для обозначения числителя и номера члена ряда переменную /. Знаменатель у каждого из членов ряда больше на 1 значения числителя, т.е. его можно обозначить как / + 1. Степень при х у каждого из членов ряда меньше на 1 значе­ ния числителя, т.е. ее можно обозначить как / —1. Также от члена к члену меняется знак. Для учета этого введем переменную ZN, а смену знака будем осуществлять путем умножения ZN на -1 на каждой итерации цикла. Сумму ряда стандартно накапливаем в переменную s, в которую поместим первый член ряда, равный 1 (будем считать, что мы его уже просуммировали).

#include<stdio.h>

#include<conio.h>

#include<math.h> main()

{float x,s;

int n=ll,i,ZN; puts("Введите x"); scanf("%f",&x) ;

s=l;

//просуммировали

первый

член ряда

i=2;

//начинаем суммирование со 2-го члена

ZN=-1;

//знак у второго

члена

ряда

while(i<=n)

{s+=ZN*(float)i/(i +1)*pow(x, i-1) ;

i++;

//переходим на новый член ряда

ZN*=-1;

//меняем у него знак на

 

//противоположный

}

print f ("%f"fs);

}

Обратите внимание, что здесь понадобилось привести пере­ менную i (которая объявлена как тип int) к типу float, иначе выра­ жение i/(i + I) будет равно 0 (а с ним и все произведение), по­ скольку при делении целочисленных переменных дробная часть не запоминается.

Задача 4. Найти п-й член ряда Фибоначчи.

Ряд Фибоначчи формируется по правилу: новый член ряда ра­ вен сумме двух предыдущих членов ряда. Первые два члена ряда равны 1. Таким образом, ряд Фибоначчи имеет вид 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ... Нумерация членов ряда начинается с 0.

#include<conio.h>

#include<stdio.h> main ()

{int n, i, F, F_2, F_l; puts("Введите целое число");

scant(M%dM,&n); //считываем номер искомого //члена ряда

if(п==0

||

n==l)

//если

номер члена 0 или 1

printf("Число Фибоначчи = 1"); //то ответ 1

else

//иначе

суммирование

с члена номер 2

{i=2;

//начинаем

F_l=l;

//предыдущий член ряда

ряда

F_2=l;

//предпредыдущий

член

while(i<=n)

 

 

 

{F=F_1+F_2;//новый член ряда

 

F_2=F_1;

//перезапись

предпредыдущего члена

F_1=F;

 

//перезапись

предыдущего члена

i++;

 

 

//переходим на новый член ряда

}

//печатаем ответ

printf("Число Фибоначчи = %d",F);

}

}

Задача 5. Получить все трехзначные числа Армстронга.

Число Армстронга - это Л^-значное число, у которого сумма цифр, возведенных в степень N, равна самому числу. Например, 153 = I3 + 53 + З3, 1634 = I4 + 64 + З4 + 44. Мы ищем трехзначные числа Армстронга, поэтому в цикле нужно перебирать все числа от 100 до 999 включительно, разбирать их на цифры и проверять по формуле для трехзначного числа. Если число является числом Армстронга, то печатаем его. Затем переходим к проверке нового числа и т.д.

#include<conio.h>

#include<stdio.h>

#include<math.h> main( )

{int n,ed,ds,st,ts, S;

for(n=100;n<1000;n++)

сотен

{st=n/100;

//выделяем разряд

ds=n/10%10;

//выделяем разряд

десятков

ed=n%10;

//выделяем разряд

единиц

//формула

S=pow (ed, 3) +pow (ds, 3) +pow (st, 3) ;

if(S==n) //если это число Армстронга,

printf("%d\n",n); //печатаем его

}

getch();

return 0;

Ответ: 153,370, 371,407.

Задача 6. Найти на отрезке от т до п натуральное число с максимальной суммой делителей.

#include<conio.h>

#include<stdio.h> main()

{int 111=10,n=4 0;//интервал, на котором ищем число int S,MAX=0,i,j,k;

//во внешнем цикле перебираем числители //от m до п

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

{S=0; //Обнуляем сумму делителей

//во внутреннем цикле перебираем знаменатели

//от 1 до

i/2

 

 

 

 

 

for(j=l;j<=i/2;j++)

j является делителем

if(i%j == 0) //если

 

//числа i

 

 

 

S+=j; //то накапливаем делитель в S

if(S>MAX)

//если

накопленная

сумма

превышает

{MAX=S;

//все

предыдущие,

сумму

для

//то запоминаем эту

 

//будущих

сравнений

 

 

k=i; //запоминаем

само

число

делителей

//с максимальной

суммой

}

 

 

 

 

 

 

printf("chislo=%d",k); //печатаем результат getch() ;

return 0;

}

Ответ: 36.

ДОМАШНЕЕ ЗАДАНИЕ

1. Написать программу, которая по заданному натуральному значению п и действительному х вычисляет результат выражения ■S^sinx + sinx2 + ... + sin^n

2. Написать программу, которая по заданному натуральному значению п вычисляет результат выражения у = 1 • 3• 5• • (2и -1 ).

3.Написать программу, которая по заданному натуральному значению п вычисляет результат выражения F = 1!+ 2! + 3! +... + и!.

4.Напечатать числа в виде таблицы

1

21

32 1

43 2 1

54 3 2 1

65 4 3 2 1

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

int i=0,j=3,а=4;

for( ; i<3; i++,j— )

{if(i>j)

a++; else

a— ;

}

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

int i=0,j=3,a=4;

for( i<3; i++,j— )

if(i>j)

a++; else

a— ;

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

int n=3,i,j,a=0; for(i=0; i<n; i++)

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

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

int n=3,i,j,a=0; for(i=0; i<n; i++) {for(j=0; j<n; j++)

a++;

a— ;

}

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

int n=3,i=0,j=0 ,а=0; for( i<n; i++)

a+=i+j;

for( j<n; j++)

a+=i+j;

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

int n=4,i,j,a=0; for(i=0,j=0; i<n; i++,j=n)

{while(j>0)

{if(i>j)

a+=i;

j — ;

}