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

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

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

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

Боби 5. Сохторҳои шартӣ: `if`, `else` ва `switch`

Боби 5. Сохторҳои шартӣ: if, else ва switch

Дар алгоритмҳои воқеӣ кам иттифоқ меафтад, ки тамоми амалҳо танҳо ба таври хаттӣ иҷро шаванд. Аксар вақт компютер бояд вобаста аз вазъият ва додаҳои воридшуда «қарор қабул кунад» — масалан, оё адад мусбат аст ё манфӣ, оё муодила реша дорад ё не, ё кадом шохаи ҳисоббарориро бояд пеш гирифт. Дар ин боб шумо тарзи сохтани алгоритмҳои шоханокро бо сохторҳои шартии if ва switch дар забони Go меомӯзед.

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

  • Амалҳои муқоиса (==, !=, ``, =) ва натиҷаи онҳо.
  • Амалҳои мантиқӣ: конъюнксия (&&), дизъюнксия (||) ва инкор (!).
  • Сохтори асосии шартии if, else if ва else.
  • Қоидаҳои синтаксиси Go барои шартҳо (қавсҳои ҳатмии фигурии {}).
  • Эълони кӯтоҳи тағйирёбанда пеш аз шарт.
  • Оператори интихоби switch ... case, шакли бе тағйирёбандаи он ва калимаи fallthrough.
  • Ҳалли мукаммали муодилаи квадратӣ ва дигар масъалаҳои шоханок.

Амалҳои муқоиса ва амалҳои мантиқӣ

Барои он ки шартеро бисанҷем, аввал бояд бузургиҳоро бо ҳам муқоиса намоем. Натиҷаи ҳар як амали муқоиса ҳамеша навъи мантиқии bool (true ё false) мебошад.

Амалҳои муқоиса

АмалАломат дар GoМисолНатиҷа
Баробарӣ==5 == 5true
Нобаробарӣ!=5 != 3true
Хурд<4 < 9true
Калон>7 > 10false
Хурд ё баробар<=5 <= 5true
Калон ё баробар>=8 >= 12false

[!WARNING] Ҳеҷ гоҳ аломати бахшидани қимат (=) ва аломати муқоисаи баробариро (==) омехта накунед! a = 5 — ба тағйирёбандаи a қимати 5 медиҳад. a == 5 — месанҷад, ки оё a ба 5 баробар аст ё не.

Амалҳои мантиқӣ

Ҳангоми санҷидани шартҳои мураккаб, якчанд муқоисаро бо амалҳои мантиқӣ муттаҳид месозанд:

  1. «Ва» (конъюнксия — &&): Натиҷа танҳо вақте true мешавад, ки ҳар ду шарт дуруст бошанд.
    x := 7
    fmt.Println(x > 0 && x < 10) // true (зеро x ҳам аз 0 калон аст ва ҳам аз 10 хурд)
    
  2. «Ё» (дизъюнксия — ||): Натиҷа вақте true мешавад, ки ҳадди ақал яке аз шартҳо дуруст бошад.
    fmt.Println(x < 0 || x == 7) // true (зеро x ба 7 баробар аст)
    
  3. «Не» (инкор — !): Қимати мантиқиро баръакс мекунад (true → false, false → true).
    fmt.Println(!(5 > 10)) // true (чунки 5 > 10 нодуруст аст, ва инкори он дуруст мешавад)
    

Сохтори шартии if, else if ва else

Дар забони Go сохтори if ба барнома имкон медиҳад, ки дар сурати дуруст будани шарт порчаи муайяни кодро иҷро кунад.

Намуди содатарини он:

if shart {
	// коде, ки дар ҳолати дуруст будани шарт иҷро мешавад
}

Агар барои ҳолати нодуруст будани шарт низ код лозим бошад, шохаи else илова мешавад:

if shart {
	// агар шарт дуруст бошад
} else {
	// агар шарт нодуруст бошад
}

