Операторы c список: Операторы языка Си — it-black.ru

Встроенные операторы C++, приоритет и ассоциативность

Twitter LinkedIn Facebook Адрес электронной почты

  • Статья

Язык C++ включает все операторы C и еще несколько новых операторов. Операторы определяют, какое вычисление следует выполнить с одним или несколькими операндами.

Очередность и ассоциативность

Приоритет операторов определяет порядок операций в выражениях, содержащих несколько операторов. Ассоциативность операторов указывает, сгруппирован ли операнд в выражении, которое содержит несколько операторов с одинаковым приоритетом, с операндом слева или с правым.

Альтернативные орфографии

C++ задает альтернативные варианты написания для некоторых операторов. В C альтернативные варианты написания предоставляются в виде макросов в заголовке <iso646.h> . В C++ эти альтернативы являются ключевыми словами, и использование <iso646.h> или эквивалента <C++ ciso646> не рекомендуется. В Microsoft C++ для включения альтернативных /permissive- орфографических орфографических ошибок требуется параметр компилятора или /Za .

Таблица приоритета и ассоциативности операторов C++

В следующей таблице показан приоритет и ассоциативность операторов C++ (в порядке убывания приоритета). Операторы с тем же номером приоритета имеют равный приоритет, если другие связи не заданы явно с помощью круглых скобок.

Описание оператораОператорАльтернатива
Приоритет группы 1, без ассоциативности
Разрешение области::
Приоритет группы 2, ассоциативность слева направо
Выбор члена для указателей (объект или указатель). или
->
Индекс массива[]
Вызов функции()
Постфиксный инкремент++
Постфиксный декремент--
Имя типаtypeid
Постоянное преобразование типаconst_cast
Динамическое преобразование типаdynamic_cast
Повторно интерпретируемое преобразование типаreinterpret_cast
Статическое преобразование типаstatic_cast
Приоритет группы 3, ассоциативность справа налево
Размер объекта или типаsizeof
Префиксный инкремент++
Префиксный декремент--
Дополнение к одному~compl
Логическое не!not
Унарное отрицание-
Унарный плюс+
Взятие адреса&
Косвенное обращение*
Создание объектаnew
Уничтожение объектаdelete
Cast()
Приоритет группы 4, ассоциативность слева направо
Указатель на член (объекты или указатели). *
или ->*
Приоритет группы 5, ассоциативность слева направо
Умножение*
Отдел/
Модуль%
Приоритет группы 6, ассоциативность слева направо
Сложение+
Вычитание-
Приоритет группы 7, ассоциативность слева направо
Сдвиг влево<<
Сдвиг вправо>>
Приоритет группы 8, ассоциативность слева направо
Меньше чем<
Больше чем>
Меньше или равно<=
Больше или равно>=
Приоритет группы 9, ассоциативность слева направо
Равенство==
Неравенство!=not_eq
Приоритет ассоциативности слева направо в группе 10
Побитовое И&bitand
Приоритет группы 11, ассоциативность слева направо
Побитовое исключающее ИЛИ^xor
Приоритет группы 12, ассоциативность слева направо
Побитовое ИЛИ|bitor
Приоритет группы 13, ассоциативность слева направо
Логическое И&&and
Приоритет группы 14, ассоциативность слева направо
Логическое ИЛИ||or
Приоритет группы 15, ассоциативность справа налево
Условная логика? :
Передача прав и обязанностей=
Присваивание умножения*=
Присваивание деления/=
Назначение модуля%=
Присваивание сложения+=
Присваивание вычитания-=
Присваивание сдвига влево<<=
Присваивание сдвига вправо>>=
Назначение побитового И&=and_eq
Назначение побитового включающего ИЛИ|=or_eq
Назначение побитового исключающего ИЛИ^=xor_eq
Выражение Throwthrow
Приоритет группы 16, ассоциативность слева направо
Запятая,

См.

также раздел

Перегрузка операторов

Языки программирования C и C++

Языки программирования C и C++
  1. Занятие 1
    • История языков программирования C и C++
    • Преимущества языка C
    • Hello, world!
    • Компиляция программы на языке C
    • Переменные в C
    • Базовый ввод-вывод в C
  2. Занятие 2
    • Среда разработки Code::Blocks
    • Целочисленные типы данных в языке С
    • Действительные типы данных в языке C
    • Арифметические операции в С
    • Операторы +=, -=, *= и /= в C
  3. Занятие 3
    • Условная инструкция if
    • Операции сравнения чисел
    • Логические операции
    • Инструкция цикла while
  4. Занятие 4
    • Инструкция цикла for
    • Операторы +=, -=, *= и /=
    • Массивы в С
    • Определение и инициализация массива в С
    • Многомерные массивы в С
  5. Занятие 5
    • Строки в языке C
  6. Занятие 6.
    • Функция printf
    • Функция scanf
  7. Занятие 7.
    • Файловый ввод-вывод
  8. Занятие 8.
    • Указатели
    • Адресная арифметика
    • Тип void*
    • Системные вызовы malloc и free
    • Работа с динамической памятью
    • Динамические двумерные массивы
  9. Занятие 9.
    • Функции
    • Возврат значения из функции
    • Функции с параметрами
    • Передача массива в функцию и возврат из функции
    • Передача параметров по указателю
    • Стек вызовов
  10. Занятие 10.
    • Компиляторы и среды разработки
    • Прототипы функций
    • Модульное программирование
    • Принцип раздельной компиляции
    • Этапы компиляции
    • Макросы препроцессора
    • Стражи включения заголовочных файлов
  11. Занятие 11.
    • Рекурсия
  12. Занятие 12.
    • Представление целых чисел
  13. Занятие 13.
    • Представление действительных чисел
    • Математическая библиотека math.h
  14. Занятие 14.
    • Отличия языков программирования C и C++
    • Логический тип в C++
    • Ссылки в C++
  15. Занятие 15.
    • Вывод в языке C++ через cout
    • Ввод в языке C++ через cin
    • Файловый ввод-вывод в C++
    • Перенаправление ввода-вывода консольных приложений
  16. Занятие 16.
    • Строки в языке C++ (класс string)
    • Строковые потоки stringstream
  17. Занятие 17.
    • Понятие класса
    • Инкапсуляция. Спецификаторы доступа к полям классов
    • Конструкторы и деструкторы
    • Указатель на объект
    • Перегрузка функций
    • Разработка класса date
  18. Занятие 18.
    • Перегрузка операторов
    • Перегрузка операторов ввода-вывода
    • Разработка класса date — перегрузка операторов
  19. Занятие 19.
    • Операторы new и delete
    • Статические поля и методы
    • Реализация двоичного дерева поиска
  20. Занятие 20.
    • Обобщённое программирование
    • Шаблоны функций
    • Шаблоны классов
    • Параметры шаблонов
    • Реализация шаблона класса “Динамический массив”
  21. Занятие 22.
    • Понятие контейнера и итератора
    • Контейнер vector
    • Контейнер stack
    • Контейнер queue
    • Контейнер deque
  22. Занятие 23.
    • Контейнер list (двусвязный список)
    • Контейнер set (множество)
    • Контейнер multiset
    • Контейнер map (ассоциативный массив, словарь)
    • Контейнер multimap
  23. Занятие 24.
    • Алгоритмы стандартной библиотеки C++
    • Использование стандартной сортировки
  24. Занятие 25.
    • Стандарты языка C++

C Приоритет и ассоциативность операторов: определение и примеры

В этом руководстве вы узнаете о приоритете и ассоциативности операторов с помощью примеров.

Приоритет операторов

Приоритет операторов определяет, какой оператор выполняется первым, если в выражении более одного оператора.

Рассмотрим пример:

 int x = 5 - 17* 6; 

В C приоритет * выше, чем - и = . Следовательно, 17 * 6 оценивается первым. Затем вычисляется выражение, включающее -, так как приоритет - выше, чем у = .

Вот таблица приоритета операторов от высшего к низшему. Вскоре мы обсудим свойство ассоциативности .


Таблица приоритета и ассоциативности операторов

9
Оператор Значение оператора Ассоциативность
()
[]
->
.
Функциональный вызов
Ссылка на элемент массива
Косвенный выбор элемента
Прямой выбор элемента
Слева направо
!
~
+

