Салам! Бүгүн биз Javaдагы секирүү операторлору жөнүндө сүйлөшөбүз:
return
break
continue
goto
if
) жана циклдер ( for
, while
ж.б.). Башкаруу структураларынан тышкары, программанын сызыктуу аткарылышын секирүү операторлору менен өзгөртүүгө болот. Алар контекстке жана конкреттүү билдирүүгө жараша программанын аткарылышын белгилүү бир жерге багыттоо үчүн жооптуу. Келгиле, төрт оператордун ар бирин кененирээк карап чыгалы.
кайтуу
Дал ушул оператор менен жаңы келгендер көбүнчө биринчи таанышат. Билдирмеreturn
ал чакырылган ыкманы токтотот жана программанын аткарылышы ыкма чакырылган жерге кайтып келет. Анын return
эки формасы бар:
- Методдун аткарылышын дароо аяктайт.
- Методдун аткарылышын дароо аяктайт жана методдун натыйжасы катары кандайдыр бир маанини кайтарат.
return;
return value; // где value — некоторое возвращаемое meaning
Маани кайтарган методдордо return
чакырылышы кепилденген кайтаруу мааниси бар жок дегенде бир оператор болушу керек жана return
кайтаруу мааниси жок оператор болбошу керек. Төмөндөгү мисалдарды карап көрөлү:
public int sum(int a, int b) {
return a + b;
}
public String getGreetings(String name) {
return "Hello " + name;
}
public int max(int x, int y) {
if (x > y) {
return x;
} else {
return y;
}
}
Маани кайтарбаган методдордо (методдор void
) алгылыктуу, бирок талап кылынbyte, жок дегенде бир return
кайтаруу мааниси жок билдирүүгө ээ болуу жана return
кайтаруу мааниси бар бир дагы билдирүүгө ээ болуу талап кылынbyte. Муну төмөндөгү мисалдар менен карап көрөлү:
public void print(String s) {
// наличие return в void методах не обязательно
System.out.println(s);
}
//Метод выведет в консоль число, если оно нечетное
public void printIfOdd(int number) {
if (number % 2 == 0) {
// Если число четное, метод завершит свою работу
// Наличие return в void методах опционально
return;
}
System.out.println(number);
}
// Метод выведет в консоль наибольшее meaning из массива
private void printMaxInArray(int[] array) {
if (array == null || array.length == 0) {
/*
Если массив пуст, метод завершит свою работу.
Иногда полезно проверять подобным образом аргументы метода вначале и прерывать выполнение метода, если аргументы не подходят для дальнейшей корректной работы
*/
System.out.println("Empty array");
return;
}
int max = array[1];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
System.out.println(max);
}
этикеткалар
break
жана операторлорун карап чыгуудан мурун continue
, мен Java тorндеги энбелгилер жөнүндө айткым келет. Бул маанилүү, анткени кээ бир учурларда break
жана операторлор continue
этикеткалар менен бирге колдонулат. Бирок, адегенде, бул code түзүлөбү деген суроого жооп берип көрүңүз:
public static void main(String[] args) {
https://www.google.com/
System.out.println("Interesting...");
}
Энбелги - бул аталган codeдун бөлүгү. Этикетканын өзү эч кандай функцияны камсыз кылbyte. Бул программист кийинчерээк колдонууга ниеттенген codeдогу кыстарма сыяктуу нерсе. Коддогу энбелги абдан жөнөкөй - ысым жана кош чекит аркылуу аныкталат. Мисалы:
labelName:
outerLoop:
printing:
anyWordYouLike:
public static void main(String[] args) {
definePrintName:
System.out.println("Таблица Умножения");
loop1:
for (int i = 1; i <= 10; i++) {
loop2:
for (int j = 1; j <= 10; j++) {
System.out.printf("%4d", i * j);
}
System.out.println();
}
}
Методдун натыйжасы main
төмөнкүдөй болот:
Таблица Умножения
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
Process finished with exit code 0
Жогорудагы мисалда definePrintName
, loop1:
жана loop2:
энбелгилер. loop1:
жана loop2:
эки циклди "белгилегиле" - тышкы жана ички. Биз төмөнкү бөлүмдө энбелгилерди колдонууну карап чыгабыз. Ошол эле учурда, эгерде сиз бул code түзүлөбү деген суроого "жок" деп жооп берсеңиз:
public static void main(String[] args) {
https://www.google.com/
System.out.println("Interesting...");
}
IDE аркылуу ага кайра жооп берип көрүңүз.
тыныгуу
Операторbreak
эки учурда колдонулат:
- Которушчу-кап блогунда кандайдыр бир аткаруу бутагын аяктоо үчүн.
- Циклдин аткарылышын үзгүлтүккө учуратууга.
break labelName; // Синтаксис оператора с меткой
break; // Синтаксис оператора без метки
Switch-case блоктарында оператор break
энбелгисиз колдонулат:
public static void main(String[] args) {
int dayOfWeekInt = 4;
String dayOfWeek;
switch (dayOfWeekInt) {
case 1:
dayOfWeek = "Monday";
break;
case 2:
dayOfWeek = "Tuesday";
break;
case 3:
dayOfWeek = "Wednesday";
break;
case 4:
dayOfWeek = "Thursday";
break;
case 5:
dayOfWeek = "Friday";
break;
case 6:
dayOfWeek = "Saturday";
break;
case 7:
dayOfWeek = "Sunday";
break;
default:
dayOfWeek = "Неизвестный день";
break;
}
System.out.println("Сегодня " + dayOfWeek);
}
Циклдерде оператор break
белгилүү бир шарттар аткарылгандан кийин кийинки итерацияларды үзүү үчүн колдонулат. Бул көп учурда массивди же элементтердин коллекциясын кайталап, андан керектүү шарттарды канааттандырган кандайдыр бир элементти табуу керек болгондо тапса болот. Бул мисалды карап көрөлү. Бизде массив бар жана массивде терс элементтер бар-жогун аныкташыбыз керек:
int a[] = {1,2,234,-123,12,-2,312,0,412,433};
boolean arrayHasNegativeElements = false;
for (int i = 0; i < a.length; i++) {
if (a[i] < 0) {
/*
Как только найдется
хотя бы один отрицательный элемент,
мы прервем цикл с помощью
оператора break, потому что
мы выяснor то, что нас интересовало,
и дальнейший перебор элементов не имеет смысла.
*/
arrayHasNegativeElements = true;
break;
}
}
Келгиле, ар кандай илмек менен бир эле мисалды карап көрөлү. Цикл for-each
:
public static void main(String[] args) {
int a[] = {1,2,234,-123,12,-2,312,0,412,433};
boolean arrayHasNegativeElements = false;
for (int number : a) {
if (number < 0) {
arrayHasNegativeElements = true;
break;
}
}
}
Цикл while
:
public static void main(String[] args) {
int a[] = {1,2,234,-123,12,-2,312,0,412,433};
boolean arrayHasNegativeElements = false;
int counter = 0;
while (counter < a.length) {
if (a[counter] < 0) {
arrayHasNegativeElements = true;
break;
}
counter ++;
}
}
Цикл do-while
:
public static void main(String[] args) {
int a[] = {1,2,234,-123,12,-2,312,0,412,433};
boolean arrayHasNegativeElements = false;
int counter = 0;
do {
if (a[counter] < 0) {
arrayHasNegativeElements = true;
break;
}
counter ++;
} while (counter < a.length);
}
Циклдеги билдирүүнүн дагы бир мисалы, break
белгилүү бир шарттар аткарылганда чексиз циклди үзүү. Бул жерде колдонуучу "стоп" деген сөздү киргизмейинче колдонуучу киргизген сапты көрсөткөн программанын мисалы:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String line;
while (true) {
line = scanner.nextLine();
if ("stop".equals(line)){
/*
Прерываем бесконечный цикл,
при достижении
определенного условия
*/
break;
}
System.out.println("Пользователь ввел: " + line);
}
}
Операторду break
энбелги менен бирге колдонууну карап көрөлү. Белгилүү үзгүлтүк бир нече циклден турган учурларда колдонулат, анын үстүнө бири бири-бирине уя салынган. Бул учурда циклдердин бири (же бардык циклдер) этикетка менен белгиленет. Андан кийин оператор break
энбелгисин көрсөтүү менен бирге каалаган циклди үзөт. Массивде эмес, матрицада терс элемент бар же жок экенин түшүнүшүбүз керек болгон мисалды карап көрөлү:
public static void main(String[] args) {
int[][] a = {
{1, 2, 3},
{-412, 12, 0},
{1223, 474, -54}
};
boolean hasNegative = false;
searchNegative:
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
if (a[i][j] < 0) {
/*
Если использовать break без метки,
тогда прервется вложенный цикл for,
но внешний продолжит выполнять свои итерации
и поиск продолжится.
Поэтому мы "помечаем" внешний цикл меткой `searchNegative`
и прерываем внешний цикл оператором break совместно с нужной меткой.
*/
hasNegative = true;
break searchNegative;
}
}
}
}
үзгүлтүксүздүк
Оператордунcontinue
эки формасы бар - энбелгиси бар жана жок:
continue; // форма оператора без метки
continue labelName; // форма оператора с меткой
break
Циклдин бардык калган итерацияларын үзгүлтүккө учураткан оператордон айырмаланып , оператор continue
учурдагы итерацияны үзгүлтүккө учуратып, кийинкисин баштоого себеп болот. Бул белгилүү бир шарттарды канааттандырган элементтер боюнча кээ бир операцияларды аткаруу керек болсо, пайдалуу болушу мүмкүн. Айталы, бизде сап бар жана биз "м" тамгасы менен башталган сөздөрдүн санын санагыбыз келет:
public static void main(String[] args) {
String sentence = "Мама мыла раму";
String[] words = sentence.split(" ");
int mWordsCount = 0;
for (int i = 0; i < words.length; i++) {
if ( ! words[i].toLowerCase().startsWith("м")) {
/*
Если слово не начинается с буквы м,
то текущая итерация прервется и цикл
ПРОДОЛЖИТ выполнение со следующей итерации
*/
continue;
}
mWordsCount ++;
}
System.out.println("Кол-во слов, начинающихся с буквы М в предложении: " + "[" + sentence + "] = " + mWordsCount);
}
Бул codeду аткаргандан кийин консолдо төмөнкүдөй жыйынтык пайда болот:
Кол-во слов, начинающихся с буквы М в предложении: [Мама мыла раму] = 2
Оператор continue
энбелгиси менен бирге элементтерди итерациялоодо да колдонулат. Келгиле, терс элементтери бар саптардын санын санашыбыз керек болгон матрицаны элестетип көрөлү:
public static void main(String[] args) {
int[][] a = {
{1, 23, -1, 23, -12},
{21, 21, 0, 23, 123, 45},
{123, 3},
{123, -5, 4, -3},
{-1, -2, -3}
};
int rowsWithNegativeElementsCount = 0;
rowsLoop:
// Проходим по каждой строке
for (int[] arr : a) {
for (int number : arr) {
if (number < 0) {
/*
Если в текущей строке найдется
хотя бы 1 отрицательный элемент,
тогда мы увеличим переменную счетчик,
и с помощью оператора continue rowsLoop
прервем текущую итерацию внешнего цикла и
принудительно начнем следующую
*/
rowsWithNegativeElementsCount ++;
continue rowsLoop;
}
}
}
System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}
Бул codeдун чыгышы болот:
Rows With Negative Elements Count = 3
Айта кетчү нерсе, операторлор break
, continue
жана return
ошол эле функцияга жетүү үчүн ар кандай жолдор менен колдонулушу мүмкүн. Ошентип, сиз акыркы мисалды кайра жазып, continue
колдоно аласыз break
:
public static void main(String[] args) {
int[][] a = {
{1, 23, -1, 23, -12},
{21, 21, 0, 23, 123, 45},
{123, 3},
{123, -5, 4, -3},
{-1, -2, -3}
};
int rowsWithNegativeElementsCount = 0;
for (int[] arr : a) {
for (int number : arr) {
if (number < 0) {
rowsWithNegativeElementsCount ++;
break;
}
}
}
System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}
Этикетканын ортосундагы айырма - бул break
жазылган циклдин кайталанышын аяктаган нерсе. Жана энбелги менен, энбелги менен белгиленген циклдин учурдагы итерациясын өткөрүп жиберет. Кээ бир учурларда, сиз бирин экинчиси менен алмаштыра аласыз жана программанын функциясында бардыгы ошол бойдон калат. Төмөндө эмнени тандаган жакшы (спойлер: codeдун окулушу) жөнүндө сүйлөшөбүз. Оператор этикетка менен гана эмес, менен да алмаштырылышы мүмкүн . Буга чейин сиз уяланган циклди өзүнчө ыкмага жылдырышыңыз керек: continue
break
continue
break
continue
return
public static void main(String[] args) {
int[][] a = {
{1, 23, -1, 23, -12},
{21, 21, 0, 23, 123, 45},
{123, 3},
{123, -5, 4, -3},
{-1, -2, -3}
};
int rowsWithNegativeElementsCount = 0;
for (int[] arr : a) {
if (arrayHasNegativeElements(arr)) {
rowsWithNegativeElementsCount ++;
}
}
System.out.println("Rows With Negative Elements Count = " + rowsWithNegativeElementsCount);
}
static boolean arrayHasNegativeElements(int[] array) {
for (int number : array) {
if (number < 0) {
return true;
}
}
return false;
}
Бир эле нерсени жазуунун көптөгөн жолдору бар. Кайсынысын тандоо керек? Өнөр жайлык программалоодо бул маселе codeду түшүнүү жеңилдиги менен чечилет. Канчалык жөнөкөй жазылса, ошончолук жакшы. Уяланган циклдер канчалык көп болсо, codeду кабыл алуу ошончолук кыйын болот. Айрыкча, эгерде циклдер үзгүлтүккө учураган жана улантууда колдонулган ар кандай энбелгилер менен белгиленген болсо ( break
жана continue
). Эгер тегдерди колдонбой коюуга мүмкүн болсо, анда муну кылган жакшы. Болбосо, мүмкүн болушунча так жана кооз жазууга аракет кылыңыз.
баруу
Кээ бир программалоо тилдеринде оператор барgoto
. Эреже катары, ал codeдун аткарылышын энбелгиси менен белгиленген программанын кайсы бир бөлүгүнө багыттайт. Бирок Javaда goto
бул бар жана андай эмес деп айтууга болот. Келгиле, аны аныктап көрөлү. Java тorндеги ачкыч сөздөрдүн тизмеси сөздү камтыйт goto
. Бирок, бул билдирүү колдонулган эмес деп белгиленген. Чындыгында, Java тorнин жаратуучусу Джеймс Гослинг алгач JVMдеги операторду колдоону камтыган goto
. Бирок, бул өзгөчөлүк кийинчерээк кесилген. Себептердин бири - операторду камтыган code блоктору goto
бирдей функцияларды аткарган code блоктору сыяктуу окула турган эмес, бирок алсыз goto
, бирок альтернативалуу ыкмалар менен ( break
, continue
, code блогун методдордо жайгаштыруу). Чынында, башкалары бар болчу, мисалы:
- операторлорду камтыган codeду окуу жана түшүнүү кыйынчылыгы
goto
; - компилятор үчүн codeду оптималдаштырууну татаалдантуу (жана кээде мүмкүн эмес);
- codeдо тымызын каталарды түзүү ыктымалдыгын жогорулатуу.
goto
Кээ бир программалоо тилдеринде оператор ийгorктүү иштегени көпчүлүк үчүн жашыруун эмес . Бирок, программисттер аны колдонуудан качышат. Мунун себептери жөнүндө Хабредеги бир макаладан окуй аласыз . Бирок эмне үчүн аны goto
сакталган сөздөрдүн тизмесине калтыруу керек? Бул жөнөкөй: келечек үчүн. Эгерде, мисалы, өзгөрмөлөр, методдор же класстар бүткүл дүйнө боюнча иштеп чыгуучулардын Java codeунда деп аталса, goto
бул билдирүү Javaнын келечектеги versionсында кайтарылса, бардык эски code бузулат. Мындай сценарийди болтурбоо үчүн, goto
ал Java ачкыч сөздөрдүн тизмесинде калат, бирок эч кандай функцияны аткарbyte. Балким, качандыр бир күнү goto
ал биздин катарыбызга кайтып келет, бирок мунун ыктымалдыгы аз.
Жыйынтыктар
Биз Javaдагы ар кандай секирүү операторлорун карадык:return
— методду аяктоо, методдон маанини кайтаруу.- кайтаруу мааниси менен: баалуулуктарды кайтаруучу ыкмалар;
- эч кандай кайтаруу мааниси:
void
ыкмалары.
break
— циклдердин, коммутатор-каптардын блокторун узгултукке учуратуу.- теги менен: ар кандай уя салуу циклдери;
- этикеткасыз: блоктун коммутатор-кассалык бутактары; деп аталган циклди үзгүлтүккө учуратып.
continue
.- теги менен: ар кандай уя салуу циклдери;
- этикеткаларсыз: ал чакырылган циклдин уландысы.
goto
.- ачкыч сөздөрдүн тизмесинде бар, бирок колдонулbyte.
GO TO FULL VERSION