10 4.104 8051 9 Acquy adc pic All datasheet ALTIUM Altium Designer AM-FM Arduino ARM ARM là gì Ấn Tượng Bản tin công nghệ Bản tin Thiết Bị Số Barobo bất động sản biến Binary Bit board lpc2378 Bộ chuyển đổi ADC Bộ Đếm Bộ điều khiển cửa cuốn Bộ Định Thời Buy Khóa Số Điện Tử Buy Mạch đếm sản phẩm Buy Mạch giao thông Buy Mạch nạp Buy Matrix Byte C cho AVR các hàm vào ra các loại lõi arm các mạch DAC cơ bản các ngắt trong pic Cách đọc điện trở Cách Đọc Giá Trị Điện Trở Cách đọc giá trị tụ điện Cách hàn linh kiện dán cách làm mạch khóa số cách tạo linh kiện dán cad/cam Cài Đặt cài đặt proteus 8 cảm biến Cấu Kiện Logic Khả Trình cấu tạo cấu trúc arm cấu trúc lệnh CCS Chân chân Transistor Chip Khả Trình chuyển đổi Chuyển đổi số tương tự Chuyển Đổi Tương Tự/Số - ADC Chuyển động số chương trình City Clip Điện Tử Code 8051 - ASM Code 8051 - C Code 8051-C code ASM code ASM mẫu 8086 Code AVR - C code C Code Lập Trình Code led sao băng code maupic code mẫu 8051 Code Mẫu 8086 Code Mẫu cho ARM - LPC1343 code mẫu pic Code PIC - C codemaupic Counter Cổng Vào Ra Cơ Bản Cuộn Cảm Cửa cuốn DA DAC Debug Decimal Delay8051 Dev-C++ Diode DIY Dò đường Do It Yourself doanh nghiệp Download DTMF Mobile đảo chiều động cơ Điện Trở Điện Tử Điện Tử Cơ Bản điều chế độ rộng xung điều chế xung PWM điều khiển bằng điện thoại Điều khiển cửa cuốn Điều khiển cửa cuốn bằng điện thoại điều khiển động cơ đo điện áp đo nhiệt độ đo nhiệt độ hiển thị lên lcd trên 8051 Đo Nhiệt Độ LM35 + LCD Đo Nhiệt Độ LM35 + Led 7 thanh đọc màu điện trở đồ chơi động cơ chân không Động cơ nhiên liệu Động cơ robo đồng hồ thời gian thực Ebook Đại Học ebook điện tử Ebook đồ án Ebook Tin Học Encoder Encoder là gì Full Giải Thuật Giải thuật PID Giáo Dục giao tiếp i2c pic 16f877a giao tiếp i2c pic16f877a với ic ds1307 giao tiếp máy tính qua rs232 Giao Tiếp Máy Tính VB6 giao tiếp rs232 giao tiếp spi giữa 2 pic giao tiếp spi trong pic Giáo Trình Điện Tử Giới thiệu 8051 Giới thiệu cơ bản GPIO Graphic Design hàm Hàn linh kiện dán Hexadecimal Hệ Hexa Hệ Nhị Phân Hệ Thập Lục Phân Hệ Thập Phân hiển thị lên lcd 16x2 Hoạt Động Học Học 8051 qua các ví dụ đơn giản Học ALtium Designer học AVR Học Corel Draw X3 Học Eagle HỌC LẬP TRÌNH 16F877A Học Lập Trình 8051 Học Lập Trình C Học Orcad Học Protues hoc-lam-robot-do-duong-qua-video Hồng ngoại hướng dẫn hướng dẫn Altium Designer hướng dẫn đo đồng hồ VOM hướng dẫn keil - C lập trình 8051 hướng dẫn làm led sao băng hướng dẫn làm led trái tim hướng dẫn lập trình ARM Hướng Dẫn Lập Trình ARM - LPC1343 hướng dẫn lập trình ARM-LPC2378 hướng dẫn lập trình CCS hướng dẫn lập trình PIC Hướng Dẫn Led Trái Tim hướng dẫn module sim548c hướng dẫn sử dụng keil hướng dẫn sử dụng proteus 8 Hyper Terminal hercules 3.2.4 I/O IC 555 IC 7447 IC 74HC151 IC 74HC154 IC 74HC245 IC 74HC595 IC 74LS138 IC DS1307 IC đồng hồ thời gian thực IC LM324 IC LM342 IC LM7805 IC số IC số opamp LM324 IC Thông Dụng IC555 Interrupt Keil 4 Full keil arm Keil C Keil uVision3 kế toán kiểm toán khái niệm Khái Niệm Cơ Bản Kho Vật Liệu khóa điện tử khóa số dùng 8051 khóa số dùng 89s52 Khóa Số Điện Tử khuếch đại kiểm tra Kinh doanh maketing kinh tế quản lí Kỹ Thuật Kỹ Thuật Vi Xử Lý làm mạch điện lý thú Làm quen AVR Lap Trinh Dieu Khien Robot Lập Trình lập trình 8051 Lập Trình AVR Lập Trình C lập trình c++ Lập Trình Led Quảng Cáo Lập Trình Nhúng Lập trình pic Lập trình Robot Lập Trình Vi Điều Khiển Lập Trình Với AVR Studio LCD 16x2 Lcd16x2 Led Clock Led Quay led sao băng led trai tim Led Trái Tim Lịch sử ra đời Linh Kiện Cơ Bản linh kiện điện tử Loa LPC 2378 LSB lý thú Mã AVR - C Mạch 7seg Mạch Amply.Mạch Loa Mạch Autorobo Mạch bảo vệ Mạch Cảm Biến mạch cảm ứng sờ tay Mạch Cầu H Mạch cube Mạch Đếm Sản Phẩm Mạch điện cơ bản Mạch điện hay Mạch Điện Ứng Dụng Mạch Điều khiển động cơ Mạch Động Cơ Mạch đồng hồ Mạch đồng hồ 4 led Mạch giao thông Mạch IC số Mạch in mạch khóa số mạch khuếch đại thuật toán mạch led chúc mừng năm mới mạch led đẹp Mạch Led đơn Mạch Led Quảng Cáo mach led trai tim mạch led trái tim Mạch Led Vumeter mạch lý thú Mạch Ma trận Phím Mạch Matrix Mạch nạp Mạch nguồn Mạch Nút Bấm mạch sóng rf mạch tăng áp Mạch thu phát Mạch tổ hợp MSI Mạch trái tim Mạch Vi điều khiển Microbicho module module GSM/GPS Module Sim548 Module Sim548 giao tiếp với vi điều khiển PIC Module Sim548C Mosfet Motor Mô Phỏng Phần Cứng Mô Tả Phần Cứng MSB mua led sao băng News Ngắt Ngắt Trong LPC23xx ngân hàng Ngôn Ngữ Ngôn Ngữ C Ngôn Ngữ Tự Học Lập Trình C Ngôn Ngữ VHDL Nguyên Lý nguyên lý ic 555 Nguyên Tắc nháy led Nhập môn C Nhỏ Gọn Nibble opamp People Phần Mềm phần mềm altium Designer Phần mềm điện tử Phần Mềm Điện Tử Phần Mềm Điện Tử Hay Phần Mềm Hay Phần Mềm Led Quảng Cáo phần mềm proteus 8 Phần mềm vi tính Phần Mền Phương pháp hàn linh kiện dán PIC pic16f877a Print Design Proteus Proteus 7.8 SP2 FULL PWM quà tặng bạn gái quà tặng độc đáo quản trị doanh nghiệp quản trị kinh doanh quét led 7 đoạn Relay robocon Robot ROBOT DÒ ĐƯỜNG rút gọn mạch logic tổ hợp Sach Dien Tu Sản Phẩm Thú Vị Sản Phẩm Thương Mại Sáng tạo Short Smart Home SMD sơ đồ nguyên lý spi Sports Sử Dụng Sử Dụng Đồng Hồ sử dụng đồng hồ VOM sử dụng ngắt trong pic sự khác nhau Sức mạnh số Tải tài chính tài chính doanh nghiệp tài chính ngân hàng Tài Khoản Chia Sẻ Tài Liệu Tài Liệu 8051 tài liệu avr Tài liệu Điện Tử Tài Liệu Pic Tài liệu robocon tài liệu về ngân hàng Tài Liệu Vi Điều Khiển tailieuvn Tạo cổng Com ảo Tạo cổng nối tiếp ảo tạo dự án trong keil arm Tạo Project trong Vi Xử Lý ARM tạo thư viện altium designer tạo xung vuông Tạp chí Tạp Chí Hay tăng áp Tập lệnh AT Team Support TEAMPLATE PROTEUS Test thị trường tài chính Thiết Bị Thú Vị Thiết kế robot Thiết lập Fuse Bits Thiết Lập Pin Thuật Toán Thuật Toán Điều Khiển PID Thuật Toán Quine MCCluskey Thư viện Protues Thực Hành Thyristor Timer Timer/Counter Tin Học Chia Sẻ Tổ Chức Bộ Nhớ tổng quan về proteus 8 Transistor Tranzito Tranzitor Trao đổi học tập Travel Trình Biên Dịch Trình Dịch Trong Suốt Truyền Thông Nối Tiếp Không Đồng Bộ- UART truyền thông nối tiếp RS232 Tụ điện TUT - 8051 - ASM TUT - 8051 - KeilC tự hành Tự Học C Tự Học Lập Trình C Tý hon UART Update USB Ứng Dụng Led Quảng Cáo ứng dụng mạch khuếch đại thuật toán vẽ mạch in vẽ mạch nguyên lý VHDL Vi Điều Khiển Vi điều khiển - Ứng dụng vi điều khiển PIC Vi mạch số Vi Xử Lý Vi Xử Lý 8051 Vi Xử Lý 8086 Vi Xử Lý ARM Vi Xử Lý PIC Video Video Mach Điện Virtual Serial Port Driver VOM vxl Web Design xác định góc quay động cơ xử lý chuỗi

Bài 4: Toán tử và Biểu thức [Lý Thuyết]

Mục tiêu:

Kết thúc bài học này, bạn có thể:

Ø  Hiểu được Toán tử gán
Ø  Hiểu được biểu thức số học
Ø  Nắm được toán tử quan hệ (Relational Operators) và toán tử luận lý (Logical Operators)
Ø  Hiểu toán tử luận lý nhị phân (Bitwise Logical Operators) và biểu thức (Expressions)
Ø  Hiểu khái niệm ép kiểu
Ø  Hiểu độ ưu tiên của các toán tử.

Giới thiệu

C có một tập các toán tử phong phú. Toán tử là công cụ dùng để thao tác dữ liệu. Một toán tử là một ký hiệu dùng để đại diện cho một thao tác cụ thể nào đó được thực hiện trên dữ liệu. C định nghĩa bốn loại toán tử: toán tử số học (arithmetic), quan hệ (relational), luận lý (logical), và toán tử luận lý nhị phân (bitwise). Bên cạnh đó, C còn có một số toán tử đặc biệt.
Toán tử thao tác trên hằng hoặc biến. Hằng hoặc biến này được gọi là toán hạng (operands). Biến đã được đề cập ở các chương trước. Hằng là những giá trị cố định mà chương trình không thể thay đổi. Hằng trong C có thể là bất cứ kiểu dữ liệu cơ bản nào. Toán tử được phân loại: toán tử một ngôi, hai ngôi hoặc ba ngôi. Toán tử một ngôi chỉ thao tác trên một phần tử dữ liệu, toán tử hai ngôi trên hai phần tử dữ liệu và ba ngôi trên ba phần tử dữ liệu.