++

и
*
размер
(тип)
Логическое отрицание
Побитовое (1) дополнение
Унарный плюс
Унарный минус
Приращение
Декремент
Разыменование (адрес)
Ссылка на указатель
Возвращает размер объекта
Приведение типов (преобразование)
Справа налево
*
/
%
Умножить
Разделить
Остаток
Слева направо
+
Двоичный плюс (сложение)
Двоичный минус (вычитание)
Слева направо
<<
>>
Сдвиг влево
Сдвиг вправо
Слева направо Побитовое исключающее ИЛИ Слева направо
| Побитовое ИЛИ Слева направо
&& Логическое И Слева направо
|| Логическое ИЛИ Слева направо
?: Условный оператор Справа налево
=
*=
/=
%=
+=
-=
&= 9=
|=
<<=
>>=
Простое присваивание
Присвоить произведение
Присвоить частное
Присвоить остаток
Присвоить сумму
Присвоить разность
Присвоить побитовое И
Присвоить побитовое XOR
Присвоить побитовое ИЛИ
Присвоить сдвиг влево
Присвоить сдвиг вправо
Справа налево
, Разделитель выражений Слева направо

Ассоциативность операторов

Ассоциативность операторов определяет направление, в котором оценивается выражение.

Например,

 б = а; 

Здесь значение a присваивается b , а не наоборот. Это потому, что оператор = ассоциативен справа налево.

Кроме того, если присутствуют два оператора с одинаковым старшинством (приоритетом), ассоциативность определяет направление их выполнения.

Рассмотрим пример:

1 == 2 != 3 

Здесь операторы == и != имеют одинаковый приоритет. И их ассоциативность слева направо. Следовательно, 1 == 2 выполняется первым.

Приведенное выше выражение эквивалентно:

(1 == 2) != 3 

Примечание: Если оператор содержит несколько операторов, вы можете использовать круглые скобки () , чтобы сделать код более читабельным.

Содержание

Операторы

8.1. Оператор Spread

Оператор Spread-dot ( *. ), часто сокращенно просто Оператор Spread, используется для вызова действия над всеми элементами агрегатного объекта. Это эквивалентно вызову действия над каждым элементом и сбору результата в список:

 класс Автомобиль {
    Строка сделать
    Струнная модель
}
деф автомобили = [
       новый автомобиль(марка: "Пежо", модель: "508"),
       новый автомобиль(марка: 'Renault', модель: 'Clio')]   (1) 
def makes = автомобили*.make   (2) 
assert makes == ['Peugeot', 'Renault']   (3)  
1 построить список из автомобилей элементов. Список представляет собой совокупность объектов.
2 вызвать оператора спреда из списка, обратившись к свойству
make
каждого элемента
3 возвращает список строк, соответствующих набору из make элементов

Выражение cars*. make эквивалентно cars.collect{ it.make } . Нотация Groovy GPath позволяет сократить путь, когда указанное свойство не является свойством содержащего списка, в этом случае он автоматически распространение. В ранее упомянутом случае выражение автомобили.марка может можно использовать, хотя часто рекомендуется сохранять явный оператор с расставленными точками.

Оператор распространения является нулевым, что означает, что если элемент коллекции имеет значение null, он вернет null вместо того, чтобы выдать

NullPointerException :

 cars = [
   новый автомобиль(марка: "Пежо", модель: "508"),
   ноль,   (1) 
   новый автомобиль(марка: 'Renault', модель: 'Clio')]
assert cars*.make == ['Peugeot', null, 'Renault']   (2) 
утверждать null*.make == null   (3)  
1 построить список, для которого один из элементов нулевой
2 с использованием оператора распространения вызовет , а не исключение NullPointerException
3 получатель также может быть нулевым, и в этом случае возвращаемое значение равно ноль

Оператор распространения можно использовать в любом классе, реализующем интерфейс Iterable :

 class Component {
    Целочисленный идентификатор
    Имя строки
}
класс CompositeObject реализует Iterable {
    Компоненты защиты = [
        новый компонент (id: 1, имя: «Foo»),
        новый компонент (id: 2, имя: «Бар»)]

    @Override
    Итератор<Компонент> итератор() {
        компоненты. iterator()
    }
}
def составной = новый составной объект ()
утверждать составной*.id == [1,2]
утверждать составное*.имя == ['Foo','Bar'] 

Использовать несколько вызовов оператора растровой точки (здесь cars*.models*.name ), когда работа с агрегатами структур данных, которые сами содержат агрегаты:

 class Make {
    Имя строки
    Список моделей
}

@канонический
модель класса {
    Имя строки
}

деф автомобили = [
    новая марка (название: «Пежо»,
             модели: [новая модель('408'), новая модель('508')]),
    новый Марка (название: «Рено»,
             модели: [новая модель('Clio'), новая модель('Captur')])
]

def makes = автомобили*.название
assert делает == ['Peugeot', 'Renault']

def модели = автомобили*.модели*.название
утверждать модели == [['408', '508'], ['Clio', 'Captur']]
assert models.sum() == ['408', '508', 'Clio', 'Captur'] // выравнивание на один уровень
assert models.flatten() == ['408', '508', 'Clio', 'Captur'] // выравниваем все уровни (в данном случае один) 

Рассмотрите возможность использования метода collectNested DGM вместо оператора с расставленными точками для коллекций коллекций:

 class Car {
    Строка сделать
    Струнная модель
}
деф автомобили = [
   [
       новый автомобиль(марка: 'Peugeot', модель: '408'),
       новый автомобиль(марка: 'Peugeot', модель: '508')
   ], [
       новый автомобиль(марка: 'Renault', модель: 'Clio'),
       новый автомобиль(марка: 'Renault', модель: 'Captur')
   ]
]
def models = cars. collectNested{ it.model }
утверждать модели == [['408', '508'], ['Clio', 'Captur']] 
8.1.1. Распространение аргументов метода

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

 int function (int x, int y, int z) {
    х*у+г
} 

тогда, если у вас есть следующий список:

 def args = [4,5,6] 

вы можете вызвать метод без определения промежуточных переменных:

 assert function(*args) == 26 

Можно даже смешивать обычные аргументы с расширенными:

 args = [4]
функция утверждения(*args,5,6) == 26 
8.1.2. Элементы списка распространения

При использовании внутри литерала списка оператор расширения действует так, как если бы содержимое элемента расширения было встроено в список:

 def items = [4,5]   (1) 
список по умолчанию = [1,2,3,*элементы,6]   (2) 
список утверждений == [1,2,3,4,5,6]   (3)  
1 элементов список
2 мы хотим вставить содержимое списка элементов непосредственно в список без вызова addAll
3 содержимое элементов было встроено в список
8.
1.3. Элементы карты распространения

Оператор карты распространения работает аналогично оператору списка распространения, но для карт. Это позволяет вам встроить содержимое карты в другой литерал карты, как в следующем примере:

 def m1 = [c:3, d:4]   (1) 
карта защиты = [a:1, b:2, *:m1]   (2) 
assert map == [a:1, b:2, c:3, d:4]   (3)  
1 m1 — это карта, которую мы хотим встроить
2 мы используем нотацию *:m1 для распространения содержимого m1 на карту
3 карта содержит все элементы m1

Должность оператора карты спреда имеет значение, как показано в следующем примере:

 по умолчанию m1 = [c:3, d:4]   (1) 
карта защиты = [a:1, b:2, *:m1, d: 8]   (2) 
assert map == [a:1, b:2, c:3, d:8]   (3)  
1 m1 — это карта, которую мы хотим встроить
2 мы используем нотацию *:m1 для распространения содержимого m1 на карту , но переопределить ключ d после распространяя
3 карта содержит все ожидаемые ключи, но d был переопределен

8.

2. Оператор диапазона

Groovy поддерживает концепцию диапазонов и предоставляет нотацию ( .. ) для создания диапазонов объектов:

 def range = 0..5   (1) 
