You are on page 1of 6

Unary + and - Operators

The unary - and-operators operate on a single operand of arithmetic type. The-operator


returns the negative of its operand (that is, it behaves as though the operand were
multiplied by -1). The unary + operator just returns the value. These operators exist
primarily to express positive and negative numbers.
If the operand has a small integer type, it is promoted (see Chapter 3), and the result of
the operation has the result of the promoted type. As a point of trivia, C has no negative
integer constants; a value such as-25 is actually an rvalue of type int with the value 25
preceded by the unary-operator.

Logical Negation Operator 


The result of the unary logical negation operator is as follows:
● 0 if the value of its operand is not 0 
● 1 if the value of its operand is 0
The operand is a scalar type. The result has type int for historical reasons. The expression
E is equivalent to (0 == E). The logical negation operator is frequently used to check for
null pointers; for example, !p is equivalent to (NULL == p).

Multiplicative Operators
The binary multiplicative operators include multiplication (*), division (/), and remainder
(%). The usual arithmetic conversions are implicitly performed on multiplicative
operands to find a common type. You can multiply and divide both floating-point and
integer operands, but remainder operates on only integer operands.
Various programming languages implement different kinds of integer division operations,
including Euclidean, flooring, and truncating. In Euclidean division, the remainder is
always nonnegative (Boute 1992). In flooring division, the quotient is rounded toward
negative infinity (Knuth 1997). In truncating division, the result of the / operator is the
algebraic quotient with any fractional part discarded. This is often referred to as
truncation toward zero.
The programming language implements truncating division, meaning that the remainder
always has the saine sign as the dividend, as shown in Table 4-2.
Table 4-2: Truncating Division
Toán tử một ngôi + và -
Toán tử một ngôi + và - hoạt động trên một toán hạng đơn của kiểu số học. Toán tử trả về
giá trị âm của toán hạng của nó (nghĩa là nó hoạt động như thể toán hạng được nhân với -
1). Toán tử một ngôi + chỉ trả về giá trị. Các toán tử này tồn tại chủ yếu để biểu thị số
dương và số âm.
Nếu toán hạng có kiểu số nguyên nhỏ, nó sẽ được tăng cấp (xem chương 3), và kết quả
của phép toán có kết quả của kiểu được tăng cấp. Là một điểm của câu đố, C không có
hằng số nguyên âm; một giá trị chẳng hạn như -25 thực sự là một giá trị của kiểu int với
giá trị 25 đứng trước toán tử một ngôi.

Toán tử phủ định logic


Kết quả của toán tử phủ định logic một ngôi (!) như sau:
● 0 nếu giá trị của toán hạng của nó không phải là 0
● 1 nếu giá trị của toán hạng của nó là 0
Toán hạng là một loại vô hướng. Kết quả có kiểu int vì lý do lịch sử. Biểu thức !E tương
đương với (0 == E). Toán tử phủ định logic thường được sử dụng để kiểm tra các con trỏ
null; ví dụ, !p tương đương với (NULL == p).

Toán tử đa nhân
Các toán tử nhân nhị phân bao gồm nhân (*), chia (/) và phần dư (%). Các chuyển đổi
số học thông thường được thực hiện ngầm định trên các toán hạng nhân để tìm một
kiểu chung. Bạn có thể nhân và chia cả toán hạng dấu phẩy động và số nguyên, nhưng
phần dư chỉ hoạt động trên các toán hạng số nguyên.
Các ngôn ngữ lập trình khác nhau thực hiện các loại phép toán chia số nguyên khác
nhau, bao gồm Euclidean, lát sàn và cắt ngắn. Trong phép chia Euclide, phần dư luôn
không âm (Boute 1992). Trong phép chia ván sàn, thương số được làm tròn về phía âm
vô cực (Knuth 1997). Trong phép chia cắt ngắn, kết quả của toán tử / là thương số đại
số với bất kỳ phần phân số nào bị loại bỏ. Điều này thường được gọi là cắt ngắn về 0.
Ngôn ngữ lập trình C thực hiện phép chia cắt ngắn truncating division, có nghĩa là
phần dư luôn có cùng dấu với số bị chia, như thể hiện trong Bảng 4-2.
Bảng 4-2: Phép chia cắt ngắn
Many CPUs implement remainder as part of the division operator, which can overflow if
the dividend is equal to the minimum negative value for the signed integer type and the
divisor is equal to -1. This occurs even though the mathematical result of such a
remainder operation is 0.
The C Standard Library provides floating-point remainder, truncation, and rounding
functions, including fmod.

Additive Operators
The binary additive operators include addition (+) and subtraction (-). Addition and
subtraction can be applied to two operands of arithmetic types, but you can also use them
to perform scaled pointer arithmetic. I'll discuss pointer arithmetic near the end of this
chapter; the discussion here is limited to operations on arithmetic types.
The binary + operator sunis its two operands. The binary - operator subtracts the right
operand from the left operand. The usual arithmetic conversions are performed on
operands of arithmetic type for both operations.

Bitwise Operators
We use bitwise operators to manipulate the bits of an object or any integer expression.
Typically, they're used on objects that represent bitmaps: each bit indicates that
something is "on" or "off," "enabled" or "disabled," or another binary pairing.
Bitwise (| & ^ ~) operators treat the bits as a pure binary model without concern for the
values represented by these bits:

1 1 0 1 = 13
^0110=6
= 1 0 1 1 = 11

Bitmaps are best represented as unsigned integer types, as the sign bit can be better used
as a value within the bitmap, and operations on the values are less prone to undefined
behavior.
Nhiều CPU thực hiện phần dư như một phần của toán tử chia, có thể tràn nếu số bị chia
bằng giá trị âm tối thiểu cho kiểu số nguyên có dấu và số chia bằng -1. Điều này xảy ra
ngay cả khi kết quả toán học của một phép toán phần dư là 0.
Thư viện tiêu chuẩn C cung cấp các phần dư dấu phẩy động, cắt ngắn truncation và hàm
làm tròn rounding functions, bao gồm cả fmod.

Toán tử cộng
Các toán tử cộng nhị phân bao gồm phép cộng (+) và phép trừ (-). Phép cộng và phép trừ
có thể được áp dụng cho hai toán hạng của kiểu số học, nhưng bạn cũng có thể sử dụng
chúng để thực hiện số học con trỏ theo tỷ lệ. Tôi sẽ thảo luận về số học con trỏ ở gần cuối
chương này; cuộc thảo luận ở đây chỉ giới hạn trong các phép toán trên các kiểu số học.
Toán tử nhị phân + tổng hợp hai toán hạng của nó. Toán tử nhị phân trừ - toán hạng bên
phải khỏi toán hạng bên trái. Các chuyển đổi số học thông thường được thực hiện trên
các toán hạng của kiểu số học cho cả hai phép toán.

Toán tử Bitwise
Chúng tôi sử dụng các toán tử bitwise để thao tác các bit của một đối tượng hoặc bất kỳ
biểu thức số nguyên nào. Thông thường, chúng được sử dụng trên các đối tượng đại diện
cho bitmap: mỗi bit chỉ ra rằng một cái gì đó đang "bật" hoặc "tắt", "đã bật" hoặc "bị vô
hiệu hóa" hoặc một cặp nhị phân khác.
Toán tử bitwise (| & ^ ~) coi các bit như một mô hình nhị phân thuần túy mà không quan
tâm đến các giá trị được biểu diễn bởi các bit này:

1 1 0 1 = 13
^0110=6
= 1 0 1 1 = 11

Bitmap được biểu thị tốt nhất dưới dạng số nguyên không dấu, vì bit dấu có thể được sử
dụng tốt hơn như một giá trị trong bitmap và các thao tác trên giá trị ít bị dẫn đến hành vi
không xác định hơn.
Complement Operator 
The unary complement (-) operator works on a single operand of integer type and returns
the bitwise complement of its operand; that is, a value in which each bit of the original
value is flipped. The complement operator is used in applying the POSIX umask, for
example. A file's permission mode is the result of a logical AND operation between the
complement of the mask and the process's requested permission mode setting. Integer
promotions are performed on the operand, and the result has the promoted type. For
example, the following code snippet applies the operator to a value of type unsigned char:

unsigned char uc = UCHAR_MAX; // 0xFF


int i = ~uc;

On an architecture with an 8-bit char type and 32-bit int type, uc is assigned the value
OxFF. When uc is used as the operand to the operator, uc is promoted to signed int by
zero-extending it to 32 bits, Ox000000FF. The complement of this value is 0xFFFFFF00.
Therefore, on this platform, complementing an unsigned short type always results in a
negative value of type signed int. As a general policy and to avoid surprises such as this,
all bitwise manipulations should involve a single, sufficiently wide unsigned integer type.

Shift Operators 
Shift operations shift the value of each bit of an operand of integer type by a specified
number of positions. Shifting is commonly performed in system programıning, where bit
masks are common. They may also be used in code that manages network protocols or
file formats to pack or unpack data. They include left-shift operations, of the form:

shift-expression << additive-expression

and right-shift operations, of the form:

Toán tử bổ sung
Toán tử bổ sung một ngôi ~ hoạt động trên một toán hạng đơn của kiểu số nguyên và trả
về phần bổ sung bitwise của toán hạng của nó; nghĩa là, một giá trị trong đó mỗi bit của
giá trị ban đầu được đảo hướng. Ví dụ: toán tử bổ sung được sử dụng trong việc áp dụng
umask POSIX. Chế độ quyền của tệp là kết quả của phép toán AND logic giữa phần bổ
sung của mặt nạ và cài đặt chế độ cấp phép được yêu cầu của quy trình. Việc thăng hạng
số nguyên được thực hiện trên toán hạng và kết quả có kiểu được thăng hạng. Ví dụ: đoạn
mã sau áp dụng toán tử cho giá trị của kiểu unsigned char:

unsigned char uc = UCHAR_MAX; // 0xFF


int i = ~uc;

Trên cấu trúc có kiểu char 8 bit và kiểu int 32 bit, uc được gán giá trị 0xFF. Khi uc được
sử dụng làm toán hạng cho toán tử, uc được thăng cấp thành signed char bằng cách không
mở rộng nó thành 32 bit, 0x000000FF. Phần bổ sung của giá trị này là 0xFFFFFF00. Do
đó, trên nền tảng này, việc bổ sung một kiểu unsigned short luôn dẫn đến giá trị âm của
kiểu signed int. Như một chính sách chung và để tránh những điều bất ngờ như vậy, tất cả
các thao tác bitwise phải liên quan đến một kiểu số nguyên không dấu duy nhất và phải
đủ rộng.

Toán tử dịch chuyển


Các phép toán dịch chuyển (shift operations) thay đổi giá trị của mỗi bit của toán hạng
kiểu số nguyên theo một số vị trí xác định. Dịch chuyển thường được thực hiện trong hệ
thống chương trình, nơi các mặt nạ bit là phổ biến. Chúng cũng có thể được sử dụng
trong mã quản lý các giao thức protocol mạng hoặc định dạng tệp để đóng gói hoặc giải
nén dữ liệu. Chúng bao gồm các hoạt động dịch chuyển sang trái, có dạng:

shift-expression << additive-expression

và các phép toán dịch chuyển sang phải có dạng:

You might also like