Қоидаҳои муҳими синтаксиси Go

  1. Дар Go гирди шарт гузоштани қавсҳои оддӣ ( ) шарт нест (ва одатан гузошта намешавад):
    if x > 0 { // дуруст ва услуби тозаи Go
    
  2. Қавсҳои фигурии { } ҳамеша ҳатмӣ мебошанд, ҳатто агар дар дохили онҳо танҳо як сатри код бошад.
  3. Қавси кушодашавандаи фигурии { бояд дар ҳамон сатри if ё else бошад, на дар сатри нав! Калимаи else низ бояд дар ҳамон сатри қавси пӯшидашавандаи } навишта шавад:
    // ДУРУСТ:
    if x > 0 {
    	fmt.Println("Мусбат")
    } else {
    	fmt.Println("Манфӣ ё сифр")
    }
    
    // ХАТО (Go иҷозат намедиҳад):
    if x > 0
    {
    	...
    }
    

Якчанд шарт бо else if

Агар масъала якчанд ҳолатро талаб кунад, мо метавонем шохаҳои else if-ро пайваст намоем:

Дар ин барнома (ва дар ҳамаи барномаҳои минбаъда) мо натиҷаи fmt.Scan-ро месанҷем: агар корбар ба ҷойи адад матн ворид кунад, барнома паёми хато медиҳад. Шакли if _, err := ...; err != nil дар қисми навбатӣ шарҳ дода мешавад.

package main

import "fmt"

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

	if n > 0 {
		fmt.Println("Ин адади мусбат аст.")
	} else if n < 0 {
		fmt.Println("Ин адади манфӣ аст.")
	} else {
		fmt.Println("Ин адад сифр (0) аст.")
	}
}

Эълони тағйирёбанда дар дохили if

Яке аз имкониятҳои беназир ва зебои забони Go ин аст, ки шумо метавонед тағйирёбандаро бевосита дар сатри if, пеш аз худи шарт эълон кунед:

if x := a * b; x > 100 {
	fmt.Println("Ҳосили зарб хеле калон аст:", x)
} else {
	fmt.Println("Ҳосили зарб:", x)
}

Дар ин ҷо тағйирёбандаи x дар шарт ва блокҳои if ва else дастрас аст. Берун аз ин сохтор ба он муроҷиат кардан мумкин нест. Ин тарз доираи истифодаи тағйирёбандаи муваққатиро маҳдуд мекунад.

Маъмултарин истифодаи ин шакл — санҷиши хатогии воридот:

if _, err := fmt.Scan(&n); err != nil {
	fmt.Println("Хато: адад ворид карда нашуд.")
	return
}

Ин ҷо fmt.Scan ду қимат бармегардонад: шумораи қиматҳои хондашуда (онро бо аломати _ нодида мегирем) ва хатогӣ err. Қимати nil маънои «хато нест»-ро дорад. Бо функсияҳое, ки якчанд қимат бармегардонанд, дар боби 9 муфассал шинос мешавем.


Ҳалли мукаммали муодилаи квадратӣ

Дар китоби кӯҳнаи Бейсик (§29) ҳалли муодилаи квадратии ax² + bx + c = 0 бо ёрии якчанд фармони печидаи GOTO сохта шуда буд. Биёед бубинем, ки ин масъала бо сохтори сода ва зебои Go чӣ тавр ҳал мешавад:

package main

import (
	"fmt"
	"math"
)

func main() {
	var a, b, c float64

	fmt.Print("Коэффисиентҳои a, b ва c-ро дохил кунед: ")
	if _, err := fmt.Scan(&a, &b, &c); err != nil {
		fmt.Println("Хато: бояд се адад ворид карда шавад.")
		return
	}

	// Санҷиши ҳолати хаттӣ будани муодила (агар a = 0)
	if a == 0 {
		if b == 0 {
			if c == 0 {
				fmt.Println("Муодила беохир бисёр реша дорад (0 = 0).")
			} else {
				fmt.Println("Муодила реша надорад (зиддият).")
			}
		} else {
			x := -c/b + 0 // «+ 0» қимати -0-ро ба 0 табдил медиҳад
			fmt.Printf("Ин муодилаи хаттӣ аст. Решааш: x = %.2f\n", x)
		}
		return // Барнома ба охир мерасад
	}

	// Ҳисобкунии дискриминант
	d := b*b - 4*a*c

	// Ададҳои ҳақиқӣ бо хатогии хурди яклухткунӣ ҳисоб мешаванд,
	// бинобар ин D-ро на бо 0, балки бо адади хеле хурди eps муқоиса мекунем.
	const eps = 1e-9

	if d > eps {
		x1 := (-b+math.Sqrt(d))/(2*a) + 0
		x2 := (-b-math.Sqrt(d))/(2*a) + 0
		fmt.Println("Муодила ду решаи ҳақиқӣ дорад:")
		fmt.Printf("x1 = %.4f\n", x1)
		fmt.Printf("x2 = %.4f\n", x2)
	} else if d >= -eps {
		x := -b/(2*a) + 0
		fmt.Printf("Муодила ду решаи баробар (решаи дукарата) дорад: x = %.4f\n", x)
	} else {
		fmt.Println("Муодила дар майдони ададҳои ҳақиқӣ реша надорад (D < 0).")
	}
}

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

Коэффисиентҳои a, b ва c-ро дохил кунед: 1 -3 2
Муодила ду решаи ҳақиқӣ дорад:
x1 = 2.0000
x2 = 1.0000

Ба се ҷузъиёти ин барнома диққат диҳед:

  1. Санҷиши воридот. Агар корбар ба ҷойи адад, масалан, abc ворид кунад, err ба nil баробар намешавад. Бе ин санҷиш тағйирёбандаҳо қимати пешфарзи 0-ро нигоҳ медоштанд ва барнома ба ғалат «Муодила беохир бисёр реша дорад» менавишт.
  2. Сифри манфӣ. Дар ададҳои ҳақиқӣ қимати махсуси -0 вуҷуд дорад: масалан, барои x² = 0 ифодаи -b / (2*a) ба -0 баробар мешавад ва Printf -0.0000 чоп мекунад. Илова кардани + 0 ин қиматро ба 0-и оддӣ табдил медиҳад ва ба дигар ададҳо таъсир намерасонад.
  3. Муқоисаи ададҳои ҳақиқӣ. Ҳисобҳо бо float64 тақрибӣ мебошанд, бинобар ин D метавонад ба ҷойи 0 қимате монанди 1e-16 гирад. Барои ҳамин мо шарти d == 0-ро бо math.Abs(d) <= eps (яъне -eps <= d <= eps) иваз кардем.

Оператори интихоби switch

Вақте ки лозим аст як тағйирёбанда бо даҳҳо қимати гуногун муқоиса шавад (масалан, интихоби рӯзи ҳафта, баҳо ё фармони меню), навиштани даҳҳо else if кодҳоро нохоно мекунад.

Барои ин дар забони Go оператори пурқуввати switch мавҷуд аст:

package main

import "fmt"

func main() {
	var baho int
	fmt.Print("Баҳои гирифтаатонро дохил кунед (2, 3, 4, 5): ")
	if _, err := fmt.Scan(&baho); err != nil {
		fmt.Println("Хато: баҳо бояд адади бутун бошад.")
		return
	}

	switch baho {
	case 5:
		fmt.Println("Аъло! Офарин!")
	case 4:
		fmt.Println("Хуб! Кӯшиш кунед боз ҳам беҳтар шавад.")
	case 3:
		fmt.Println("Қаноатбахш. Бояд бештар мутолиа кунед.")
	case 2:
		fmt.Println("Ғайриқаноатбахш. Мавзӯъро аз нав такрор кунед.")
	default:
		fmt.Println("Хато: чунин баҳо дар мактаб вуҷуд надорад!")
	}
}

Бартарии бузурги switch дар Go нисбат ба C++ ва Java

Дар шакли анъанавии switch дар C++ ва Java иҷро метавонад аз як case ба навбатӣ гузарад, агар break ё дастури дигари қатъи иҷро набошад.

Дар забони Go ин мушкил бартараф шудааст: ҳар як case худаш ба таври худкор ва бехатар қатъ мегардад (break навиштан шарт нест)!

Шумо ҳамчунин метавонед дар як case якчанд қиматро бо вергул нависед:

switch moh {
case 12, 1, 2:
	fmt.Println("Зимистон")
case 3, 4, 5:
	fmt.Println("Баҳор")
case 6, 7, 8:
	fmt.Println("Тобистон")
case 9, 10, 11:
	fmt.Println("Тирамоҳ")
}

