Kiểu dữ liệu void c. Chức năng

Năm 1989 Trong ngôn ngữ C++, void đã được chuẩn hóa vào năm 1998.

Sau đó, từ khóa void và các cấu trúc ngôn ngữ liên quan được kế thừa bởi các ngôn ngữ Java và C#, D.

Cú pháp

Về mặt cú pháp, void là một trong những công cụ xác định kiểu được bao gồm trong nhóm công cụ xác định khai báo tổng quát hơn, nhưng được triển khai như một toán tử trong một số ngôn ngữ lập trình. Ví dụ: trong JavaScript, void là một toán tử và luôn trả về giá trị không xác định:

Biểu thức trống === không xác định;

Ngữ nghĩa

Ngữ nghĩa của từ khóa void không phụ thuộc vào ngữ nghĩa chung của các bộ xác định loại và phụ thuộc vào phương pháp sử dụng:

  • Vì tên của loại giá trị được hàm trả về: chỉ ra rằng hàm không trả về một giá trị và lệnh gọi hàm như vậy là một biểu thức void. Phần thân của hàm như vậy không được chứa các câu lệnh trả về có biểu thức. Ví dụ:

    Vô hiệu f() ;

  • Là một phần của bộ khai báo hàm: chỉ ra rằng hàm có nguyên mẫu và không có tham số. Ví dụ:

    Int f(void);

  • Như tên của loại mục tiêu của thao tác truyền: việc truyền void như vậy có nghĩa là từ bỏ giá trị của biểu thức được truyền. Ví dụ:

    #define Promote_ptr() ((void) (ptr++))

  • Là một phần của tên loại của một con trỏ void: một con trỏ như vậy có khả năng biểu thị các giá trị của bất kỳ con trỏ nào đối với các loại đối tượng và các loại không đầy đủ, tức là. địa chỉ của bất kỳ đối tượng nào. Vì vậy, con trỏ void là con trỏ đối tượng tổng quát. con trỏ void không có khả năng biểu diễn giá trị của con trỏ hàm. Ngoại trừ trường hợp truyền con trỏ null thành con trỏ hàm trong C, không có chuyển đổi rõ ràng hoặc ngầm định giữa con trỏ void và con trỏ hàm.

Loại void được định nghĩa là loại không đầy đủ và không thể mở rộng. Do đó, loại này không nên được sử dụng khi chỉ cho phép loại đầy đủ, chẳng hạn như loại tham số trong định nghĩa hàm.

Ngôn ngữ C trước khi giới thiệu void

Trước khi xuất bản tiêu chuẩn C đầu tiên vào năm 1989, tiêu chuẩn này đưa từ khóa void vào ngôn ngữ, thông thường là khai báo các hàm không trả về giá trị mà không sử dụng công cụ xác định kiểu. Mặc dù việc khai báo này tương đương về mặt ngữ nghĩa với việc khai báo một hàm trả về giá trị kiểu int, nhưng việc cố tình bỏ sót các bộ xác định kiểu đã nhấn mạnh rằng hàm này không trả về bất kỳ giá trị cụ thể nào. Ví dụ:

F(dài l) ( /* ... */ )

Tương tự, các định nghĩa hàm không có tham số được viết bằng dấu ngoặc đơn trống:

Int main() ( /* ... */ )

Một con trỏ tới char được sử dụng làm con trỏ chung. Hơn nữa, các tiêu chuẩn hiện đại yêu cầu các yêu cầu về biểu diễn và căn chỉnh cho con trỏ void giống như đối với con trỏ char, nghĩa là các kiểu có thể thay thế cho nhau.

Phương ngữ tiêu chuẩn đầu tiên của C (C89), mặc dù nó đã cho phép các mục nhập có từ khóa void, nhưng vẫn cho phép sử dụng int ngầm định này để duy trì khả năng tương thích với mã hiện có. Phương ngữ hiện đại của C (C99) không cho phép thiếu chỉ định loại trong tên loại và khai báo.

Ví dụ

Trên đây là các ví dụ về cách khai báo hàm trả về void.

C++

Tin nhắn trống()

Java

Tin nhắn trống()

C#

Tin nhắn trống()

C

Tin nhắn vô hiệu(void)

Mục tiêu-C

- (vô hiệu) tin nhắn;

D

Tin nhắn trống()

Tập lệnh hành động

Thông báo chức năng (): void

Ghi chú


Quỹ Wikimedia. 2010.

Câu chuyện

Trong số các ngôn ngữ lập trình hiện đại, từ khóa void xuất hiện lần đầu tiên trong C++ để hỗ trợ khái niệm con trỏ chung. Tuy nhiên, nhờ vay mượn nhanh chóng từ C++, tài liệu quy chuẩn đầu tiên chứa từ khóa này là tiêu chuẩn ngôn ngữ C, được ANSI xuất bản năm 1989. Trong ngôn ngữ C++, void đã được chuẩn hóa vào năm 1998.

Sau đó, từ khóa void và các cấu trúc ngôn ngữ liên quan được kế thừa bởi các ngôn ngữ Java và C#, D.

Cú pháp

Về mặt cú pháp, void là một trong những công cụ xác định kiểu được bao gồm trong nhóm công cụ xác định khai báo tổng quát hơn.

Ngữ nghĩa

Ngữ nghĩa của từ khóa void không phụ thuộc vào ngữ nghĩa chung của các bộ xác định loại và phụ thuộc vào phương pháp sử dụng:

  • Vì tên của loại giá trị được hàm trả về: chỉ ra rằng hàm không trả về một giá trị và lệnh gọi hàm như vậy là một biểu thức void. Phần thân của hàm như vậy không được chứa các câu lệnh trả về có biểu thức. Ví dụ:

    Vô hiệu f() ;

  • Là một phần của bộ khai báo hàm: chỉ ra rằng hàm có nguyên mẫu và không có tham số. Ví dụ:

    Int f(void);

  • Như tên của loại mục tiêu của thao tác truyền: việc truyền void như vậy có nghĩa là từ bỏ giá trị của biểu thức được truyền. Ví dụ:

    #define Promote_ptr() ((void) (ptr++))

  • Là một phần của tên loại của một con trỏ void: một con trỏ như vậy có khả năng biểu thị các giá trị của bất kỳ con trỏ nào đối với các loại đối tượng và các loại không đầy đủ, tức là. địa chỉ của bất kỳ đối tượng nào. Vì vậy, con trỏ void là con trỏ đối tượng tổng quát. con trỏ void không có khả năng biểu diễn giá trị của con trỏ hàm. Ngoại trừ trường hợp truyền con trỏ null thành con trỏ hàm trong C, không có chuyển đổi rõ ràng hoặc ngầm định giữa con trỏ void và con trỏ hàm.

Loại void được định nghĩa là loại không đầy đủ và không thể mở rộng. Do đó, loại này không nên được sử dụng khi chỉ cho phép loại đầy đủ, chẳng hạn như loại tham số trong định nghĩa hàm.

Ngôn ngữ C trước khi giới thiệu void

Trước khi xuất bản tiêu chuẩn C đầu tiên vào năm 1989, tiêu chuẩn này đưa từ khóa void vào ngôn ngữ, thông thường là khai báo các hàm không trả về giá trị mà không sử dụng công cụ xác định kiểu. Mặc dù việc khai báo này tương đương về mặt ngữ nghĩa với việc khai báo một hàm trả về giá trị kiểu int, nhưng việc cố tình bỏ sót các bộ xác định kiểu đã nhấn mạnh rằng hàm này không trả về bất kỳ giá trị cụ thể nào. Ví dụ:

F(dài l) ( /* ... */ )

Tương tự, các định nghĩa hàm không có tham số được viết bằng dấu ngoặc đơn trống:

Int main() ( /* ... */ )

Một con trỏ tới char được sử dụng làm con trỏ chung. Hơn nữa, các tiêu chuẩn hiện đại yêu cầu các yêu cầu về biểu diễn và căn chỉnh cho con trỏ void giống như đối với con trỏ char, nghĩa là các kiểu có thể thay thế cho nhau.

Phương ngữ tiêu chuẩn đầu tiên của C (C89), mặc dù nó đã cho phép các mục nhập có từ khóa void, nhưng vẫn cho phép sử dụng int ngầm định này để duy trì khả năng tương thích với mã hiện có. Phương ngữ hiện đại của C (C99) không cho phép thiếu chỉ định loại trong tên loại và khai báo.

Ví dụ

C++

#bao gồm void main() ( printf("Xin chào!\n"); )

Java

void message())( System.out.println("Xin chào!"); )

C

void message(void) ( printf("Xin chào!"); )

D

void message() ( writefln("Xin chào!"); )

Liên kết


Quỹ Wikimedia. 2010.

Xem "Void" là gì trong các từ điển khác:

    trống rỗng- 1 / vȯid/ adj 1: không có hiệu lực hoặc hiệu lực theo pháp luật a vô hiệu hôn nhân 2: vô hiệu vô hiệu n void ness n void 2 vt: thực hiện hoặc tuyên bố … Từ điển luật

    Vô hiệu- có thể tham khảo:Trong tiểu thuyết: * Void (truyện tranh), nhân vật trong WildC.A.T.S. * Void (Mortal Kombat), một địa điểm hoặc vương quốc hư cấu trong Mortal Kombat * Void, một trong những nhân vật phản diện nhỏ trong Sonic the Hedgehog * Void 1.1, một trò chơi chiến tranh khoa học viễn tưởng được tạo ra… … Wikipedia

    Vô hiệu- Đổ la xã Pháp, với Void Vacon. Trong lập trình, void est un mot clé que l on retrouve dans le langage C et plusieurs autres langages deprogrammation không phải là một nguồn gốc, như C++, le C# hoặc Java. Ce mot clé void… … Wikipédia en Français

    Vô hiệu- Vô ích, a. 1. Không chứa đựng gì; trống; bỏ trống; không chiếm; Chưa được điên.… …

    trống rỗng- tính từ LUẬT một hợp đồng hoặc thỏa thuận vô hiệu không có hiệu lực pháp lý vì nó trái pháp luật: Theo luật tiểu bang, hợp đồng trả tiền khi cố ý đánh bạc là vô hiệu. động từ trống: Mr. Việc Mullen chấm dứt hợp đồng… …Các điều khoản tài chính và kinh doanh

    Vô hiệu- Vô ích, v. t. 1. Xóa nội dung của; để trống hoặc để trống; bỏ cuộc; rời đi; như, để làm trống một bảng. Vô hiệu hóa vị trí của cô ấy.… … Từ điển tiếng Anh quốc tế hợp tác

    Vô hiệu- steht für: Void (Astronomie), eine astronomische Struktur mit sehr wenig Materie und damit sehr geringer Dichte Void (Verbindungstechnik) Void (Schlüsselwort), ein Schlüsselwort in einigen Programmiersprachen Void Vacon, eine francösische… … Wikipedia tiếng Đức

    trống rỗng- trống rỗng, bị bỏ rơi, trần trụi, cằn cỗi, thiếu thốn, trong sáng, thiếu thốn, cơ cực, trống rỗng, cạn kiệt, trống rỗng, tự do, thiếu thốn, thiếu thốn, ngắn ngủi, nhút nhát, không có người thuê, không có người ở, không có người ở, trống rỗng, trống rỗng, không có; khái niệm 481,583,740,774 Ant. đầy, đầy, chiếm…Từ điển đồng nghĩa mới

Trong Bài 1, bạn đã tạo một số chương trình C++. Khi đó, mục tiêu của bạn là hiểu quá trình tạo và biên dịch chương trình C++ chứ không phải hiểu các câu lệnh C++. Trong bài học này, trước tiên bạn sẽ xem xét kỹ hơn các câu lệnh tạo nên chương trình C++. Bạn sẽ thấy rằng hầu hết các chương trình C++ đều tuân theo cùng một định dạng: bắt đầu bằng một hoặc nhiều câu lệnh #.bao gồm, chứa chuỗi void chính(void),và sau đó là một tập hợp các câu lệnh được nhóm giữa các dấu ngoặc nhọn trái và phải. Như bạn sẽ thấy trong hướng dẫn này, những toán tử có phần đáng sợ này thực ra lại rất dễ thành thạo. Đến cuối bài học này, bạn sẽ học được các khái niệm cốt lõi sau:

  • Nhà điều hành # bao gồm cung cấp những lợi ích của việc sử dụng các tệp tiêu đề có chứa các câu lệnh C++ hoặc định nghĩa chương trình.
  • Phần chính của chương trình C++ bắt đầu bằng câu lệnh void chính(void).
  • Các chương trình bao gồm một hoặc nhiều chức năng, lần lượt bao gồm các câu lệnh được thiết kế để giải quyết một vấn đề cụ thể.
  • Khi được in ra màn hình, các chương trình của bạn sẽ tận dụng tối đa luồng đầu ra cout.

Khi bạn viết chương trình C++, thực tế là bạn đang làm việc về mặt người vận hành, nhưng không có hướng dẫn. Sau này bạn sẽ học toán tử gán,để gán giá trị cho biến, toán tử nếu như, cho phép chương trình đưa ra quyết định, v.v. Hiện tại, chúng tôi sẽ chỉ coi nội dung chương trình của bạn là người điều hành chương trình.


TÌM HIỂU VỀ NHÀ ĐIỀU HÀNH CHƯƠNG TRÌNH

Trong Bài học 1, bạn đã tạo một chương trình C++, FIRST.CPP, chứa các câu lệnh sau:

#bao gồm

khoảng trống chính(void)

{
cout<< «Учимся программировать на языке С++!»;
}

Trong trường hợp này, chương trình chứa ba câu lệnh. Niềng răng xoăn (gọi là nhóm ký tự) các toán tử liên quan đến nhóm:

#bao gồm

khoảng trống chính (void)

{
cout<< «Учимся программировать << «на языке С++!»;
}

Phần tiếp theo mô tả chi tiết hơn từng câu lệnh của chương trình.

GIỚI THIỆU VỀ NGƯỜI ĐIỀU HÀNH #bao gồm

Mỗi chương trình được trình bày trong Bài 1 đều bắt đầu bằng câu lệnh sau # bao gồm:

#bao gồm

Khi viết chương trình C++, bạn được hưởng lợi từ các toán tử và định nghĩa mà trình biên dịch cung cấp cho bạn. Khi biên dịch chương trình, toán tử # bao gồm khiến trình biên dịch đưa nội dung của một tệp nhất định vào đầu chương trình của bạn. Trong trường hợp này, trình biên dịch sẽ bao gồm nội dung của tệp iostream.h.

Các tệp có phần mở rộng h mà bạn đưa vào đầu (hoặc tiêu đề) chương trình của bạn được gọi là các tập tin tiêu đề. Nếu bạn nhìn vào thư mục chứa các tệp trình biên dịch của mình, bạn sẽ tìm thấy thư mục con có tên INCLUDE chứa nhiều tệp tiêu đề khác nhau. Mỗi tệp tiêu đề chứa các định nghĩa do trình biên dịch cung cấp cho các hoạt động khác nhau. Ví dụ: có một tệp tiêu đề chứa các định nghĩa cho các phép toán, một tệp tiêu đề khác mô tả các phép toán tệp, v.v.

Tệp tiêu đề là tệp ASCII, vì vậy bạn có thể xuất nội dung của chúng ra màn hình hoặc máy in. Hiện tại, đừng lo lắng về nội dung của các tệp tiêu đề. Chỉ cần hiểu rằng toán tử # bao gồm cho phép bạn sử dụng các tập tin này. Tất cả các chương trình C++ bạn tạo trong cuốn sách này đều chứa # câu lệnh. bao gồm, mà bạn nên sử dụng trong các chương trình của mình.

Tệp tiêu đề C++

Mỗi chương trình C++ bạn viết đều bắt đầu bằng một hoặc nhiều câu lệnh #include. Những câu lệnh này yêu cầu trình biên dịch đưa nội dung của một tệp nhất định (tệp tiêu đề) vào chương trình của bạn, như thể chương trình chứa các câu lệnh nằm trong tệp bao gồm. Các tệp tiêu đề chứa các định nghĩa được trình biên dịch sử dụng cho các loại hoạt động khác nhau. Có các tệp tiêu đề xác định các hoạt động I/O C++, các hàm hệ thống (chẳng hạn như các hàm trả về ngày và giờ hiện tại), v.v.

Các tệp tiêu đề, giống như các chương trình C++, là các tệp ASCII có nội dung bạn có thể xem hoặc in. Để hiểu rõ hơn nội dung của các tệp tiêu đề, hãy dành chút thời gian để in tệp tiêu đề IOSTREAM.H, nội dung mà bạn sẽ sử dụng trong mọi chương trình C++ mà bạn viết. Thông thường, tệp tiêu đề IOSTREAM.H nằm trong thư mục con có tên INCLUDE, nằm trong thư mục chứa các tệp trình biên dịch C++. Sử dụng trình soạn thảo văn bản để xem và in nội dung của tệp tiêu đề.

Lưu ý: Không bao giờ thay đổi nội dung của tệp tiêu đề. Điều này có thể dẫn đến lỗi biên dịch trong mọi chương trình bạn tạo.

Cái gì là trống rỗng chính (không có)

Khi bạn tạo một chương trình C++, tệp nguồn của bạn sẽ chứa nhiều câu lệnh. Như bạn sẽ học khi học, thứ tự xuất hiện các câu lệnh trong chương trình không nhất thiết phải là thứ tự các câu lệnh sẽ được thực thi khi chương trình chạy. Mỗi chương trình C++ có một đầu vào để bắt đầu thực hiện chương trình - chương trình chính. Trong các chương trình C++, toán tử khoảng trống chính(void) cho biết điểm bắt đầu của chương trình của bạn.

Khi chương trình của bạn trở nên lớn hơn và phức tạp hơn, bạn sẽ chia chúng thành nhiều phần nhỏ, dễ quản lý. Trong trường hợp này người vận hành khoảng trống chính(void) cho biết các câu lệnh ban đầu (hoặc chính) của một chương trình - phần của chương trình được thực thi đầu tiên.

Giới thiệu chương trình chính

Các tệp nguồn C++ có thể chứa nhiều câu lệnh. Khi một chương trình bắt đầu, câu lệnh void main(void) xác định chương trình chính chứa câu lệnh đầu tiên được thực thi. Các chương trình C++ của bạn phải luôn bao gồm một và chỉ một câu lệnh gọi là main.

Khi xem các chương trình C++ lớn, hãy tìm main để xác định các câu lệnh bắt đầu thực hiện chương trình.

Cách sử dụng trống rỗng

Khi chương trình của bạn trở nên phức tạp hơn, bạn nên chia nó thành các phần nhỏ hơn, dễ quản lý hơn, gọi là chức năng. Hàm là một tập hợp các câu lệnh đơn giản trong một chương trình để thực hiện một tác vụ cụ thể. Ví dụ: nếu bạn đang tạo một chương trình chứng từ thanh toán, bạn có thể tạo một hàm có tên lương tính lương cho nhân viên. Tương tự như vậy, nếu bạn đang viết một chương trình toán học, bạn có thể tạo các hàm có tên căn bậc hai hoặc khối lập phương trả về kết quả của một số phép toán nhất định. Nếu chương trình của bạn sử dụng một hàm, hàm đó sẽ thực hiện nhiệm vụ của nó và sau đó trả về kết quả cho chương trình.

Mỗi chức năng trong chương trình của bạn có một tên duy nhất. Và mọi chương trình đều có ít nhất một chức năng. Mỗi chương trình ở Bài 1 chỉ có một hàm tên là chủ yếu. Bài 9 cung cấp cái nhìn tổng quan chi tiết hơn về các chức năng. Hiện tại, chỉ cần lưu ý rằng một hàm bao gồm một số câu lệnh liên quan để thực hiện một tác vụ cụ thể.

Khi bạn khám phá các chương trình C++ khác nhau, bạn sẽ liên tụcđối mặt với lời nói trống rỗng. Chương trình sử dụng từ trống rỗngđể chỉ ra rằng một hàm không trả về một giá trị hoặc không có giá trị nào được truyền vào nó. Ví dụ: nếu bạn đang sử dụng môi trường MS-DOS hoặc UNIX, chương trình có thể chấm dứt và trả về giá trị trạng thái cho hệ điều hành có thể được xác minh bằng tệp lệnh. Các tệp bó MS-DOS kiểm tra trạng thái đầu ra của chương trình bằng lệnh IF ERRORLEVEL. Ví dụ: giả sử một chương trình có tên PAYROLL. EXE thoát với một trong các giá trị trạng thái đầu ra sau tùy thuộc vào kết quả xử lý:

Bên trong tệp bó MS-DOS, bạn có thể kiểm tra đầu ra của chương trình bằng lệnh IF ERRORLEVEL:

LƯƠNG BỔNG

NẾU LỖI 0 NẾU KHÔNG LỖI 1 GOTO THÀNH CÔNG
NẾU LỖI 1 NẾU KHÔNG CÓ LỖI 2 GOTO NO_FILE
NẾU LỖI 2 NẾU KHÔNG CÓ LỖI 3 GOTO NO_PAPER
REM Các lệnh khác theo sau

Hầu hết các chương trình C++ đơn giản mà bạn tạo trong cuốn sách này không trả về kết quả trạng thái cho hệ điều hành. Vì vậy bạn phải đặt từ trống rỗng trước chủ yếu như sau:

khoảng trống chính (void) //- ——-> Chương trình không trả về giá trị

Trong các bài học sau, bạn sẽ biết rằng chương trình của bạn có thể sử dụng thông tin (chẳng hạn như tên tệp) mà người dùng cung cấp trên dòng lệnh khi họ chạy chương trình. Nếu chương trình không sử dụng thông tin dòng lệnh thì bạn nên đặt từ trống rỗng bên trong dấu ngoặc đơn sau chủ yếu như sau:

khoảng trống chính( vô hiệu) //———————-> Chương trình không sử dụngđối số dòng lệnh

Khi các chương trình của bạn trở nên phức tạp hơn, chúng có thể trả về các giá trị cho hệ điều hành hoặc sử dụng các tham số dòng lệnh. Tuy nhiên bây giờ chỉ cần sử dụng vô hiệu hóa toán tử với chủ yếu như được hiển thị trong chương trình này.

QUAN ĐIỂM VỀ NHÓM ĐIỀU HÀNH ( )

Khi chương trình của bạn trở nên phức tạp hơn, sẽ có một tập hợp câu lệnh mà máy tính phải thực thi với số lần nhất định và một tập hợp câu lệnh khác mà máy tính phải thực thi nếu đáp ứng một điều kiện nhất định. Trong trường hợp đầu tiên, máy tính có thể thực hiện cùng một bộ câu lệnh 100 lần để cộng điểm kiểm tra cho 100 học sinh. Trong trường hợp thứ hai, máy tính có thể hiển thị một thông báo nếu tất cả học sinh vượt qua bài kiểm tra và một thông báo khác nếu một hoặc nhiều học sinh trượt. Trong các chương trình C++, bạn sẽ sử dụng dấu ngoặc nhọn phải và trái () để nhóm các câu lệnh liên quan. Trong các chương trình đơn giản được trình bày trong một số bài học đầu tiên của cuốn sách, các ký hiệu này nhóm các câu lệnh tương ứng với các câu lệnh trong chương trình chính của bạn.

CÁCH SỬ DỤNG coutĐỂ HIỂN THỊ ĐẦU RA TRÊN MÀN HÌNH

Tất cả các chương trình C++ bạn đã tạo trong Bài 1 đều in các thông báo trên màn hình. Để hiển thị thông báo, các chương trình được sử dụng cout và gấp đôi dấu nhỏ hơn (<<), как показано ниже:

cout<< «Привет, C++!»;

Từ coutđại diệnluồng đầu ra,mà C++ gán cho thiết bị đầu ra tiêu chuẩn của hệ điều hành. Theo mặc định, hệ điều hành gán thiết bị đầu ra tiêu chuẩn cho màn hình hiển thị. Để in thông báo ra màn hình, bạn chỉ cần sử dụng ký hiệu nhỏ hơn gấp đôi (gọi là toán tử chèn) với luồng đầu racout.Trong Bài học 3, bạn sẽ biết rằng bạn có thể sử dụng toán tử chèn để truyền các ký hiệu, số và các ký tự khác vào màn hình.

Xem luồng đầu ra cout

Bạn đã biết rằng các chương trình C++ sử dụng cout luồng đầu ra để hiển thị thông báo trên màn hình. Khi sử dụng cout để hiển thị thông báo, hãy coi cout như một dòng ký tự mà hệ điều hành hiển thị trên màn hình. Nói cách khác, thứ tự chương trình của bạn gửi các ký tự tới cout sẽ xác định thứ tự các ký tự sẽ xuất hiện trên màn hình. Ví dụ: đối với các câu lệnh chương trình sau:

cout<< «Это сообщение появляется первым,»;
cout<< » а за ним следует настоящее сообщение.»;

Hệ điều hành xuất ra luồng ký tự như sau:

Thông báo này xuất hiện đầu tiên, tiếp theo là thông báo thực tế.

Toán tử chèn (<<) называется так, потому что позволяет вашей программе вставлять символы в выходной поток.

Bạn đã biết rằng luồng đầu ra là cout mặc định để phù hợp với màn hình của bạn. Nói cách khác, khi chương trình của bạn gửi đầu ra tới cout,đầu ra xuất hiện trên màn hình. Tuy nhiên, bằng cách sử dụng các toán tử chuyển hướng đầu ra của hệ điều hành, bạn có thể gửi đầu ra của chương trình tới máy in hoặc tới một tệp. Ví dụ: lệnh sau hướng dẫn MS-DOS chuyển hướng đầu ra của chương trình FIRST.EXE tới máy in thay vì tới màn hình:

C:\>FIRST>PRN

Như bạn sẽ học ở Bài 3, sử dụng cout Trong C++ bạn có thể in các ký tự, số nguyên chẳng hạn như 1001 và số dấu phẩy động chẳng hạn như 3.12345. Trong Bài 8, bạn sẽ biết rằng trong C++ cũng có một luồng đầu vào được gọi là cin, mà chương trình của bạn có thể sử dụng để đọc đầu vào bàn phím.

NHỮNG GÌ BẠN CẦN BIẾT

Bài học này thảo luận về một số vấn đề phổ biến mà bạn sẽ gặp phải trong các chương trình C++. Trong Bài 3, bạn sẽ học cách sử dụng tìm kiếm ký tự đầu ra, số nguyên và giá trị dấu phẩy động. Bạn cũng sẽ học cách định dạng đầu ra. Trước khi học Bài 3, hãy đảm bảo bạn đã nắm vững các khái niệm cơ bản sau:

  1. Hầu hết các chương trình C++ đều bắt đầu bằng toán tử # bao gồm, hướng dẫn trình biên dịch đưa nội dung của tệp tiêu đề nhất định vào chương trình.
  2. Tệp tiêu đề chứa các định nghĩa do trình biên dịch cung cấp mà chương trình của bạn có thể sử dụng.
  3. Tệp nguồn có thể bao gồm nhiều câu lệnh; nhà điều hành khoảng trống chính(void) cho biết sự bắt đầu của chương trình chính, chứa câu lệnh chương trình đầu tiên được thực thi.
  4. Khi chương trình của bạn trở nên phức tạp hơn, bạn sẽ nhóm các câu lệnh liên quan thành các phần nhỏ, dễ quản lý được gọi là hàm. Nhóm các câu lệnh chương trình sử dụng dấu ngoặc nhọn phải và trái ().
  5. Hầu hết các chương trình C++ đều sử dụng luồng đầu ra coutđể hiển thị thông tin trên màn hình; tuy nhiên, bằng cách sử dụng toán tử chuyển hướng I/O của hệ điều hành, bạn có thể chuyển hướng đầu ra cout vào một tập tin, một thiết bị (chẳng hạn như máy in) hoặc thậm chí biến nó thành đầu vào của một chương trình khác.

Cho đến nay, chúng ta đã viết các chương trình bằng một mã duy nhất, không thể phân chia về mặt chức năng. Thuật toán của chương trình được chứa trong hàm chính và không có hàm nào khác trong chương trình. Chúng tôi đã viết các chương trình nhỏ nên không cần phải khai báo các hàm của mình. Để viết các chương trình lớn, kinh nghiệm cho thấy rằng sử dụng các hàm sẽ tốt hơn. Chương trình sẽ bao gồm các đoạn mã riêng biệt, một đoạn mã riêng biệt là một hàm. Riêng biệt, vì công việc của một chức năng riêng biệt không phụ thuộc vào công việc của bất kỳ chức năng nào khác. Nghĩa là, thuật toán trong mỗi hàm có đầy đủ chức năng và độc lập với các thuật toán khác trong chương trình. Khi bạn viết một hàm, nó có thể dễ dàng được chuyển sang các chương trình khác. Hàm (trong lập trình) là một đoạn mã hoặc thuật toán được triển khai bằng một số ngôn ngữ lập trình nhằm mục đích thực hiện một chuỗi thao tác nhất định. Vì vậy, các hàm cho phép bạn tạo một chương trình theo mô-đun, nghĩa là chia chương trình thành nhiều chương trình con (chức năng) nhỏ, chúng cùng nhau thực hiện nhiệm vụ. Một điểm cộng lớn khác của các chức năng là chúng có thể được tái sử dụng. Tính năng này cho phép bạn sử dụng lại mã đã viết một lần, điều này giúp giảm đáng kể số lượng mã chương trình!

Ngoài thực tế là C++ cung cấp khả năng khai báo các hàm của nó, bạn cũng có thể sử dụng các hàm được xác định trong các tệp tiêu đề tiêu chuẩn của ngôn ngữ lập trình C++. Để sử dụng hàm được xác định trong tệp tiêu đề, bạn cần đưa nó vào. Ví dụ: để sử dụng hàm nâng lũy ​​thừa của một số nhất định, bạn cần bao gồm tệp tiêu đề và chạy hàm pow() trong phần thân chương trình. Hãy phát triển một chương trình trong đó chúng ta sẽ chạy hàm pow().

// inc_func.cpp: Xác định điểm vào cho ứng dụng bảng điều khiển. #include "stdafx.h" //hành động 1 - bao gồm tệp tiêu đề

// mã Code::Khối

// Mã Dev-C++

// inc_func.cpp: Xác định điểm vào cho ứng dụng bảng điều khiển. //hành động 1 - bao gồm tệp tiêu đề chứa các nguyên mẫu của các hàm toán học cơ bản #include int main(int argc, char* argv) ( float power = pow(3.14,2); //hành động 2 - chạy hàm nâng một số lên lũy thừa 0; )

Việc bao gồm các tệp tiêu đề được thực hiện như trong dòng 5, tức là chỉ thị tiền xử lý #include được khai báo, sau đó bên trong các ký tự<>tên của tập tin tiêu đề được viết. Khi bao gồm tệp tiêu đề, bạn có thể sử dụng chức năng này, đó là những gì được thực hiện trong dòng 9.Hàm pow() tăng một số 3.14 bình phương và gán kết quả thu được cho biến lũy thừa, trong đó
pow - tên hàm;
số 3,14 và 2 là đối số của hàm;

Tên hàm luôn được theo sau bởi dấu ngoặc đơn, trong đó các đối số được truyền cho hàm và nếu có nhiều đối số thì chúng được phân tách với nhau bằng dấu phẩy. Các đối số là cần thiết để các hàm truyền thông tin. Ví dụ: để bình phương số 3,14 bằng hàm pow(), bạn cần bằng cách nào đó cho hàm này biết đó là số nào và lũy thừa bao nhiêu để nâng nó lên. Đây chính xác là lý do tại sao các đối số hàm được phát minh, nhưng có những hàm trong đó đối số không được truyền; các hàm như vậy được gọi với dấu ngoặc đơn trống. Vì vậy, để sử dụng một hàm từ tệp tiêu đề C++ tiêu chuẩn, bạn cần thực hiện hai bước:

  1. Bao gồm tệp tiêu đề được yêu cầu;
  2. Khởi chạy chức năng mong muốn.

Ngoài việc gọi các hàm từ các tệp tiêu đề tiêu chuẩn, ngôn ngữ lập trình C++ còn cung cấp khả năng tạo các hàm của riêng bạn. Có hai loại hàm trong ngôn ngữ lập trình C++:

  1. Hàm không trả về giá trị
  2. Hàm trả về một giá trị

Các hàm không trả về giá trị sẽ không cung cấp bất kỳ phản hồi nào cho chương trình sau khi hoàn thành công việc của chúng. Chúng ta hãy xem cấu trúc khai báo các hàm như vậy.

// cấu trúc khai báo hàm không trả về giá trị void /*tên hàm*/(/*tham số hàm*/) // tiêu đề hàm ( // thân hàm)

Dòng 2 bắt đầu bằng từ dành riêng void là loại dữ liệu không thể lưu trữ bất kỳ dữ liệu nào. Kiểu dữ liệu void có nghĩa là hàm này không trả về bất kỳ giá trị nào. void không có công dụng nào khác và chỉ cần thiết để trình biên dịch có thể xác định loại hàm. Sau từ dành riêng void, tên của hàm được viết. Ngay sau tên hàm có hai dấu ngoặc đơn, một dấu mở và một dấu đóng. Nếu một hàm cần truyền một số dữ liệu thì các tham số của hàm được khai báo bên trong dấu ngoặc đơn, chúng được phân tách với nhau bằng dấu phẩy. Dòng 2 được gọi là tiêu đề hàm. Sau phần đầu hàm, hai dấu ngoặc nhọn được viết, bên trong có một thuật toán gọi là thân hàm. Hãy phát triển một chương trình trong đó chúng ta khai báo một hàm để tìm giai thừa và hàm này không được trả về một giá trị.

<= numb; i++) // цикл вычисления значения n! rezult *= i; // накапливаем произведение в переменной rezult cout << numb << "! = " << rezult << endl; // печать значения n! } int main(int argc, char* argv) { int digit; // переменная для хранения значения n! cout << "Enter number: "; cin >> chữ số; faktorial(digit);//khởi động chức năng tìm hệ giai thừa("pause"); trả về 0; )

// mã Code::Khối

// Mã Dev-C++

sử dụng không gian tên std; // khai báo hàm tìm n! void faktorial(intnum) // tiêu đề hàm ( int rezult = 1; // khởi tạo biến rezult với giá trị 1 for (int i = 1; i<= numb; i++) // цикл вычисления значения n! rezult *= i; // накапливаем произведение в переменной rezult cout << numb << "! = " << rezult << endl; // печать значения n! } int main(int argc, char* argv) { int digit; // переменная для хранения значения n! cout << "Enter number: "; cin >> chữ số; faktorial(digit);//chạy hàm tìm giai thừa 0; )

Sau khi đã bao gồm tất cả các tệp tiêu đề cần thiết, bạn có thể khai báo một hàm để tìm giai thừa. Khi khai báo một hàm, chúng ta muốn nói đến việc chọn tên hàm, xác định các tham số của hàm và viết thuật toán là phần thân của hàm . Sau khi hoàn thành các bước này, chức năng có thể được sử dụng trong chương trình. Vì hàm không trả về giá trị nên kiểu trả về phải là void . Tên hàm là faktorial, bên trong dấu ngoặc đơn khai báo biến số kiểu int. Biến này là tham số của hàm faktorial(). Vì vậy, tất cả các quảng cáo trong dòng 8 chúng cùng nhau tạo nên tiêu đề hàm. Các dòng 9 - 14 tạo thành phần thân của hàm faktorial(). Bên trong phần thân, dòng 10 khai báo biến rezult , biến này sẽ lưu trữ kết quả tìm n! Sau đó, ở dòng 11-12 Toán tử vòng lặp for đã được khai báo để tìm giai thừa. TRONG dòng 13 Toán tử cout được khai báo, với sự trợ giúp của nó, giá trị của giai thừa sẽ được in trên màn hình. Bây giờ hàm đã được khai báo, bạn có thể sử dụng nó. TRONG dòng 21 Hàm faktorial(digit) được khởi chạy, đối số được truyền bên trong dấu ngoặc của hàm, tức là giá trị chứa trong biến chữ số. Kết quả của chương trình (xem Hình 1).

Hình 1 - Các hàm trong C++

Như vậy, sau khi chạy chương trình, số 5 được nhập vào và chương trình tính được giá trị 120 là 5!.

Các hàm trả về giá trị trả về một kết quả cụ thể sau khi hoàn thành công việc của chúng. Các hàm như vậy có thể trả về giá trị của bất kỳ loại dữ liệu nào. Cấu trúc của các hàm trả về một giá trị sẽ hơi khác so với cấu trúc của các hàm được thảo luận trước đó.

// cấu trúc khai báo hàm trả về giá trị /*trả về kiểu dữ liệu*/ /*tên hàm*/(/*tham số hàm*/) // tiêu đề hàm ( // thân hàm return /*return value*/; )

Cấu trúc khai báo hàm hầu như không thay đổi, ngoại trừ hai dòng. Trong tiêu đề hàm, trước tiên bạn cần xác định kiểu dữ liệu trả về, đây có thể là kiểu dữ liệu int nếu bạn muốn trả về số nguyên hoặc kiểu dữ liệu float cho số dấu phẩy động. Nói chung, bất kỳ loại dữ liệu nào khác, tất cả đều phụ thuộc vào hàm sẽ trả về cái gì. Vì hàm phải trả về một giá trị nên phải cung cấp một cơ chế đặc biệt cho việc này, như trong dòng 5. Sử dụng từ dành riêng return, bạn có thể trả về một giá trị khi hàm hoàn thành. Tất cả những gì cần làm là chỉ định một biến chứa giá trị mong muốn hoặc một giá trị nào đó sau câu lệnh return. Kiểu dữ liệu giá trị trả về trong dòng 5 phải phù hợp với kiểu dữ liệu trong dòng 2. Chúng ta hãy làm lại chương trình tìm giai thừa để hàm faktorial() trả về giá trị giai thừa.

// struct_func.cpp: Xác định điểm vào cho ứng dụng console. #include "stdafx.h" #include <= numb; i++) // цикл вычисления значения n! rezult *= i; // накапливаем произведение в переменной rezult return rezult; // передаём значение факториала в главную функцию } int main(int argc, char* argv) { int digit; // переменная для хранения значения n! cout << "Enter number: "; cin >> chữ số; cout<< digit << "! = " << faktorial(digit) << endl;// запуск функции нахождения факториала system("pause"); return 0; }

// mã Code::Khối

// Mã Dev-C++

// struct_func.cpp: Xác định điểm vào cho ứng dụng console. #bao gồm sử dụng không gian tên std; // khai báo hàm tìm n! int faktorial(int tê) // tiêu đề hàm ( int rezult = 1; // khởi tạo biến rezult với giá trị 1 for (int i = 1; i<= numb; i++) // цикл вычисления значения n! rezult *= i; // накапливаем произведение в переменной rezult return rezult; // передаём значение факториала в главную функцию } int main(int argc, char* argv) { int digit; // переменная для хранения значения n! cout << "Enter number: "; cin >> chữ số; cout<< digit << "! = " << faktorial(digit) << endl;// запуск функции нахождения факториала return 0; }

Hàm faktorial() hiện có kiểu dữ liệu trả về là int vì n! là một số nguyên.B dòng 13 một câu lệnh return được khai báo sẽ trả về giá trị có trong biến rezult. TRONG dòng 21 Chúng tôi chạy hàm faktorial(), giá trị trả về của hàm này được gửi đến luồng đầu ra bằng toán tử cout. Người ta có thể viết nó như thế này: int fakt = faktorial(digit); - biến kiểu int Chúng ta gán giá trị trả về cho hàm faktorial(), sau đó biến fakt sẽ lưu giá trị n! . Kết quả của chương trình không thay đổi (xem Hình 2).

Nhập số: 5 5! = 120 Để tiếp tục, nhấn phím bất kỳ. . .

Hình 2 - Các hàm trong C++

Chúng ta đã xem xét hai loại hàm và việc khai báo hàm được thực hiện trong khu vực chương trình, sau khi bao gồm các tệp tiêu đề nhưng trước khi bắt đầu hàm main(). Có một số cách khai báo hàm (xem Hình 3).

Hình 3 - Các hàm trong C++

TRÊN Hình 3 hướng dẫn 4 cách khai báo hàm trong ngôn ngữ lập trình C++. Chúng ta hãy xem cấu trúc khai báo hàm trong một tệp, với hàm main. Các hàm có thể được khai báo theo hai vùng, trước hàm main(), sau hàm main(). Cho đến nay chúng ta đã khai báo các hàm trong một file, trước hàm main() - đây là cách đơn giản nhất.

// struct_func.cpp: Xác định điểm vào cho ứng dụng console. #include "stdafx.h" /*area 1 - khai báo hàm trước khi bắt đầu main(), nơi khai báo hàm; các hàm được khai báo trong vùng này không cần nguyên mẫu */ int main(int argc, char* argv) ( trả về 0; )

Nếu các hàm được khai báo trong vùng 1, trước hàm chính thì không cần có nguyên mẫu cho các hàm này. Phong cách lập trình tốt là khai báo các hàm sau main() . Chúng ta hãy xem cấu trúc của một khai báo hàm như vậy.

// struct_func.cpp: Xác định điểm vào cho ứng dụng console. #include "stdafx.h" // nơi khai báo nguyên mẫu hàm int main(int argc, char* argv) ( return 0; ) /*area 2 - khai báo hàm sau main() nơi khai báo hàm */

// mã Code::Khối

// Mã Dev-C++

// struct_func.cpp: Xác định điểm vào cho ứng dụng console. // nơi khai báo nguyên mẫu hàm int main(int argc, char* argv) ( return 0; ) /*area 2 - khai báo hàm sau main() nơi khai báo hàm */

Vùng khai báo hàm đã được chuyển xuống cuối chương trình, sau main() . Còn về phương thức khai báo hàm thì không có gì thay đổi. Nhưng vì các hàm được khai báo sau main() nên sẽ không thể sử dụng chúng, vì thứ tự khai báo đã thay đổi và đơn giản là hàm main() sẽ không thấy các hàm được khai báo sau. Vì vậy, để các hàm này hiển thị trong main(), cần có khái niệm về nguyên mẫu. Nguyên mẫu hàm là tiêu đề hàm được khai báo trước hàm main(). Và nếu bạn khai báo một nguyên mẫu hàm, thì hàm đó có thể được nhìn thấy trong main() .

// cú pháp khai báo nguyên mẫu /*hàm trả về kiểu dữ liệu*/ /*tên hàm*/(/*tham số hàm*/);

Cấu trúc của một khai báo nguyên mẫu rất giống với cấu trúc của một khai báo hàm. Hãy phát triển một chương trình xác định xem số có năm chữ số đã nhập có phải là số palindrome hay không. Bảng màu là một số hoặc văn bản đọc giống nhau ở cả bên trái và bên phải: 93939; 49094; 11311.

// palindrom_func.cpp: Xác định điểm vào cho ứng dụng bảng điều khiển. #include "stdafx.h" #include << "Enter 5zn-e chislo: "; // введите пятизначное число int in_number, out_number; // переменные для хранения введённого пятизначного числа cin >> << "Number " << out_number << " - palendrom" << endl; else cout<<"This is not palendrom"<

// mã Code::Khối

// Mã Dev-C++

// palindrom_func.cpp: Xác định điểm vào cho ứng dụng bảng điều khiển. #bao gồm sử dụng không gian tên std; bool palindrome5(int); // nguyên mẫu của hàm tìm palindrome của các số có 5 chữ số int main(int argc, char* argv) ( cout<< "Enter 5zn-e chislo: "; // введите пятизначное число int in_number, out_number; // переменные для хранения введённого пятизначного числа cin >>trong_số; out_number = in_number; // lưu số đã nhập vào biến out_number if (palindrom5(in_number)) // nếu hàm trả về true thì điều kiện là đúng, nếu không hàm sẽ trả về false - false cout<< "Number " << out_number << " - palendrom" << endl; else cout<<"This is not palendrom"<

TRONG dòng 7 một hàm nguyên mẫu để tìm bảng màu của các số có năm chữ số đã được công bố. Xin lưu ý rằng nguyên mẫu phải hoàn toàn khớp với tiêu đề hàm, nhưng vẫn có một số khác biệt. Ví dụ, nguyên mẫu không cần liệt kê tên tham số, chỉ cần khai báo kiểu dữ liệu của chúng là đủ. Bạn phải luôn đặt dấu chấm phẩy ở cuối phần khai báo nguyên mẫu. Mặt khác, khai báo nguyên mẫu giống như khai báo tiêu đề của một hàm. Nguyên mẫu phải được khai báo riêng cho từng chức năng. Biến out_number được sử dụng để lưu trữ tạm thời số đã nhập. TRONG dòng 16điều kiện của câu lệnh lựa chọn if chạy hàm palindrom5(). Đối số cho nó là biến in_number. hàm sẽ trả về giá trị kiểu bool, và nếu hàm trả về true thì điều kiện sẽ đúng, ngược lại sẽ là sai. Trước tiên, có thể gán giá trị được hàm trả về cho một biến nào đó, sau đó thay thế biến này vào điều kiện của câu lệnh lựa chọn if, nhưng điều này sẽ làm tăng mã chương trình lên một dòng. TRONG dòng 23 - 40 Hàm palindrom5() được khai báo, với một tham số mà qua đó một số có năm chữ số được truyền vào hàm. Các biến Balance1, Balance2, Balance4, Balance5 được khai báo trong dòng 25 và cần thiết để lưu trữ các chữ số của số có năm chữ số: thứ nhất, thứ hai, thứ tư, thứ năm (đánh số - từ phải sang trái). Ở các dòng 26, 29, 32, 35, thao tác tương tự được thực hiện - phần còn lại của phép chia. Phép chia số dư sẽ cắt một bit từ phải sang trái và lưu chúng vào các biến số Balance1, Balance2, Balance4, Balance5 tương ứng. Hơn nữa, phép toán còn lại của phép chia xen kẽ với phép toán của phép chia thông thường. Phép chia được thực hiện trong dòng 27, 30 , 33 và giảm số có năm chữ số đã nhập theo từng bước một chữ số. TRONG dòng 30 Phép chia làm giảm số đã nhập xuống hai chữ số cùng một lúc, vì số đó có năm chữ số và chữ số ở giữa không được chúng ta quan tâm, nó có thể là bất cứ thứ gì. TRONG dòng 36 - 39 một toán tử lựa chọn được khai báo if , so sánh các chữ số của một số có năm chữ số và nếu chúng tương ứng bằng nhau thì hàm sẽ trả về true , nếu không thì false . Kết quả của chương trình (xem Hình 4).

Nhập số 5zn-e: 12321 Số 12321 - palendrom Để tiếp tục, nhấn phím bất kỳ. . .

Hình 4 - Các hàm trong C++

Cho đến nay chúng ta đã khai báo các hàm trong cùng một tệp với chương trình chính, tức là nơi chứa hàm main(). Trong C++, có thể đặt các khai báo hàm trong một tệp riêng biệt, sau đó bạn sẽ cần đưa vào tệp đó các hàm, như trường hợp bao gồm các tệp tiêu đề tiêu chuẩn. Có hai cách:

  1. tạo một tệp *.cpp trong đó các hàm được khai báo;
  2. tạo các tệp *.cpp và *.h.

Phương pháp thứ hai là một phong cách lập trình tốt. Như vậy, nếu khai báo hàm ở file khác thì thực hiện theo cách 2. Chúng ta hãy làm lại chương trình tìm palindrome để việc khai báo hàm palindrom5() nằm trong một tệp *.cpp riêng biệt. Cần có tệp *.h để ẩn việc triển khai các hàm, tức là tệp *.h sẽ chứa các nguyên mẫu hàm. Sử dụng MVS Solution Explorer, tạo tệp *.h và gọi nó là palendrom.

// mã tập tin palendrom.h #ifndef palendrom #define palendrom bool palindrom5(int); // nguyên mẫu của hàm tìm palindrome của số có 5 chữ số #endif

Chỉ thị trong dòng 2,3,5 phải luôn được khai báo trong tệp nguyên mẫu hàm và nguyên mẫu hàm luôn được khai báo trong tệp *.h. Sau khi có chỉ thị bằng văn bản dòng 2,3, nhưng nguyên mẫu hàm được khai báo trước lệnh #endif. Dòng 4 khai báo nguyên mẫu của hàm palindrom5(). Việc khai báo hàm này nằm trong tệp palendrom.cpp, tệp này cũng được tạo trước đó bằng MVS Solution Explorer.

// nội dung của file palendrom.cpp #include "stdafx.h" #include "palendrom.h" bool palindrom5(int number) // hàm tìm palindrome của các số có 5 chữ số ( int Balance1, Balance2, Balance4, Balance5 ; // các biến lưu trữ kết quả trung gian Balance1 = số % 10; // biến số dư1 được gán số dư đầu tiên = số / 10; // giảm số đã nhập xuống một chữ số Balance2 = số % 10; // biến số dư2 được gán số dư thứ hai = số / 100; // giảm số đã nhập xuống hai chữ số số dư4 = số % 10; // biến số dư4 được gán số dư thứ tư = số / 10; // giảm số đã nhập xuống một chữ số số dư5 = số % 10; // biến số dư5 được gán phần còn lại thứ năm if ((balance1 == Balance5) && (balance2 == Balance4)) trả về true; // hàm trả về giá trị true nếu không trả về false; // hàm trả về giá trị false )

// mã Code::Khối

// Mã Dev-C++

// nội dung của tệp palendrom.cpp #include "palendrom.h" bool palindrom5(int number) // hàm tìm palindrome của các số có 5 chữ số ( int Balance1, Balance2, Balance4, Balance5; // các biến lưu trữ kết quả trung gian số dư1 = số % 10; // biến số dư1 được gán số dư đầu tiên = số / 10; // giảm số đã nhập xuống một chữ số số dư2 = số % 10; // biến số dư2 được gán số dư thứ hai = số / 100 ; // giảm số đã nhập xuống hai chữ số Balance4 = số % 10; // biến số dư4 được gán số dư thứ tư = số / 10; // giảm số đã nhập xuống một chữ số Balance5 = số % 10; // biến số dư5 được gán phần còn lại thứ năm if ((balance1 == Balance5) && (balance2 == Balance4)) return true; // hàm trả về giá trị true nếu không trả về false; // hàm trả về giá trị false )

Tệp palendrom.cpp chứa phần khai báo hàm palindrom5(). Vì tệp palendrom.cpp là một tệp thực thi (*.cpp là các tệp thực thi), nên cần phải bao gồm vùng chứa "stdafx.h" trong đó, như trong dòng 2. Để liên kết tệp nơi hàm palindrom5() được khai báo và tệp với nguyên mẫu của nó, hãy bao gồm tệp tiêu đề (tệp có nguyên mẫu), việc này được thực hiện trong dòng 3. Xin lưu ý rằng khi kết nối tệp chúng tôi đã tạo, dấu ngoặc kép được sử dụng và không lớn hơn hoặc nhỏ hơn dấu. Tất cả những gì còn lại là chạy hàm palindrom5() trong tệp thực thi chính func_palendrom.cpp .

// func_palendrom.cpp: Xác định điểm vào cho ứng dụng bảng điều khiển. #include "stdafx.h" #include << "Enter 5zn-e chislo: "; // введите пятизначное число int in_number, out_number; // переменные для хранения введённого пятизначного числа cin >>trong_số; out_number = in_number; // lưu số đã nhập vào biến out_number if (palindrom5(in_number)) // nếu hàm trả về true thì điều kiện là đúng, nếu không hàm sẽ trả về false - false cout<< "Number " << out_number << " - palendrom" << endl; else cout<<"This is not palendrom"<

// mã Code::Khối

// Mã Dev-C++

// func_palendrom.cpp: Xác định điểm vào cho ứng dụng bảng điều khiển. #bao gồm // bao gồm tệp tiêu đề, với nguyên mẫu hàm palindrom5() #include "palendrom.h" sử dụng không gian tên std; int main(int argc, char* argv) ( cout<< "Enter 5zn-e chislo: "; // введите пятизначное число int in_number, out_number; // переменные для хранения введённого пятизначного числа cin >>trong_số; out_number = in_number; // lưu số đã nhập vào biến out_number if (palindrom5(in_number)) // nếu hàm trả về true thì điều kiện là đúng, nếu không hàm sẽ trả về false - false cout<< "Number " << out_number << " - palendrom" << endl; else cout<<"This is not palendrom"<

TRONG dòng 6 chúng tôi đã bao gồm một tệp có nguyên mẫu của hàm palindrom5(), sau đó chúng tôi có thể sử dụng hàm này. Vì vậy, chúng tôi chia chương trình thành ba tệp:

  • tập tin dự án: func_palendrom.cpp
  • tập tin tiêu đề palendrom.h
  • tập tin thực thi palendrom.cpp

Chúng tôi liên kết tệp dự án với tệp tiêu đề và chúng tôi liên kết tệp tiêu đề với tệp thực thi, trong trường hợp đó tệp dự án sẽ thấy hàm palindrom5() và sẽ có thể chạy nó.

thẻ: Các hàm trong C, nguyên mẫu, mô tả, định nghĩa, gọi. Tham số hình thức và tham số thực tế. Đối số của hàm, truyền theo giá trị, truyền theo con trỏ. Giá trị trả về.

Giới thiệu

Chúng ta càng nghiên cứu C nhiều thì các chương trình càng trở nên lớn hơn. Chúng tôi thu thập tất cả các hành động vào một chức năng chính và sao chép các hành động tương tự nhiều lần, tạo ra hàng chục biến có tên duy nhất. Các chương trình của chúng ta ngày càng phình to và ngày càng khó hiểu, các nhánh ngày càng dài hơn.

Nhưng có một cách thoát khỏi tình huống này! Bây giờ chúng ta sẽ tìm hiểu cách tạo hàm trong C. Thứ nhất, các hàm sẽ giúp tách mã trùng lặp thành các chương trình con riêng biệt, thứ hai, chúng sẽ giúp chia chương trình thành các phần một cách hợp lý và thứ ba, các hàm trong C có nhiều tính năng liên quan đến chúng sẽ cho phép sử dụng các phương pháp tiếp cận mới để cấu trúc ứng dụng.

Hàm là một phần được đặt tên của chương trình và có thể được gọi lặp đi lặp lại từ một phần khác của chương trình (trong đó hàm hiển thị). Một hàm có thể nhận một số đối số cố định hoặc thay đổi hoặc có thể không có đối số. Một hàm có thể trả về một giá trị hoặc để trống (void) và không trả về gì cả.

Chúng ta đã làm quen với nhiều hàm và biết cách gọi chúng - đây là các hàm của thư viện stdio, stdlib, string, conio, v.v. Hơn nữa, main cũng là một hàm. Nó khác với những cái khác chỉ ở chỗ nó là điểm vào khi khởi chạy ứng dụng.
Một hàm trong C được định nghĩa trong ngữ cảnh toàn cục. Cú pháp hàm: (, ...) ( )

Ví dụ đơn giản nhất là hàm lấy số thực và trả về bình phương của số này

#bao gồm #bao gồm float sqr(float x) ( float tmp = x*x; return tmp; ) void main() ( printf("%.3f", sqr(9.3f)); getch(); )

Bên trong hàm sqr, chúng ta đã tạo một biến cục bộ được gán giá trị của đối số. Số 9,3 được truyền làm đối số cho hàm. Từ dịch vụ return trả về giá trị của biến tmp. Bạn có thể viết lại hàm như sau:

Float sqr(float x) ( return x*x; )

Trong trường hợp này, phép nhân sẽ được thực hiện trước, sau đó giá trị sẽ được trả về. Nếu hàm không trả về bất cứ thứ gì thì kiểu trả về sẽ là void. Ví dụ: hàm in bình phương của một số:

Void printSqr(float x) ( printf("%d", x*x); return; )

trong trường hợp này, return có nghĩa là thoát khỏi hàm. Nếu hàm không trả về bất cứ thứ gì thì không cần phải viết return. Sau đó, hàm sẽ hoàn thành việc hoàn thành và quyền điều khiển sẽ quay trở lại hàm gọi.

Void printSqr(float x) ( printf("%d", x*x); )

Nếu hàm không có đối số thì dấu ngoặc đơn sẽ để trống. Bạn cũng có thể viết từ void:

Void printHelloWorld() ( printf("Xin chào thế giới"); )

tương đương

Void printHelloWorld(void) ( printf("Xin chào thế giới"); )

Các tham số chính thức và thực tế

Khi khai báo một hàm, các tham số hình thức sẽ được chỉ định, sau đó các tham số này sẽ được sử dụng trong chính hàm đó. Khi gọi một hàm, chúng ta sử dụng các tham số thực tế. Các tham số thực tế có thể là các biến thuộc bất kỳ loại hoặc hằng số phù hợp nào.

Ví dụ: giả sử có một hàm trả về bình phương của một số và một hàm tính tổng hai số.

#bao gồm #bao gồm // Các tham số chính thức có tên a và b // sử dụng chúng, chúng ta truy cập các đối số được truyền bên trong hàm int sum(int a, int b) ( return a+b; ) float Square(float x) ( return x*x; ) void main() ( //Các tham số thực tế có thể có bất kỳ tên nào, kể cả không có tên int one = 1; float two = 2.0; // Truyền biến, biến thứ hai được ép kiểu thành kiểu mong muốn printf("%d\n" , sum(one, two)); // Truyền các hằng số printf("%d\n", sum(10, 20)); // Truyền các hằng số sai kiểu, chúng sẽ tự động được chuyển đổi thành kiểu mong muốn printf ("%d\n ", sum(10, 20.f)); // Một biến kiểu số nguyên được chuyển đổi thành kiểu dấu phẩy động printf("%.3f\n", Square(one)); // Lệnh gọi hàm cũng có thể được sử dụng làm đối số, trả về giá trị mong muốn printf("%.3f\n", Square(sum(2 + 4, 3))); getch(); )

Xin lưu ý rằng việc truyền kiểu diễn ra ngầm định và chỉ khi có thể. Nếu một hàm nhận một số làm đối số thì nó không thể được truyền vào một chuỗi biến, ví dụ "20", v.v. Nói chung, tốt hơn là luôn sử dụng đúng loại hoặc chuyển loại rõ ràng sang loại mong muốn.
Nếu một hàm trả về một giá trị thì nó không cần phải được lưu trữ. Ví dụ: chúng tôi sử dụng hàm getch để đọc một ký tự và trả về ký tự đó.

#bao gồm #bao gồm void main() ( char c; do ( //Lưu giá trị trả về vào một biến c = getch(); printf("%c", c); ) while(c != "q"); //Kết quả trả về giá trị không được lưu getch(); )

Truyền đối số

Khi truyền đối số, chúng sẽ được sao chép. Điều này có nghĩa là bất kỳ thay đổi nào mà hàm thực hiện đối với các biến chỉ diễn ra trong hàm. Ví dụ

#bao gồm #bao gồm void thay đổi(int a) ( a = 100; printf("%d\n", a); ) void main() ( int d = 200; printf("%d\n", d); thay đổi(d) ; printf("%d", d); getch(); )

Các chương trình sẽ hiển thị
200
100
200
Rõ ràng là tại sao. Bên trong hàm, chúng ta làm việc với biến x, là bản sao của biến d. Chúng tôi thay đổi bản sao cục bộ, nhưng bản thân biến d không thay đổi. Sau khi thoát hàm, biến cục bộ sẽ bị hủy. Biến d sẽ không thay đổi theo bất kỳ cách nào.
Làm thế nào bạn có thể thay đổi biến? Để làm điều này, bạn cần truyền địa chỉ của biến này. Hãy viết lại hàm để nó chấp nhận một con trỏ kiểu int

#bao gồm #bao gồm void thay đổi(int *a) ( *a = 100; printf("%d\n", *a); ) void main() ( int d = 200; printf("%d\n", d); thay đổi (&d); printf("%d", d); getch(); )

Bây giờ chương trình xuất ra
200
100
100
Ở đây, một biến cục bộ cũng được tạo, nhưng vì địa chỉ đã được truyền nên chúng tôi đã thay đổi giá trị của biến d bằng địa chỉ của nó trong RAM.

Trong lập trình, phương thức truyền tham số đầu tiên được gọi là truyền theo giá trị, phương thức thứ hai - truyền qua con trỏ. Hãy nhớ một quy tắc đơn giản: nếu bạn muốn thay đổi một biến, bạn phải truyền một con trỏ tới biến đó cho hàm. Vì vậy, để thay đổi một con trỏ, bạn phải truyền một con trỏ tới một con trỏ, v.v. Ví dụ: hãy viết một hàm lấy kích thước của một mảng int và tạo nó. Thoạt nhìn, hàm này sẽ trông giống như thế này:

#bao gồm #bao gồm #bao gồm void init(int *a, unsigned size) ( a = (int*) malloc(size * sizeof(int)); ) void main() ( int *a = NULL; init(a, 100); if (a = = NULL) ( printf("ERROR"); ) else ( printf("OKAY..."); free(a); ) getch(); )

Nhưng hàm này sẽ xuất ra LỖI. Chúng tôi đã chuyển địa chỉ của biến. Bên trong hàm init, một biến cục bộ a được tạo để lưu trữ địa chỉ của mảng. Sau khi hàm thoát, biến cục bộ này bị hủy. Ngoài thực tế là chúng tôi không thể đạt được kết quả mong muốn, chúng tôi còn phát hiện ra rò rỉ bộ nhớ: bộ nhớ được cấp phát trên heap, nhưng không còn biến nào lưu trữ địa chỉ của vùng này nữa.

Để thay đổi một đối tượng, bạn phải truyền một con trỏ tới nó, trong trường hợp này là một con trỏ tới một con trỏ.

#bao gồm #bao gồm #bao gồm void init(int **a, unsigned size) ( *a = (int*) malloc(size * sizeof(int)); ) void main() ( int *a = NULL; init(&a, 100); if ( a == NULL) ( printf("ERROR"); ) else ( printf("OKAY..."); free(a); ) getch(); )

Bây giờ mọi thứ hoạt động như bình thường.
Một ví dụ tương tự khác. Hãy viết một hàm lấy một chuỗi làm đối số và trả về một con trỏ tới vùng bộ nhớ mà chuỗi này được sao chép vào.

#bao gồm #bao gồm #bao gồm #bao gồm char* initByString(const char *str) ( char *p = (char*) malloc(strlen(str) + 1); strcpy(p, str); return p; ) void main() ( char *test = initByString( "Xin chào thế giới!"); printf("%s", test); free(test); getch(); )

Không có rò rỉ bộ nhớ trong ví dụ này. Chúng tôi cấp phát bộ nhớ bằng hàm malloc, sao chép một chuỗi ở đó rồi trả về một con trỏ. Các biến cục bộ đã bị xóa, nhưng biến test lưu địa chỉ của một phần bộ nhớ trên heap, do đó nó có thể được xóa bằng hàm free.

Khai báo hàm và định nghĩa hàm. Tạo thư viện của riêng bạn

Trong C, bạn có thể khai báo một hàm trước khi định nghĩa nó. Một khai báo hàm, nguyên mẫu của nó, bao gồm giá trị trả về, tên hàm và kiểu đối số. Tên của các đối số có thể được bỏ qua. Ví dụ

#bao gồm #bao gồm // Nguyên mẫu hàm. Tên của các đối số không cần phải viết int Odd(int); int chẵn(int); void main() ( printf("if %d Odd? %d\n", 11, Odd(11)); printf("if %d Odd? %d\n", 10, Odd(10)); getch (); ) //Định nghĩa hàm int Even(int a) ( if (a) ( Odd(--a); ) else ( return 1; ) ) int Odd(int a) ( if (a) ( Even( - -a); ) khác ( trả về 0; ) )

Đây là một đệ quy hỗn hợp - hàm lẻ trả về 1 nếu số lẻ và 0 nếu số đó là số chẵn.

Thông thường phần khai báo hàm được đặt riêng trong tệp .h và định nghĩa hàm trong tệp .c. Do đó, tệp tiêu đề đại diện cho giao diện của thư viện và hiển thị cách làm việc với nó mà không cần đi sâu vào nội dung của mã.

Hãy tạo một thư viện đơn giản. Để thực hiện việc này, bạn sẽ cần tạo hai tệp - một tệp có phần mở rộng .h và đặt các nguyên mẫu hàm ở đó, tệp kia có phần mở rộng .c và đặt định nghĩa của các hàm này vào đó. Nếu bạn đang làm việc với IDE thì tệp .h phải được tạo trong thư mục Tệp Tiêu đề và các tệp mã trong thư mục Tệp Mã Nguồn. Đặt tên tệp là File1.h và File1.c
Hãy viết lại mã trước đó. Tệp tiêu đề File1.h sẽ trông như thế này

#ifndef _FILE1_H_ #define _FILE1_H_ int lẻ(int); int chẵn(int); #endif

Nội dung của file mã nguồn File1.c

#include "File1.h" int chẵn(int a) ( if (a) ( lẻ(--a); ) else ( return 1; ) ) int Odd(int a) ( if (a) ( chẵn(-- a); ) khác ( trả về 0; ) )

Chức năng chính của chúng tôi

#bao gồm #bao gồm #include "File1.h" void main() ( printf("if %d Odd? %d\n", 11, Odd(11)); printf("if %d Odd? %d\n", 10, lẻ(10)); getch(); )

Hãy xem xét các tính năng của từng tập tin. Tệp của chúng tôi chứa hàm chính, bao gồm các thư viện mà nó cần, cũng như tệp tiêu đề File1.h. Bây giờ trình biên dịch đã biết nguyên mẫu hàm, nghĩa là nó biết kiểu trả về, số lượng và kiểu đối số cũng như tên hàm.

Tệp tiêu đề, như đã nêu trước đó, chứa nguyên mẫu hàm. Các thư viện được sử dụng cũng có thể được đưa vào đây. Bảo vệ macro #define _FILE1_H_, v.v. được sử dụng để ngăn mã thư viện bị sao chép lại trong quá trình biên dịch. Những dòng này có thể được thay thế bằng một

#pragma một lần int lẻ(int); int chẵn(int);

Tệp mã nguồn File1.c bao gồm tệp tiêu đề của nó. Mọi thứ đều hợp lý và đơn giản như thường lệ. Trong các tệp tiêu đề, ngoài các nguyên mẫu hàm, người ta thường bao gồm các hằng số, thay thế macro và xác định các kiểu dữ liệu mới. Ngoài ra, trong các tệp tiêu đề, bạn có thể nhận xét rộng rãi về mã và viết ví dụ về cách sử dụng nó.

Truyền một mảng làm đối số

Như đã đề cập trước đó, tên mảng được thay thế bằng một con trỏ, do đó việc truyền mảng một chiều tương đương với việc truyền một con trỏ. Ví dụ: hàm nhận một mảng và kích thước của nó và in ra:

#bao gồm #bao gồm void printArray(int *arr, unsigned size) ( unsigned i; for (i = 0; i< size; i++) { printf("%d ", arr[i]); } } void main() { int x = {1, 2, 3, 4, 5}; printArray(x, 10); getch(); }

Trong ví dụ này, hàm có thể trông như thế này

Void printArray(int arr, unsigned size) ( unsigned i; for (i = 0; i< size; i++) { printf("%d ", arr[i]); } }

Tôi cũng xin nhắc bạn rằng quy tắc thay thế mảng bằng con trỏ là không đệ quy. Điều này có nghĩa là cần phải xác định kích thước của mảng hai chiều khi truyền

#bao gồm #bao gồm void printArray(int arr, unsigned size) ( unsigned i, j; for (i = 0; i< size; i++) { for (j = 0; j < 5; j++) { printf("%d ", arr[i][j]); } printf("\n"); } } void main() { int x = { { 1, 2, 3, 4, 5}, { 6, 7, 8, 9, 10}}; printArray(x, 2); getch(); }

Hoặc bạn có thể viết

#bao gồm #bao gồm void printArray(int (*arr), kích thước không dấu) ( unsigned i, j; for (i = 0; i< size; i++) { for (j = 0; j < 5; j++) { printf("%d ", arr[i][j]); } printf("\n"); } } void main() { int x = { { 1, 2, 3, 4, 5}, { 6, 7, 8, 9, 10}}; printArray(x, 2); getch(); }

Nếu mảng hai chiều được tạo động thì bạn có thể truyền con trỏ tới con trỏ. Ví dụ: một hàm lấy một mảng các từ và trả về một mảng các số nguyên bằng độ dài của mỗi từ:

#bao gồm #bao gồm #bao gồm #bao gồm #define SIZE 10 unsigned* getLengths(const char **words, unsigned size) ( unsigned *lengths = NULL; unsigned i; lengths = (unsigned*) malloc(size * sizeof(unsigned)); for (i = 0; i< size; i++) { lengths[i] = strlen(words[i]); } return lengths; } void main() { char **words = NULL; char buffer; unsigned i; unsigned *len = NULL; words = (char**) malloc(SIZE * sizeof(char*)); for (i = 0; i < SIZE; i++) { printf("%d. ", i); scanf("%127s", buffer); words[i] = (char*) malloc(128); strcpy(words[i], buffer); } len = getLengths(words, SIZE); for (i = 0; i < SIZE; i++) { printf("%d ", len[i]); free(words[i]); } free(words); free(len); getch(); }

Thay vì trả về một con trỏ tới một mảng, bạn có thể truyền một mảng cần điền vào

#bao gồm #bao gồm #bao gồm #bao gồm #define SIZE 10 void getLengths(const char **words, unsigned size, unsigned *out) ( unsigned i; for (i = 0; i< size; i++) { out[i] = strlen(words[i]); } } void main() { char **words = NULL; char buffer; unsigned i; unsigned *len = NULL; words = (char**) malloc(SIZE * sizeof(char*)); for (i = 0; i < SIZE; i++) { printf("%d. ", i); scanf("%127s", buffer); words[i] = (char*) malloc(128); strcpy(words[i], buffer); } len = (unsigned*) malloc(SIZE * sizeof(unsigned)); getLengths(words, SIZE, len); for (i = 0; i < SIZE; i++) { printf("%d ", len[i]); free(words[i]); } free(words); free(len); getch(); }

Đây là nơi kết thúc quá trình làm quen đầu tiên với các hàm: chủ đề rất lớn và được chia thành nhiều bài viết.