Зеҳн
Алгоритмсозӣ ва барномасозӣ дар забони Go

Китоби таълимии забони Go барои мактабиён, донишҷӯён ва омӯзгорон: аз алгоритм ва блок-схемаҳо то веб-сервер ва боти Телеграм. Таҷдиди китоби А. П. Назаров «Алгоритмсозӣ ва барномасозӣ дар забони Бейсик» (2009).

Агенти Зеҳнӣ · 26 октябри 2026 · 15 саҳифа

МаорифБарномасозӣТехнология
Аз аввал хондан

Боби 6. Даврҳо дар Go

Боби 6. Даврҳо дар Go

Дар барномасозӣ ҳисоб кардани як формула барои як адад душвор нест. Қудрати ҳақиқии компютер дар он аст, ки метавонад як амалро миллионҳо маротиба дар як сония бе хато ва бе хастагӣ такрор кунад. Ин такроршавӣ бо ёрии даврҳо (loops) амалӣ мешавад. Дар забони кӯҳнаи Бейсик якчанд намуди даврҳо бо калимаҳои гуногун вуҷуд доштанд (FOR...NEXT, WHILE...WEND, ҷаҳиш бо GOTO). Забони Go ин мафҳумро ба авҷи содагӣ расонидааст: дар Go танҳо як калимаи калидӣ барои ҳамаи намудҳои давр вуҷуд дорад — for.

Дар ин боб меомӯзем

  • Сохтори ягона ва пуриқтидори даври for дар Go.
  • Чор шакли асосии даври for: классикӣ (бо ҳисобкунак), аз рӯи адад (for i := range n), шартӣ (монанди while) ва беохир.
  • Идоракунии давр бо операторҳои break ва continue.
  • Ҳисобкунии суммаҳо, ҳосили зарбҳо ва факториал (N!).
  • Даврҳои дарунбадарун (nested loops) ва сохтани ҷадвали зарб.
  • Алгоритмҳои ҷустуҷӯи тақсимкунандаҳо ва санҷиши ададҳои сода (ададҳои Фибоначчӣ — дар машқҳо).

Чор тарзи истифодаи даври for дар Go

Дар Go барои сохтани даврҳо калимаи калидии for истифода мешавад. Шаклҳои гуногуни он даврҳои дорои ҳисобкунак, даврҳои шартӣ ва даврҳои беохирро ифода мекунанд:

1. Даври классикӣ бо се бахш (бо ҳисобкунак)

Ин шакли маъмултарини давр мебошад, ки вақте шумораи дақиқи такрорҳо пешакӣ маълум аст, истифода мешавад:

for ibtido; shart; qadam {
	// танаи давр
}
  • ibtido (ибтидо): эълони ҳисобкунак ва додани қимати аввала (масалан i := 1). Танҳо як бор дар аввал иҷро мешавад.
  • shart (шарт): пеш аз ҳар як даврзанӣ санҷида мешавад (масалан i <= 10). Агар дуруст бошад, давр идома меёбад.
  • qadam (қадам): дар охири ҳар як даврзанӣ ҳисобкунакро тағйир медиҳад (масалан i++, ки маънои i = i + 1-ро дорад).

Мисоли 1: Чопи ададҳо аз 1 то 5:

package main

import "fmt"

func main() {
	for i := 1; i <= 5; i++ {
		fmt.Println("Адад:", i)
	}
}

Натиҷа:

Адад: 1
Адад: 2
Адад: 3
Адад: 4
Адад: 5

Агар хоҳед қадами давр 2 ё 5 бошад, метавонед i += 2 ё i += 5 нависед:

// Чопи ададҳои ҷуфт аз 2 то 10
for i := 2; i <= 10; i += 2 {
	fmt.Print(i, " ")
}
// Натиҷа: 2 4 6 8 10

2. Давр аз рӯи адад: for i := range n (Go 1.22+)

Аз версияи Go 1.22 сар карда, барои такрори амал маҳз n маротиба шакли кӯтоҳтар мавҷуд аст. Ифодаи for i := range n ҳисобкунакро аз 0 то n-1 мегузаронад:

package main