switch бе тағйирёбанда — ивази занҷири else if

Агар пас аз калимаи switch ҳеҷ чиз нанависед, ҳар як case шарти мантиқии худро мегирад. Go шартҳоро аз боло ба поён месанҷад ва аввалин шохаеро, ки шарташ дуруст аст, иҷро мекунад. Ин шакл дар Go барои ивази занҷирҳои дарози if ... else if маъмул аст:

package main

import "fmt"

func main() {
	var harorat float64
	fmt.Print("Ҳарорати ҳаворо дохил кунед (°C): ")
	if _, err := fmt.Scan(&harorat); err != nil {
		fmt.Println("Хато: адад ворид кунед.")
		return
	}

	switch {
	case harorat < 0:
		fmt.Println("Ях мебандад.")
	case harorat < 15:
		fmt.Println("Хунук.")
	case harorat < 30:
		fmt.Println("Мӯътадил.")
	default:
		fmt.Println("Гарм.")
	}
}

Калимаи fallthrough

Агар дар ҳолати махсус ба шумо лозим бошад, ки баъд аз як case шохаи навбатӣ низ иҷро шавад, калимаи fallthrough-ро дар охири case нависед. Он шохаи навбатиро бе санҷиши шарташ иҷро мекунад:

switch n := 1; n {
case 1:
	fmt.Println("як")
	fallthrough
case 2:
	fmt.Println("ду")
case 3:
	fmt.Println("се")
}
// Натиҷа:
// як
// ду

Дар амал fallthrough хеле кам истифода мешавад; одатан якчанд қимат дар як case (бо вергул) роҳи равшантар аст.


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

5–1. Калонтарини се адад: Барномае нависед, ки се адади ҳақиқии a, b, c-ро қабул карда, калонтарини онҳоро (max(a, b, c)) бо ёрии сохтори if чоп намояд.

5–2. Санҷиши секунҷа: Се порчаи дарозиашон x, y, z дода шудаанд. Муайян кунед, ки оё аз ин се порча секунҷа сохтан мумкин аст? (Ёдрас: Секунҷа танҳо вақте вуҷуд дорад, ки суммаи ҳар ду тарафи он аз тарафи сеюм калон бошад: x + y > z, x + z > y, y + z > x). Агар сохтан мумкин бошад, муайян кунед, ки оё он секунҷаи росткунҷа аст: квадрати тарафи калонтарин бояд ба суммаи квадратҳои ду тарафи дигар баробар бошад (масалан, x² + y² = z², агар z калонтарин бошад). Ҳар се ҳолатро санҷед. Дарозиҳоро ададҳои бутун гиред, то баробарии ададҳои ҳақиқӣ мушкил наорад.

5–3. Нуқта ва доира: Доираи марказаш (0, 0) ва радиусаш R > 0, инчунин нуқтаи (x, y) дода шудаанд. Муайян кунед, ки нуқта дар дохили доира, рӯйи давра ё берун аз доира ҷойгир аст. Барои ин x² + y²-ро бо R² муқоиса кунед: хурд будан, баробар будан ва калон будан се ҳолати ҷудогонаанд.

5–4. Ҳисобкунаки оддӣ бо switch: Барномае созед, ки ду адади a ва b ва як аломати амали риёзиро (+, -, *, /) қабул карда, бо ёрии switch амали дахлдорро иҷро кунад ва натиҷаро чоп намояд. Ҳолати ба сифр тақсим карданро ба назар гиред!


Хулоса

Дар ин боб шумо сохторҳои шартиро ҳамчун пояи алгоритмҳои шоханок аз худ кардед. Фаҳмидед, ки амалҳои муқоиса ва мантиқӣ чӣ гуна кор мекунанд, тарзи навишти бехатари if/else-ро бо қавсҳои ҳатмӣ омӯхтед ва дидед, ки оператори switch чӣ тавр интихоби якчанд ҳолатро бениҳоят сода ва хоно мегардонад.

Дар боби 6 мо ба яке аз муҳимтарин ва пуриқтидортарин қисмҳои барномасозӣ — даврҳо (for) — мегузарем, ки ба мо имкон медиҳанд амалҳоро ҳазорон ва миллионҳо маротиба бо суръати барқ такрор намоем.

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