утверждать (0..5).collect() == [0, 1, 2, 3, 4, 5]   (2) 
утверждать (0..<5).collect() == [0, 1, 2, 3, 4]   (3) 
утверждать (0<..5).collect() == [1, 2, 3, 4, 5]   (4) 
утверждать (0<..<5).collect() == [1, 2, 3, 4]   (5) 
assert (0..5) instanceof List   (6) 
утверждать (0..5).size() == 6   (7)  
1 простой диапазон целых чисел, сохраненный в локальной переменной
2 и IntRange с включенными границами
3 и IntRange с исключительной верхней границей
4 и IntRange с эксклюзивной нижней границей
5 и IntRange с исключительными нижними и верхними границами
6 a groovy. lang.Range реализует интерфейс List
7 означает, что вы можете вызвать на нем метод размера

Реализация диапазонов упрощена, т. е. сохраняются только нижняя и верхняя границы. Вы можете создать диапазон из любых Сопоставимый объект, который имеет методы next() и previous() для определения следующего/предыдущего элемента в диапазоне. Например, вы можете создать диапазон символов следующим образом:

 assert('a'..'d').collect() == ['a','b','c','d'] 

8.3. Оператор космического корабля

Оператор космического корабля ( <=> ) делегирует метод compareTo :

 assert (1 <=> 1) == 0
утверждать (1 <=> 2) == -1
утверждать (2 <=> 1) == 1
утверждать ('a' <=> 'z') == -1 

8.4. Оператор нижнего индекса

Оператор нижнего индекса представляет собой сокращенную запись для getAt или putAt , в зависимости от того, найдете ли вы его на левая или правая часть задания:

 def list = [0,1,2,3,4]
утвердить список [2] == 2   (1) 
список[2] = 4   (2) 
утвердить список [0. .2] == [0,1,4]   (3) 
список[0..2] = [6,6,6]   (4) 
список утверждений == [6,6,6,3,4]   (5)  
1 [2] можно использовать вместо getAt(2)
2 , если слева от задания, вызовет putAt
3 getAt также поддерживает диапазоны
4 так же как и putAt
5 список изменен

Оператор нижнего индекса в сочетании с пользовательской реализацией getAt / putAt является удобным способом деструктурирования объекты:

 класс Пользователь {
    Длинный идентификатор
    Имя строки
    защита getAt(int i) {   (1) 
        переключатель (я) {
            случай 0: возвращаемый идентификатор
            случай 1: вернуть имя
        }
        выбросить новое исключение IllegalArgumentException("Нет такого элемента $i")
    }
    void putAt (int i, значение по умолчанию) {   (2) 
        переключатель (я) {
            случай 0: идентификатор = значение; возвращаться
            случай 1: имя = значение; возвращаться
        }
        выбросить новое исключение IllegalArgumentException("Нет такого элемента $i")
    }
}
def user = новый пользователь (id: 1, имя: «Алекс»)   (3) 
утверждать пользователя [0] == 1   (4) 
утвердить пользователя [1] == 'Алекс'   (5) 
пользователь [1] = 'Боб'   (6) 
утверждать user. name == 'Боб'   (7)  
1 класс User определяет пользовательский getAt реализация
2 класс User определяет пользовательскую реализацию putAt
3 создать образец пользователя
4 с помощью оператора индекса с индексом 0 позволяет получить идентификатор пользователя
5 с помощью оператора нижнего индекса с индексом 1 позволяет получить имя пользователя
6 мы можем использовать оператор нижнего индекса для записи в свойство благодаря делегированию putAt
7 и проверьте, действительно ли свойство имя было изменено

8.

5. Оператор безопасного индексирования

Groovy 3.0.0 представляет оператор безопасного индексирования, т. е. ?[] , что аналогично ?. . Например:

 Строка[] массив = ['a', 'b']
assert 'b' == array?[1] // получаем с использованием индекса обычного массива
array?[1] = 'c' // устанавливаем с использованием индекса обычного массива
утверждать 'c' == массив?[1]

массив = ноль
assert null == array?[1] // возвращаем null для всех значений индекса
array?[1] = 'c' // тихо игнорируем попытку установить значение
утверждать массив null ==?[1]

def personInfo = [имя: 'Daniel.Sun', местоположение: 'Шанхай']
assert 'Daniel.Sun' == personInfo?['name'] // используем индекс карты нормалей
personInfo?['name'] = 'sunlan' // устанавливается с использованием индекса карты нормалей
утверждать 'sunlan' == personInfo?['name']