import "fmt"

func main() {
	for i := range 5 {
		fmt.Print(i, " ")
	}
	fmt.Println()
}

Натиҷа:

0 1 2 3 4 

Ин шакл ба for i := 0; i < 5; i++ баробар аст ва эҳтимоли хатои «як қадам зиёд ё кам»-ро коҳиш медиҳад. Агар ҳисобкунак лозим набошад, онро наменависем: for range 3 { fmt.Println("Салом!") }.

[!NOTE] Аз Go 1.22 инҷониб тағйирёбандае, ки бо := дар сарлавҳаи давр эълон мешавад, дар ҳар даврзанӣ нусхаи алоҳида дорад. Ин қоида ба тағйирёбандаҳои қаблан эълоншуда, ки дар давр бо = қимат мегиранд, дахл надорад. Фарқи мазкур ҳангоми истифодаи функсияҳо ва горутинаҳо дар дохили давр муҳим аст.


3. Даври танҳо бо шарт (ивази while)

Агар бахши аввал ва охири даврро партоед, танҳо як шарт боқӣ мемонад. Ин давр то он даме кор мекунад, ки шарти додашуда дуруст бошад:

package main

import "fmt"

func main() {
	i := 1
	for i <= 5 {
		fmt.Println(i)
		i++ // худамон дар дохили давр зиёд мекунем
	}
}

Ин навъ вақте хеле муфид аст, ки мо дақиқ намедонем давр чанд бор такрор мешавад ва он ба як шарти махсус вобаста аст (масалан, то замоне ки корбар калимаи «баромад»-ро ворид накунад ё адад аз як ҳудуди муайян нагузарад).


4. Даври беохир

Агар тамоми шартҳоро партоед, даври беохир ҳосил мешавад:

for {
	// Ин код то беохир такрор мешавад!
}

Даври беохир дар барномаҳои муосир барои корҳои пайваста васеъ истифода мешавад (масалан, сервери веб ҳамеша мунтазири паёми нав аст). Барои баромадан аз чунин давр фармони махсуси break истифода мегардад.


Идоракунии давр: break ва continue

Дар забони Go ду калимаи муҳим барои идоракунии рафтори давр мавҷуд аст:

  1. break (қатъ кардан): Даврро фавран қатъ мекунад ва иҷрои барномаро ба сатри баъд аз давр мегузаронад.
  2. continue (идома додан): Қисми боқимондаи баданаи даврзании ҷориро мегузаронад. Дар даври себахша аввал амали қадам иҷро ва баъд шарт аз нав санҷида мешавад.

Мисол:

package main

import "fmt"

func main() {
	for i := 1; i <= 10; i++ {
		if i == 5 {
			continue // адади 5-ро чоп накун, ба қадами оянда гузар!
		}
		if i == 8 {
			break // вақте ба 8 расидӣ, даврро тамоман қатъ кун!
		}
		fmt.Print(i, " ")
	}
}

Натиҷа:

1 2 3 4 6 7 

(Бубинед: 5 партофта шуд, ва дар 8 давр қатъ гардид).


Масъалаҳои классикии алгоритмсозӣ бо даврҳо

Биёед чанд масъалаи муҳимро, ки дар китоби кӯҳна оварда шуда буданд, бо забони Go ҳал кунем:

Масъалаи 1. Суммаи ададҳои тоқ

Суммаи ҳамаи ададҳои тоқро аз 1 то N ҳисоб кунед:

package main

import "fmt"

func main() {
	var n int
	fmt.Print("Адади N-ро дохил кунед: ")
	if _, err := fmt.Scan(&n); err != nil {
		fmt.Println("Хато: адади бутун ворид кунед.")
		return
	}

	summa := 0
	for i := 1; i <= n; i += 2 {
		summa += i // баробар ба: summa = summa + i
	}

	fmt.Printf("Суммаи ададҳои тоқ аз 1 то %d баробар аст ба: %d\n", n, summa)
}

Масъалаи 2. Ҳисобкунии факториал (N!)

Факториали адади натуралии N ин ҳосили зарби тамоми ададҳои аз 1 то N мебошад: N! = 1 · 2 · 3 · … · N

Диққат: Барои ҳисоб кардани ҳосили зарб ба тағйирёбандаи натиҷа аввал қимати 1 медиҳанд, на 0. Зарб ба сифр натиҷаро сифр мекунад.

package main

import "fmt"

func main() {
	var n int
	fmt.Print("Адади натуралии N-ро дохил кунед: ")
	if _, err := fmt.Scan(&n); err != nil {
		fmt.Println("Хато: адади бутун ворид кунед.")
		return
	}

	if n < 0 {
		fmt.Println("Факториал барои ададҳои манфӣ муайян нашудааст!")
		return
	}
	if n > 20 {
		// 21! аз қимати калонтарини uint64 (тақрибан 1.8·10¹⁹) зиёд аст
		fmt.Println("Барои N > 20 натиҷа дар uint64 намеғунҷад!")
		return
	}

	// Навъи uint64 ададҳои бутуни мусбатро то 18446744073709551615 нигоҳ медорад
	var faktorial uint64 = 1
	for i := 1; i <= n; i++ {
		faktorial *= uint64(i)
	}

	fmt.Printf("%d! = %d\n", n, faktorial)
}

Намунаи иҷро:

Адади натуралии N-ро дохил кунед: 20
20! = 2432902008176640000

[!WARNING] Факториал хеле зуд меафзояд. 20! ≈ 2.4 · 10¹⁸ ҳанӯз дар uint64 ҷой мегирад, аммо 21! ≈ 5.1 · 10¹⁹ аз ҳадди он мегузарад. Go дар ин ҳолат хато намедиҳад: аз ҳудуди навъ гузаштан (overflow) рух медиҳад ва натиҷаи нодуруст ҳосил мешавад. Аз ин рӯ мо N > 20-ро пешакӣ рад кардем. Барои ҳисоби факториали ададҳои калон дар Go бастаи стандартии math/big (навъи big.Int) мавҷуд аст, ки ададҳои бутуни калонро дар ҳудуди хотираи дастрас нигоҳ медорад.


Масъалаи 3. Ҷустуҷӯи тақсимкунандаҳо ва санҷиши адади сода

Адади натуралии N дода шудааст. Ҳамаи тақсимкунандаҳои мусбати онро чоп кунед ва муайян намоед, ки он сода, мураккаб ё 1 аст. Адади сода аз 1 калон буда, маҳз ду тақсимкунандаи мусбат дорад: 1 ва худи адад. Масалан: 2, 3, 5, 7, 11, 13. Адади 1 на сода асту на мураккаб.

Аввал ҳамаи тақсимкунандаҳоро бо як даври оддӣ меёбем:

package main

import "fmt"

func main() {
	var n int
	fmt.Print("Адади натуралии N-ро дохил кунед: ")
	if _, err := fmt.Scan(&n); err != nil || n < 1 {
		fmt.Println("Хато: адади натуралӣ (N ≥ 1) ворид кунед.")
		return
	}

	shumora := 0 // шумораи тақсимкунандаҳо
	fmt.Printf("Тақсимкунандаҳои %d: ", n)
	for i := 1; i <= n; i++ {
		if n%i == 0 { // бақия 0 аст, яъне i адади n-ро бебақия тақсим мекунад
			fmt.Print(i, " ")
			shumora++
		}
	}
	fmt.Println()
	fmt.Println("Шумораи тақсимкунандаҳо:", shumora)
}

Намунаи иҷро:

Адади натуралии N-ро дохил кунед: 36
Тақсимкунандаҳои 36: 1 2 3 4 6 9 12 18 36 
Шумораи тақсимкунандаҳо: 9

Адади сода маҳз ду тақсимкунанда дорад (1 ва худаш). Аммо барои санҷиши сода будан ҳамаи ададҳоро аз назар гузаронидан шарт нест: агар N тақсимкунандаи i > √N дошта бошад, пас тақсимкунандаи ҷуфти он N/i < √N аст. Бинобар ин то √N санҷидан кифоя аст ва баъди ёфтани аввалин тақсимкунанда даврро бо break қатъ мекунем:

package main

import "fmt"

func main() {
	var n int
	fmt.Print("Адади бутуни мусбати N (>1)-ро дохил кунед: ")
	if _, err := fmt.Scan(&n); err != nil {
		fmt.Println("Хато: адади бутун ворид кунед.")
		return
	}

	if n <= 1 {
		fmt.Println("Адади сода бояд аз 1 калон бошад.")
		return
	}

	sodaAst := true

	// Барои санҷиш то решаи квадратии N санҷидан кифоя аст
	for i := 2; i*i <= n; i++ {
		if n%i == 0 {
			sodaAst = false
			break // агар ҳадди ақал як тақсимкунанда ёфт шуд, дигар санҷидан лозим нест
		}
	}

	if sodaAst {
		fmt.Printf("Адади %d адади СОДА аст.\n", n)
	} else {
		fmt.Printf("Адади %d адади МУРАККАБ аст.\n", n)
	}
}

Даврҳои дарунбадарун ва ҷадвали зарб

Агар дар дохили як давр даври дигар ҷойгир бошад, онҳоро даврҳои дарунбадарун (nested loops) меноманд. Ҳар боре ки иҷро ба даври дарунӣ мерасад, он аз нав оғоз мешавад ва то иҷро нашудани шарт ё қатъ гардидани он идома меёбад.

Ин сохтор барои сохтани ҷадвалҳо ва матритсаҳо беҳтарин васила аст.

Мисоли 4: Ҷадвали зарб аз 2 то 9:

package main

import "fmt"

func main() {
	fmt.Println("======== ҶАДВАЛИ ЗАРБ ========")
	for i := 2; i <= 9; i++ {
		for j := 1; j <= 10; j++ {
			fmt.Printf("%d x %2d = %2d    ", i, j, i*j)
			if j == 5 {
				fmt.Println() // ҳар ҷадвалро ба ду қатори 5-тоӣ ҷудо мекунем
			}
		}
		fmt.Println()
		fmt.Println("-------------------------------")
	}
}

Худатон бисанҷед

6–1. Пайдарпайии Фибоначчӣ: Аввалин N аъзои пайдарпайии машҳури Фибоначчиро чоп кунед: 0, 1, 1, 2, 3, 5, 8, 13, 21 … (Ҳар як аъзои навбатии пайдарпайӣ аз суммаи ду аъзои қаблӣ ҳосил мешавад).

6–2. Баргардонидани рақамҳо: Адади бисёррақамаи натуралии N дода шудааст (масалан 12345). Бо ёрии даври for рақамҳои онро ба таври чаппа чоп кунед: 54321.

6–3. Ҳисоби сумма бо шарти қатъ: Суммаи зеринро ҳисоб кунед: S = 1/1² + 3/2² + 5/3² + 7/4² + … + (2i − 1)/i² Ҳисоббарориро то он даме давом диҳед, ки аъзои навбатӣ аз 0.001 хурд шавад. Чанд қадам иҷро шуд ва сумма ба чанд баробар гардид?

6–4. Расмкашӣ бо ситорачаҳо: Бо истифода аз даврҳои дарунбадарун дар экран секунҷаи зеринро ҳосил кунед:

*
**
***
****
*****

Хулоса

Дар ин боб шумо фаҳмидед, ки забони Go чӣ гуна тамоми имкониятҳои даврзаниро танҳо дар зери як оператори ягона ва фаҳмои for муттаҳид кардааст. Шумо даврҳои дорои ҳисобкунак, шакли нави for i := range n, даврҳои шартӣ ва тарзи истифодаи break ва continue-ро омӯхтед ва якчанд алгоритми бунёдиро аз қабили ҳисоби факториал, ёфтани тақсимкунандаҳо, санҷиши ададҳои сода ва ҷадвали зарб татбиқ намудед.

Дар боби 7 мо ба массивҳо ва буришҳо (slices) мегузарем, ки ба мо имкон медиҳанд на як адад, балки садҳо ва ҳазорон ададро дар як сохтори муттаҳид нигоҳ дорем ва коркард намоем.

пешина
аз 15
навбатӣ