Ví dụ 4.1:
c = a + b;
Ở đây abc là những toán hạng, dấu ‘=’ và dấu ‘+’ là những toán tử.

4.1       Biểu thức (Expressions)

Một biểu thức là tổ hợp các toán tử và toán hạng. Toán tử thực hiện các thao tác như cộng, trừ, so sánh v.v... Toán hạng là những biến hay những giá trị mà các phép toán được thực hiện trên nó. Trong ví dụ  a + b, “a” và “b” là toán hạng  và “+” là toán tử. Tất cả kết hợp lại là một biểu thức.
Trong quá trình thực thi chương trình, giá trị thực sự của biến (nếu có) sẽ được sử dụng cùng với các hằng có mặt trong biểu thức. Việc đánh giá biểu thức được thực hiện nhờ các toán tử. Vì vậy, mọi biểu thức trong C  đều có một giá trị.
Các ví dụ về biểu thức là:
2
x
3 + 7
2 × y + 5
2 + 6 × (4 - 2)
z + 3 × (8 - z)

Ví dụ 4.2:
Roland nặng 70 kilograms, và Mark nặng k kilograms. Viết một biểu thức cho tổng cân nặng của họ. Tổng cân nặng của hai người tính bằng kilograms là 70 + k.

Ví dụ 4.3:
Tính giá trị biểu thức 4 × z + 12 với z = 15.
Chúng ta thay thế mọi z với giá trị 15, và đơn giản hóa biểu thức theo quy tắc: thi hành phép toán trong dấu ngoặc trước tiên, kế đến lũy thừa, phép nhân và chia rồi phép cộng và trừ.
4 × z + 12 trở thành
4 × 15 + 12 =                           (phép nhân thực hiện trước phép cộng)
60 + 12 =
72

Toán tử gán (Assignment Operator)
Trước khi nghiên cứu các toán tử khác, ta hãy xét toán tử gán (=). Ðây là toán tử thông dụng nhất cho mọi ngôn ngữ và mọi người đều biết. Trong C, toán tử gán có thể được dùng cho bất kỳ biểu thức C hợp lệ. Dạng thức chung cho toán tử gán là:

Tên biến = biểu thức;

Gán liên tiếp
Nhiều biến có thể được gán cùng một giá trị trong một câu lệnh đơn. Việc này thực hiện qua cú pháp gán liên tiếp. Ví dụ:
a = b = c =10;
Dòng mã trên gán giá trị 10 cho a, b,và c. Tuy nhiên, việc này không thể thực hiện lúc khai báo biến. Ví dụ:
int a = int b = int c= 0;
Câu lệnh trên phát sinh lỗi vì sai cú pháp.

Biểu thức số học (Arithmetic Expressions)
Các phép toán thường được thực hiện theo một thứ tự cụ thể (hoặc riêng biệt) để cho ra giá trị cuối cùng. Thứ tự này gọi là độ ưu tiên (sẽ nói đến sau).
Các biểu thức toán học trong C được biểu diễn bằng cách sử dụng toán tử số học cùng với các toán hạng dạng số và ký tự. Những biểu thức này gọi là biểu thức số học (Arithmetic Expressions). Ví dụ về biểu thức số học là :
a * (b+c/d)/22;
++i % 7;
5 + (c = 3+8);
Như chúng ta thấy ở trên, toán hạng có thể là hằng, biến hay kết hợp cả hai. Hơn nữa, một biểu thức có thể là sự kết hợp của nhiều biểu thức con. Chẳng hạn, trong biểu thức đầu, c/d là một biểu thức con, và trong biểu thức thứ ba c = 3+8 cũng là một biểu thức con.

4.2    Toán tử quan hệ (Relational Operators)

Toán tử quan hệ được dùng để kiểm tra mối quan hệ giữa hai biến, hay giữa một biến và một hằng. Ví dụ, việc xét số lớn hơn của hai số, a và b, được thực hiện thông qua dấu lớn hơn (>) giữa hai toán hạng a và b (a > b).
Trong C, true (đúng) là bất cứ giá trị nào khác không (0), và false (sai) là bất cứ giá trị nào bằng không (0). Biểu thức dùng toán tử quan hệ trả về cho false và 1 cho true. Ví dụ biểu thức sau :
a == 14 ;
Biểu thức này kiểm tra xem giá trị của a có bằng 14 hay không. Giá trị của biểu thức sẽ là 0 (false) nếu a có giá trị khác 14 và 1 (true) nếu nó là 14.

Bảng sau mô tả ý nghĩa của các toán tử quan hệ.
Toán tử
Ý nghĩa
> 
lớn hơn
>=
lớn hơn hoặc bằng
< 
nhỏ hơn
<=
nhỏ hơn hoặc bằng
==
bằng
!=
không bằng
Bảng 4.1: Toán tử quan hệ và ý nghĩa

4.3    Toán tử luận lý (Logical Operators) và biểu thức

Toán tử luận lý là các ký hiệu dùng để kết hợp hay phủ định biểu thức có chứa các toán tử quan hệ.
Những biểu thức dùng toán tử luận lý trả về cho false và 1 cho true.                                              
Bảng sau mô tả ý nghĩa của các toán tử luận lý.                     

Toán tử
Ý nghĩa
&&
AND: trả về kết quả là true khi cả 2 toán hạng đều true
||
OR : trả về kết quả là true khi chỉ một   trong hai toán hạng  đều true
!
NOT: Chuyển đổi giá trị của toán hạng duy nhất từ true thành false và ngược   lại.
Bảng 4.2: Toán tử luận lý và ý nghĩa

Lưu ý: Bất cứ toán tử luận lý nào có ký hiệu là hai ký tự thì không được có khoảng trắng giữa hai ký tự đó, ví dụ :  ==  sẽ không đúng nếu viết là =  =.
Giả sử một chương trình phải thực thi những bước nhất định nếu điều kiện a < 10 và b == 7 được thoả mãn. Ðiều kiện này được viết ra bằng cách dùng toán tử quan hệ kết hợp với toán tử luận lý AND. Toán tử AND được viết là &&. Ta sẽ có điều kiện để kiểm tra như sau :
(a < 10) && (b == 7);

Tương tự, toán tử OR dùng để kiểm tra xem có một trong số các điều kiện kiểm tra là đúng hay không. Nó có dạng là dấu (||). Cùng ví dụ trên nhưng điều kiện cần kiểm tra là: chỉ cần một trong hai câu lệnh là đúng thì ta có mã sau :
(a < 10) || (b == 7);

Toán tử luận lý thứ ba là NOT được biểu diễn bằng ký hiệu dấu chấm than ‘!’. Toán tử này đảo ngược giá trị luận lý của biểu thức. Ví dụ, để kiểm tra xem biến s có bé hơn 10 hay không, ta viết đều kiện kiểm tra như sau:
(s < 10);
hay là
(! (s >= 10))    /* s không lớn hơn hay bằng 10 */

Cả toán tử quan hệ và luận lý có quyền ưu tiên thấp hơn toán tử số học. Ví dụ, 5 > 4 + 3 được tính tương đương với 5 > (4 + 3), nghĩa là 4+3 sẽ được tính trước và sau đó toán tử quan hệ sẽ được thực hiện. Kết quả sẽ là false, tức là trả về 0.
Câu lệnh sau:
         printf("%d", 5> 4 + 3);
sẽ cho ra:
         0
vì 5 bé hơn (4 + 3) .

4.4       Toán tử luận lý nhị phân (Bitwise Logical Operators) và biểu thức

Ví dụ xét toán hạng có giá trị là 12, toán tử luận lý nhị phân sẽ coi số 12 này như 1100. Toán tử luận lý nhị phân xem xét các toán hạng dưới dạng chuỗi bit chứ không là giá trị số thông thường. Giá trị số có thể thuộc các cơ số: thập phân (decimal), bát phân (octal) hay thập lục phân (hexadecimal). Riêng toán tử luận lý nhị phân sẽ chuyển đổi toán hạng mà nó thao tác thành biểu diễn nhị phân tương ứng, đó là dãy số 1 hoặc là 0.
Toán tử luận lý nhị phân gồm &, | , ^ , ~ , vv … được tổng kết qua bảng sau:.

Toán tử
Mô tả
Bitwise AND
( x & y)
Mỗi vị trí của bit trả về kết quả là 1 nếu bit tại vị trí tương ứng của hai toán hạng đều là 1.
Bitwise OR
( x | y)
Mỗi vị trí của bit trả về kết quả là 1 nếu bit tại vị trí tương ứng của một trong hai toán hạng là 1.
Bitwise NOT
( ~ x)
Ðảo ngược giá trị các bit của toán hạng (1 thành 0 và ngược lại).

Bitwise XOR
( x ^ y)
Mỗi vị trí của bit trả về kết quả là 1 nếu bit tại vị trí tương ứng của một trong hai toán hạng là 1 chứ không phải cả hai cùng là 1.
Bảng 4.3:  Toán tử luận lý nhị phân

Toán tử luận lý nhị phân xem kiểu dữ liệu số như là số nhị phân 32-bit, giá trị số được đổi thành giá trị bit để tính toán trước rồi sau đó sẽ trả về kết quả ở dạng số ban đầu. Ví dụ:
Biểu thức 10 & 15 có nghĩa là (1010 & 1111) trả về giá trị 1010 có nghĩa là 10.
Biểu thức 10 | 15 có nghĩa  là (1010 | 1111) trả về giá trị 1111 có nghĩa là 15.
Biểu thức 10 ^ 15 có nghĩa  là (1010 ^ 1111) trả về giá trị 0101 có nghĩa là 5.
Biểu thức ~10 có nghĩa  là ( ~1010 ) trả về giá trị 1111.1111.1111.1111.1111.1111.1111.0101 có nghĩa là -11.

4.5       Biểu thức dạng hỗn hợp & Chuyển đổi kiểu

Một biểu thức dạng hỗn hợp là một biểu thức mà trong đó các toán hạng của một toán tử thuộc về nhiều kiểu dữ liệu khác nhau. Những toán hạng này thông thường được chuyển về cùng kiểu với toán hạng có kiểu dữ liệu lớn nhất. Điều này được gọi là tăng cấp kiểu. Sự phát triển về kiểu dữ liệu theo thứ tự sau :
         char < int

Chuyển đổi kiểu tự động được trình bày dưới đây nhằm xác định giá trị của biểu thức:
a.      char và short được chuyển thành int và float được chuyển thành double.
b.      Nếu có một toán hạng là double,  toán hạng còn lại sẽ được chuyển thành double, và kết quả là double.
c.      Nếu có một toán hạng là long, toán hạng còn lại sẽ được chuyển thành long, và kết quả là long.
d.      Nếu có một toán hạng là unsigned,  toán hạng  còn lại sẽ được chuyển thành unsigned và kết quả cũng là unsigned.
e.             Nếu tất cả toán hạng kiểu int, kết quả là int.

Ngoài ra nếu một toán hạng là long và toán hạng khác là unsigned và giá trị của kiểu unsigned không thể biểu diễn bằng kiểu long. Do vậy, cả hai toán hạng được chuyển thành unsigned long.

Sau khi áp dụng những quy tắc trên, mỗi cặp toán hạng có cùng kiểu và kết quả của mỗi phép tính sẽ cùng kiểu với hai toán hạng.
                                char ch;
                                int i;
                                float f;
                                double d;
                                result = (ch/i) + (f*d) – (f+i);

Trong ví dụ trên, trước tiên, ch có kiểu ký tự được chuyển thành integer và float f được chuyển thành double. Sau đó, kết quả của ch/i được chuyển thành double bởi vì f*d là double. Kết quả cuối cùng là double bởi vì các toán hạng lúc này đều là double.

4.5.1    Ép kiểu (Casts)

Thông thường, ta nên đổi tất cả hằng số nguyên sang kiểu float nếu biểu thức bao gồm những phép tính số học dựa trên số thực, nếu không thì vài biểu thức có thể mất đi giá trị thật của nó.Ta xem ví dụ:
int x,y,z;
x = 10;
y = 100;
z = x/y;

Trong trường hợp này, z sẽ được gán 0 khi phép chia diễn ra và phần thập phân (0.10) sẽ bị cắt bỏ.
Do đó một biểu thức có thể được ép thành một kiểu nhất định. Cú pháp chung của cast là:
(kiểu dữ liệu) biểu thức
Ví dụ, để đảm bảo rằng biểu thức a/b, với a và b là số nguyên, cho kết quả là kiểu float, dòng mã sau được viết:
(float) a/b;
Ép kiểu có thể áp dụng cho các giá trị hằng, biểu thức hay biến, ví dụ:
(int) 17.487;
(double) (5 * 4 / 8);
(float) (a + 7);
Trong ví dụ thứ hai, toán tử ép kiểu không đạt mục đích của nó bởi vì nó chỉ thực thi sau khi toàn biểu thức trong dấu ngoặc đã được tính. Biểu thức 5 * 4 / 8 cho ra giá trị là 2 (vì nó có kiểu là số nguyên nên đã cắt đi phần thập phân), vì vậy, giá trị kết quả với kiểu double cũng là 2.0.

Ví dụ:
int i = 1, j = 3;
x = i / j;          /* x = 0.0 */
x = (float) i/(float) j;        /* x = 0.33 */

4.6    Độ ưu tiên của toán tử (Precedence)

Độ ưu tiên của toán tử thiết lập thứ tự ưu tiên tính toán khi một biểu thức số học cần được ước lượng. Tóm lại, độ ưu tiên đề cập đến thứ tự mà C thực thi các toán tử. Thứ tự ưu tiên của toán tử số học được thể hiện như bảng dưới đây.

Loại toán tử
Toán tử
Tính kết hợp
Một ngôi
++, --
Phải sang trái
Hai ngôi
^
Trái sang phải
*, /, %
+, -
=
Phải sang trái
Bảng 4.4: Thứ tự ưu tiên của toán tử số học
                                                                       
Những toán tử nằm cùng một hàng ở bảng trên có cùng quyền ưu tiên. Việc tính toán của một biểu thức số học sẽ được thực hiện từ trái sang phải cho các toán  tử cùng độ ưu tiên. Toán tử */, và % có cùng đô ưu tiên và cao hơn và (hai ngôi).
Độ ưu tiên của những toán tử này có thể được thay đổi bằng cách sử dụng dấu ngoặc đơn. Một biểu thức trong ngoặc luôn luôn được tính toán trước. Một cặp dấu ngoặc đơn này có thể được bao trong cặp khác. Ðây là sự lồng nhau của những dấu ngoặc đơn. Trong trường hợp đó, việc tính toán trước tiên được thực hiện tại cặp dấu ngoặc đơn trong cùng nhất rồi đến dấu ngoặc đơn bên ngoài.
Nếu có nhiều bộ dấu ngoặc đơn  thì việc thực thi sẽ theo thứ tự từ trái sang phải.

Tính kết hợp cho biết cách thức các toán tử kết hợp với các toán hạng của chúng. Ví dụ, đối với toán tử một ngôi: toán hạng nằm bên phải được tính trước, trong phép chia thì toán hạng bên trái được chia cho toán hạng bên phải. Đối với toán tử gán thì biểu thức bên phải được tính trước rồi gán giá trị cho biến bên trái toán tử.

Tính kết hợp cũng cho biết thứ tự mà theo đó C đánh giá các toán tử trong biểu thức có cùng độ ưu tiên. Các toán tử như vậy có thể tính toán từ trái sang phải hoặc ngược lại như thấy trong bảng 4.5.

Ví dụ:
a = b = 10/2;
Giá trị 5 sẽ gán cho b xong rồi gán cho a. Vì vậy thứ tự ưu tiên sẽ là phải sang trái. Hơn nữa:
-8 * 4 % 2 – 3
được tính theo trình tự sau:
         Trình tự        Thao tác                                    Kết quả
         1.                   - 8 (phép trừ một ngôi)               số âm của 8
         2.                   - 8 * 4                                        - 32
         3.                   - 32 % 2                                       0
         4.                     0-3                                            -3

Theo trên thì toán tự một ngôi (dấu - ) có quyền ưu tiên cao nhất được tính trước tiên. Giữa * và % thì được tính từ trái sang phải. Tiếp đến sẽ là phép trừ hai ngôi.

Thứ tự ưu tiên của các biểu thức con
Những biểu thức phức tạp có thể chứa những biểu thức nhỏ hơn gọi là biểu thức con. C không xác định thứ tự mà các biểu thức con được lượng giá. Một biểu thức sau:
a * b /c + d *c;
bảo đảm rằng biểu thức con a * b/c và d*c sẽ được tính trước phép cộng. Hơn nữa, quy tắc từ trái sang phải cho phép toán nhân và chia bảo đảm rằng a sẽ được nhân với và sau đó sẽ chia cho c. Nhưng không có quy tắc xác định hoặc a*b /c được tính trước hay sau d*c. Tùy chọn này là ở người thiết kế trình biên dịch quyết định. Quy tắc trái sang phải hay ngược lại chỉ áp dụng cho một chuỗi toán tử cùng độ ưu tiên. Cụ thể, nó áp dụng cho phép nhân và chia trong a*b/c. Nhưng nó không áp dụng cho toán tử  + vì đã khác cấp.
Bởi vì không thể xác định thứ tự tính toán các biểu thức con, do vậy, ta không nên dùng các biểu thức nếu giá trị biểu thức phụ thuộc vào thứ tự tính toán các biểu thức con . Xét ví dụ sau:
a * b + c * b++ ;
Có thể trình biên dịch này tính giá trị mục bên trái trước và dùng cùng giá trị cho cả hai biểu thức con. Nhưng trình biên dịch khác lại tính giá trị mục bên phải và tăng giá trị  trước khi tính giá trị mục bên trái.

Ta không nên dùng toán tử tăng hay giảm cho một biến mà nó xuất hiện nhiều hơn một lần trong một biểu thức.

Thứ tự ưu tiên giữa những toán tử so sánh (toán tử quan hệ)
          Ta đã thấy trong phần trước một số toán tử số học có độ ưu tiên cao hơn các toán tử số học khác. Riêng với toán tử so sánh, không có thứ tự ưu tiên giữa các toán tử và chúng được ước lượng từ trái sang phải.

Thứ tự ưu tiên giữa những toán tử luận lý
          Bảng dưới đây trình bày thứ tự ưu tiên cho toán tử luận lý.
Thứ tự
Toán tử
1
NOT
2
AND
3
OR
Bảng 4.5: Thứ tự ưu tiên cho toán tử luận lý

Khi có nhiều toán tử luận lý trong một điều kiện, chúng được lượng giá từ phải sang trái.

Ví dụ, xét điều kiện sau:
False OR True AND NOT False AND True

Ðiều kiện này được tính như sau:
1.      False OR True AND [NOT False] AND True
            NOT có độ ưu tiên cao nhất.
2.      False OR True AND [True AND True]
            Ở đây, AND là toán tử có độ ưu tiên cao nhất và những toán tử có cùng ưu tiên được tính từ phải sang trái.
3.      False OR [True AND True]
4.      [False OR True]
5.      True

Thứ tự ưu tiên giữa các kiểu toán tử khác nhau
Khi một biểu thức có nhiều hơn một kiểu toán tử thì thứ tự ưu tiên phải được thiết lập giữa các kiểu toán tử với nhau.

Bảng dưới đây cho biết thứ tự ưu tiên giữa các kiểu toán tử khác nhau.
Thứ tự
Kiểu toán tử
1
Số học
2
So sánh (Quan hệ)
3
Luận lý
Bảng 4.6. Thứ tự ưu tiên giữa các kiểu toán tử khác nhau

Do vậy, trong một biểu thức gồm cả ba kiểu toán tử, các toán tử số học được tính trước, kế đến là toán tử so sánh và sau đó là toán tử luận lý. Thứ tự ưu tiên của các toán tử trong cùng một kiểu thì đã được nói tới ở những phần trước.

Xét ví dụ sau:
2*3+4/2 > 3 AND 3<5 10="" or="" span="">

Việc thực hiện tính toán sẽ như sau:
1.      [2*3+4/2] > 3 AND 3<5 10="" o:p="" or="">
            Ðầu tiên toán tử số học sẽ được tính theo thứ tự ưu tiên như bảng 4.4.
2.      [[2*3]+[4/2]] > 3 AND 3<5 10="" o:p="" or="">
3.      [6+2] >3 AND 3<5 10="" o:p="" or="">
4.      [8 >3] AND [3<5 o:p="" or="">
            Kế đến sẽ tính tất cả những toán tử so sánh có cùng độ ưu tiên theo quy tắc tính từ trái sang phải.
5.      True AND True OR False
            Cuối cùng tính toán các toán tử kiểu luận lý. AND sẽ có độ ưu tiên cao hơn OR.
6.      [True AND True]OR False
7.      True OR False
8.      True

Dấu ngoặc đơn
Thứ tự ưu tiên của các toán tử có thể thay đổi bởi các dấu ngoặc đơn. Khi đó, chương trình sẽ tính toán các phần dữ liệu trong dấu ngoặc đơn trước.

Ø  Khi một cặp dấu ngoặc đơn này được bao trong cặp khác, việc tính toán thực hiện trước tiên tại cặp dấu ngoặc đơn trong cùng nhất, rồi đến dấu ngoặc đơn bên ngoài.
Ø  Nếu có nhiều bộ dấu ngoặc đơn thì việc thực hiện sẽ theo thứ tự từ trái sang phải.

Xét ví dụ sau:
5+9*3^2-4 > 10 AND (2+2^4-8/4 > 6 OR (2<6 10="" and="">11))
Cách tính sẽ là:
1.      5+9*3^2-4 > 10 AND (2+2^4-8/4 > 6 OR (True AND False))
Dấu ngoặc đơn trong cùng sẽ được tính trước tất cả các toán tử khác và áp dụng quy tắc cơ bản trong bảng 4.6 cho tính toán bên trong cặp dấu ngoặc này.
2.      5+9*3^2-4 > 10 AND (2+2^4-8/4 > 6 OR False)
3.      5+9*3^2-4 > 10 AND (2+16-8/4 > 6 OR False)
Kế đến dấu ngoặc đơn ở ngoài được xét đến. Xem lại các bảng nói về thứ tự ưu tiên của các toán tử.
4.      5+9*3^2-4 > 10 AND (2+16-2 > 6 OR False)
5.      5+9*3^2-4 > 10 AND (18-2 > 6 OR False)
6.      5+9*3^2-4 > 10 AND (16 > 6 OR False)
7.      5+9*3^2-4 > 10 AND (True OR False)
8.      5+9*3^2-4 > 10 AND True
9.      5+9*9-4>10 AND True

Ta tính biểu thức bên trái trước theo các quy tắc
10.  5+81-4>10 AND True
11.  86-4>10 AND True
12.  82>10 AND True
13.  True AND True
14.  True.





Tóm tắt bài học
Ø  C định nghĩa bốn loại toán tử: số học, quan hệ (so sánh), luận lý và luận lý nhị phân.
Ø  Tất cả toán tử trong C được tính toán theo thứ tự độ ưu tiên.
Ø  Toán tử quan hệ được dùng kiểm tra mối quan hệ giữa hai biến hay giữa một biến và một hằng.
Ø  Toán tử luận lý là những ký hiệu dùng để kết hợp hay phủ định những biểu thức chứa các toán tử quan hệ.
Ø  Toán tử luận lý nhị phân xét các toán hạng như là bit nhị phân chứ không phải là các giá trị số thập phân.
Ø  Phép gán (=) được xem như là một toán tử có tính kết hợp từ phải sang trái.
Ø  Độ ưu tiên thiết lập sự phân cấp của một tập các toán tử so với tập các toán tử khác khi ước lượng một biểu thức.





Kiểm tra tiến độ học tập

1.      ______ là những công cụ thao tác dữ liệu.
A. Những toán tử
B. Những toán hạng
C. Những biểu thức
D. Không câu nàođúng
2.       Một ­­­­­_______ bao gồm sự kết hợp của các toán tử và các toán hạng.
A. Biểu thức
B. Hàm
C. Con trỏ
D. Không câu nàođúng
3.      ________ thiết lập sự phân cấp của một tập các toán tử so với tập các toán tử khác khi ước lượng một biểu thức.
A. Những toán hạng
B. Độ ưu tiên
C. Toán tử
D. Không câu nàođúng
4.      ____________  là một biểu thức có  các toán hạng thuộc nhiều kiểu dữ liệu khác nhau.
A. Biểu thức đơn
B. Biểu thức hỗn hợp
C.  Quyền ưu tiên
D. Không câu nào đúng
5.      Một biểu thức được ép thành một kiểu nhất định bằng cách dùng ____.
A. Ép kiểu
B. Quyền ưu tiên
C. Toán tử
D. Không câu nàođúng
6.      _________ được dùng để kết hợp hay phủ định biểu thức chứa các toán tử quan hệ.
A. Những toán tử luận lý
B. Những toán tử luận lý nhịphân
C. Những toán tử phức
D. Không câu nào đúng
7.      Những toán tử luận lý nhị phân là __, ___, __ và __ .
A. % , ^ , * and @
B. &,|,~ and ^
C.  !,],& and *
D. Không câu nàođúng
8.   Ðộ ưu tiên của các toán tử  có thể được thay đổi bằng cách đặt các phần tử được yêu cầu của biểu thức trong _________  .
A. Dấu ngoặc xoắn ({ })
B. Ký hiệu mũ ( ^)
C. Những dấu ngoặc đơn (())
D. Không câu nàođúng





Bài tập tự làm

1.      Viết một chương trình nhập và cộng ba số.
2.      Viết một chương trình tính giá trị của biểu thức với các giá trị sau:
z = a*b+(c/d)-e*f ;
      a = 10
      b = 7
      c = 15.75
      d = 4
      e = 2
      f = 5.6

3.      Viết một chương trình tính diện tích và chu vi của hình chữ nhật.
4.      Viết một chương trình tính thể tích của một hình trụ.
5.      Viết một chương trình tính lương thực lãnh của một nhân viên theo công thức dưới đây
Lương cơ bản : $ 12000
DA : 12% lương cơ bản
HRA : $150
TA : $120
Các mục khác : $450
      Thuế :
  PF :14% lương cơ bản   và   IT: 15% lương cơ bản
Lương thực lãnh = Lương cơ bản + DA + HRA + TA + Các mục khác – (PF + IT)
DIENTUCHIASE.COM- TÀI LIỆU MIỄN PHÍ VÀ LUÔN NHƯ VẬY!

Lập Trình, Lập Trình C, Ngôn Ngữ C, Nhập môn C, Tự Học C, Tự Học Lập Trình C, Điện Tử Cơ Bản, Tài Liệu Vi Điều Khiển,

Đăng nhận xét

Author Name

{picture https://lh3.googleusercontent.com/-5Ns_H0UG4cU/Vuu5KrqbEnI/AAAAAAAAEZs/XgsHemy00D4eQ3ivA76v6FFEm7jg9reVwCCo/s512-Ic42/pham-van-ngoc-anh.jpg}

Tôi là Ngọc Anh. Tôi đến từ Nghệ An. Tôi tốt nghiệp một trường đại học tại Sài Gòn. Hiện tôi đang phát triển công ty riêng. Liên lạc với tôi qua:

{facebook https://www.facebook.com/phamvanngocanh}
{twitter https://twitter.com/nghiphong1993}
{google https://plus.google.com/+dientuchiase/posts}
{youtube https://www.youtube.com/channel/UCeJKhA_goBNFmDw6RKNtmYQ}

Biểu mẫu liên hệ

Tên

Email *

Thông báo *

Được tạo bởi Blogger.