информация о человеке = ноль
assert null == personInfo?['name'] // возвращаем null для всех значений карты
personInfo?['name'] = 'sunlan' // незаметно игнорируем попытку установить значение
утверждать null == personInfo?['name'] 

8.

6. Оператор принадлежности

Оператор принадлежности ( в ) эквивалентен вызову метода isCase . В контексте списка это эквивалентно для вызова содержится , как в следующем примере:

 def list = ['Grace','Rob','Emmy']
утверждать («Эмми» в списке)   (1) 
утверждать ('Алекс'! в списке)   (2)  
1 эквивалентно вызову list.contains('Эмми') или list.isCase('Эмми')
2 отрицание членства эквивалентно вызову !list.contains('Emmy') или !list.isCase('Emmy')

8.7. Оператор идентификации

В Groovy использование == для проверки равенства отличается от использования того же оператора в Java. В Groovy это вызов равно . Если вы хотите сравнить ссылочное равенство, вы должны использовать равно , как в следующем примере:

 def list1 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3']   (1) 
def list2 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3']   (2) 
утверждать список1 == список2   (3) 
утверждать !list1.is(list2)   (4) 
утверждать список1 !== список2   (5)  
..
1 Создать список строк
2 Создайте еще один список строк, содержащих те же элементы
3 , используя == , мы проверяем равенство объектов, что эквивалентно list1.equals(list2) в Java
4 с использованием равно , мы можем проверить, что ссылки различны, что эквивалентно list1 == list2 в Java
5 , используя === или !== (поддерживается и рекомендуется, начиная с Groovy 3.0.0), мы также можем проверить, являются ли ссылки различными или нет, что эквивалентно list1 == list2 и list1 != list2 на Яве

8.8. Оператор приведения

Оператор приведения ( как ) — вариант литья. Приведение преобразует объект из одного типа в другой без их быть совместимым для назначения. Возьмем пример:

 Целое число x = 123
Строка s = (Строка) x   (1)  
1 Целое число не может быть присвоено String , поэтому оно создаст ClassCastException во время выполнения

Это можно исправить, используя вместо этого приведение :

 Целое число x = 123
Строка s = x as Строка   (1)  
1 Целое число не может быть присвоено строке , но использование в качестве приведет к принудительному преобразованию в строку

Когда объект принудительно преобразуется в другой, если целевой тип не совпадает с исходным типом, приведение возвращает новый объект . Правила приведения различаются в зависимости от исходного и целевого типов, и приведение может завершиться ошибкой, если не выполняется преобразование. правила найдены. Пользовательские правила преобразования могут быть реализованы благодаря методу asType :

 класс Идентифицируемый {
    Имя строки
}
класс Пользователь {
    Длинный идентификатор
    Имя строки
    def asType (Цель класса) {   (1) 
        если (цель == Идентифицируемый) {
            вернуть новый идентифицируемый (имя: имя)
        }
        выбросить новое исключение ClassCastException («Пользователь не может быть принужден к $ target»)
    }
}
def u = новый пользователь (имя: «Ксавье»)   (2) 
def p = u как идентифицируемый   (3) 
утверждать p instanceof Идентифицируемый   (4) 
assert !(p instanceof User)   (5)  
1 класс User определяет пользовательское правило преобразования с User на Идентифицируемый
2 мы создаем экземпляр пользователя
3 мы принуждаем экземпляр пользователя к идентифицируемому
4 цель является экземпляром Идентифицируемый
5 цель не является экземпляром Пользователь Больше

8.

9. Алмазный оператор

Алмазный оператор ( <> ) является синтаксическим сахарным оператором, добавленным для поддержки совместимости с оператором то же имя в Java 7. Оно используется для указания того, что универсальные типы должны выводиться из объявления:

 List strings = new LinkedList<>() 

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

8.10. Оператор вызова

Оператор вызова () используется для неявного вызова метода с именем call . Для любого объекта, который определяет метод вызова , вы можете опустить часть .call и вместо этого использовать оператор вызова:

 class MyCallable {
 внутренний вызов (int x) {   (1)  2*х
 }
}  def mc = новый MyCallable()
утверждать mc.
Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *