JavaRush /Java блогу /Random-KY /Javaдагы секирүү операторлору

Javaдагы секирүү операторлору

Группада жарыяланган
Салам! Бүгүн биз Javaдагы секирүү операторлору жөнүндө сүйлөшөбүз:
  • return
  • break
  • continue
  • goto
Биринчиден, анын чындыгында эмне экенин аныктап алалы. Белгилүү болгондой, нормалдуу кырдаалда программа сызыктуу түрдө – жогорудан ылдыйга чейин, команда аркылуу аткарылат. Программанын сызыктуу агымын башкаруу структуралары деп аталгандар менен өзгөртүүгө болот: мисалы, бутактар ​​( if) жана циклдер ( for, whileж.б.). Башкаруу структураларынан тышкары, программанын сызыктуу аткарылышын секирүү операторлору менен өзгөртүүгө болот. Алар контекстке жана конкреттүү билдирүүгө жараша программанын аткарылышын белгилүү бир жерге багыттоо үчүн жооптуу. Javaдагы секирүү операторлору - 1Келгиле, төрт оператордун ар бирин кененирээк карап чыгалы.

кайтуу

Дал ушул оператор менен жаңы келгендер көбүнчө биринчи таанышат. Билдирме returnал чакырылган ыкманы токтотот жана программанын аткарылышы ыкма чакырылган жерге кайтып келет. Анын returnэки формасы бар:
  1. Методдун аткарылышын дароо аяктайт.
  2. Методдун аткарылышын дароо аяктайт жана методдун натыйжасы катары кандайдыр бир маанини кайтарат.
Эки форманын синтаксиси:
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:
Жана Java codeунун ичинде энбелгилер кандай көрүнөт:
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эки учурда колдонулат:
  1. Которушчу-кап блогунда кандайдыр бир аткаруу бутагын аяктоо үчүн.
  2. Циклдин аткарылышын үзгүлтүккө учуратууга.
Оператор эки формага ээ: маркировка менен (этикетка) жана жок. Эки форманын синтаксиси:
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учурдагы итерацияны үзгүлтүккө учуратып, кийинкисин баштоого себеп болот. Javaдагы секирүү операторлору - 2Бул белгилүү бир шарттарды канааттандырган элементтер боюнча кээ бир операцияларды аткаруу керек болсо, пайдалуу болушу мүмкүн. Айталы, бизде сап бар жана биз "м" тамгасы менен башталган сөздөрдүн санын санагыбыз келет:
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дун окулушу) жөнүндө сүйлөшөбүз. Оператор этикетка менен гана эмес, менен да алмаштырылышы мүмкүн . Буга чейин сиз уяланган циклди өзүнчө ыкмага жылдырышыңыз керек: continuebreakcontinuebreakcontinuereturn
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дагы ар кандай секирүү операторлорун карадык:
  1. return— методду аяктоо, методдон маанини кайтаруу.
    • кайтаруу мааниси менен: баалуулуктарды кайтаруучу ыкмалар;
    • эч кандай кайтаруу мааниси: voidыкмалары.
  2. break— циклдердин, коммутатор-каптардын блокторун узгултукке учуратуу.
    • теги менен: ар кандай уя салуу циклдери;
    • этикеткасыз: блоктун коммутатор-кассалык бутактары; деп аталган циклди үзгүлтүккө учуратып.
  3. continue.
    • теги менен: ар кандай уя салуу циклдери;
    • этикеткаларсыз: ал чакырылган циклдин уландысы.
  4. goto.
    • ачкыч сөздөрдүн тизмесинде бар, бирок колдонулbyte.
Мунун бардыгынан тыянак жөнөкөй: codeду окууну жеңилдеткен эң жөнөкөй ыкмаларга артыкчылык берүү жакшы. Кодуңузду көптөгөн белгилер, үзгүлтүктөр жана улантуулар менен бири-биринин ичине салынган көп деңгээлдүү циклдер менен ашыкча жүктөгөнгө аракет кылыңыз.
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION