Xin chào, và chào mừng trở lại.
Trong bài giảng này, tôi muốn nói về một số lỗi phổ biến mà bạn sẽ mắc
phải khi lập trình trong c.
Một số lỗi trong số này bạn có thể quen thuộc với những
thử thách trước đây và bạn đã thực sự gặp phải những lỗi này,
nhưng đây là những loại lỗi phổ biến nhất.
Đầu tiên là rất, rất rõ ràng. Nó thiếu một dấu chấm phẩy.
Hãy nhớ rằng tất cả các câu lệnh trong c sẽ kết thúc bằng dấu chấm phẩy.
Nếu bạn không có nó ở đó, trình biên dịch sẽ phàn nàn.
Vì vậy, đặt sai dấu chấm phẩy hoặc thiếu hoàn toàn dấu chấm phẩy là
một lỗi thực sự phổ biến. Trong trường hợp này, chúng ta đang đặt nhầm dấu chấm phẩy.
Chúng tôi có một câu lệnh if. Chúng tôi đặt dấu chấm phẩy ở cuối câu lệnh if.
Và điều này thực sự khiến hoạt động của chương trình hoàn toàn khác.
Điều này thực sự sẽ biên dịch.
Khi bạn bỏ lỡ dấu chấm phẩy và thậm chí không có nó, nó sẽ không biên dịch.
Nhưng trong trường hợp này, giá trị của j sẽ luôn được đặt bằng 0
vì dấu chấm phẩy trên câu lệnh if đã được đặt.
Vì vậy, dấu chấm phẩy hoàn toàn hợp lệ để có nó sau câu lệnh if.
Nó thực sự đại diện cho câu lệnh null.
Và do đó, bạn không gặp lỗi bởi trình biên dịch,
nhưng điều này sẽ gây ra sự cố vì j sẽ không bao giờ được đặt thành 0.
Và loại lỗi này cũng có thể phổ biến trong lặp lại.
Khi bạn có một vòng lặp và bạn đặt dấu chấm
phẩy ở cuối vòng lặp for và sau đó bạn có thể có một dấu ngoặc, nơi
bạn không có dấu ngoặc vì bạn sẽ gặp lỗi nếu bạn có dấu ngoặc, rất phổ biến.
Một người khác đang nhầm lẫn toán tử bằng với toán tử bằng bằng.
Cụ thể đã đề cập rằng toán tử bằng
bằng không so sánh các chuỗi. Vì vậy, nếu bạn sử dụng equals khi so
sánh các chuỗi, điều đó không hợp lệ. Nó chỉ là để so sánh các tài liệu tham khảo.
Nhưng nếu bạn thực sự muốn gán một giá trị cho một biến và thay vào
đó sử dụng các dấu bằng bằng, bạn sẽ có một trình biên dịch.
Bây giờ nếu bạn cố gắng so sánh hai mục, chẳng hạn như
hai số nguyên bên trong câu lệnh if và thay vào đó bạn sử dụng
toán tử gán, bạn thực sự sẽ không gặp lỗi
trình biên dịch, nhưng biểu thức đó sẽ luôn đánh giá thành true.
Vì vậy, khi bạn sử dụng dấu bằng và bạn không sử dụng dấu
bằng bằng, điều này thường được thực hiện trong câu lệnh if while do, bên trong biểu thức Boolean.
Và điều này là hợp lệ ngoại trừ nó có tác dụng
gán cho một cái gì đó trái ngược với việc thực thi một cái gì đó.
Vì vậy, trong ví
dụ này, nếu chúng ta có nếu a bằng 2, nó sẽ gán 2 cho a.
Nó luôn được đặt thành true bởi vì đó là một câu nói đúng bởi vì bạn không
bao giờ thất bại khi thực hiện nhiệm vụ. Và vì vậy printf sẽ luôn chạy.
Những gì bạn thực sự muốn làm ở đây là nói nếu một bằng bằng với.
Vì vậy, nó rất phổ biến bằng cách sử dụng bằng trái ngược với bằng bằng
bằng và sau đó không có lỗi trình biên dịch.
Nếu bạn sử dụng dấu bằng bằng trong trường
hợp sai, bạn cũng có thể
có hành vi không mong muốn, nhưng bạn sẽ gặp
lỗi trình biên dịch nếu bạn sử dụng nó để gán không chính xác.
Nhưng hãy cẩn thận với điều này với các dấu bằng thay vì các dấu bằng bằng.
Bỏ qua khai báo nguyên mẫu.
Tôi đã đề cập rằng điều thực sự quan trọng là phải luôn khai báo các
hàm của bạn ở đầu tệp trước khi bạn sử dụng chúng.
Tuy nhiên, điều này không phải lúc nào cũng xảy ra và đó là sai lầm rất phổ biến.
Và thông thường, những gì sẽ xảy ra là bạn sẽ gặp lỗi khai báo ngầm
trong trình biên dịch.
Trong ví dụ này, nếu bạn có căn bậc hai được xác định muộn hơn
trong chương trình so với nơi bạn đang gọi nó hoặc trong một tệp khác
và bạn không khai báo nó một
cách rõ ràng, bạn sẽ có một số cảnh báo.
Trình biên dịch sẽ giả sử rằng hàm trả về một số nguyên.
Luôn an toàn nhất là bao gồm khai báo nguyên mẫu đó ở trên
cùng cho tất cả các hàm mà
bạn gọi, rõ ràng hoặc
ẩn ý bằng cách bao gồm tệp tiêu đề chính xác trong chương trình của bạn.
Nhưng khi bạn không bao gồm điều đó, những khai báo nguyên mẫu đó bạn
có thể có lỗi.
Không bao gồm tệp tiêu đề bao gồm định nghĩa cho một hàm thư viện
lập trình c đang được sử dụng trong chương trình.
Vì vậy, trong trường hợp này, bạn muốn sử dụng lại một số mã. Có thể bạn có hàm printf mà
bạn muốn hiển thị một số đầu ra, nhưng bạn không bao gồm tệp tiêu đề lib tiêu chuẩn.
Đó là một sai lầm. Và điều đó thường sẽ được trình biên dịch cho bạn biết.
Sẽ có vấn đề liên kết
với chức năng đó.
Vì vậy, trong trường hợp này, chúng tôi có câu trả lời kép bằng giá trị căn bậc hai 1.
Nếu chương trình này không bao gồm toán học. tệp tiêu đề, điều
này sẽ tạo ra lỗi căn bậc hai không được xác định.
Nó sẽ cố gắng liên kết các tệp đối tượng. Nó sẽ không có một phép toán. o.
Và nó sẽ nói, này, bạn đang gọi căn bậc hai, nhưng không có cách triển khai nào cho nó.
Vì vậy, hãy đảm bảo rằng bạn bao gồm các tiêu đề
chính xác cho tất cả các lệnh gọi hàm, đặc biệt là từ thư viện chuẩn.
Gây nhầm lẫn một hằng ký tự trong một chuỗi ký tự.
Vì vậy, ở đây nếu chúng ta có văn bản bằng một dấu ngoặc kép bên
trong, đó là một ký tự duy nhất được gán cho văn bản.
Nếu chúng ta có một biến có tên là văn bản và chúng ta gán trong
dấu ngoặc kép, đó là một con trỏ đến chuỗi ký tự.
Điều đó không hợp lệ cho một
ký tự.
Và điều này thực sự chúng ta đã nói về
các hằng số chuỗi và gán chúng cho các mảng ký tự.
Và làm thế nào bạn không thể làm điều đó với các dấu bằng và
bạn phải thực sự làm chúng với bản sao.
Trong trường hợp này, khi chúng tôi nói văn bản bằng a, nó đang gán một con
trỏ và điều này thực sự cũng không hợp
lệ và hãy xem những gì bạn sẽ phải làm là bạn phải
làm sao văn bản bằng a hoặc sao chép nếu bạn không Tôi không muốn chỉ
định nó trực tiếp như vậy.
Nhưng bạn có được ý chính.
Sử dụng ký tự bên trong dấu ngoặc kép so với ký tự bên trong
dấu ngoặc kép hoàn toàn khác, ký tự so với chuỗi.
Trong trường hợp đầu tiên, văn bản thường được khai báo là một biến char.
Và trong trường hợp thứ hai, nó nên được khai báo là kiểu con trỏ tới một char.
Và nếu bạn muốn gán một giá trị cho con trỏ đó
khác với chính con trỏ đó, bạn phải hủy tham chiếu nó.
Điều này thực sự không chính xác vì nếu đó là một
con trỏ thay vì chỉ định địa chỉ, bạn đang gán cho nó một chuỗi, vì vậy điều
đó không có ý nghĩa.
Sử dụng sai giới hạn cho một mảng, ngoại lệ mảng nằm ngoài giới hạn.
Ở đây, chúng tôi đang khai báo một mảng số nguyên có kích thước 100 và sau
đó là một vài biến I và tổng với chỉ một số được khởi tạo.
Và chúng tôi đi qua vòng lặp của chúng tôi, chúng tôi nói với I bằng 1 Tôi nhỏ hơn bằng 100.
Điều đó không chính xác vì kích thước của một trăm có nghĩa là có
một trăm phần tử trong mảng. Nhưng các mảng được dựa trên số không.
Vì vậy, phần tử đầu tiên là số không. Chỉ số tối đa mà bạn
có thể gán hoặc truy cập trong một mảng là 99.
Điều này sẽ nhỏ hơn bằng.
Vì vậy, bạn sẽ có một sai lầm ngoài giới hạn ở đây.
Đây không phải là một chỉ
số con hợp lệ vì vòng lặp này sẽ đi đến 100.
Nó cũng có thể không chính xác vì bạn đang bắt đầu từ 1.
Nếu bạn thực sự muốn phần tử đầu tiên của mảng này, bạn sẽ bắt đầu từ 0.
Quên dành một vị trí bổ sung trong một mảng cho
ký tự null kết thúc của một chuỗi cũng
là một vấn đề phổ biến.
Khi khai báo mảng ký tự của bạn, chúng cần phải đủ lớn để chứa ký tự kết thúc một mình.
Đây là lý do tại sao tôi khuyên bạn không
nên đặt kích thước vào một mảng khi bạn tạo nó nếu bạn đang khởi tạo nó.
Bạn sẽ chỉ đặt kích thước vào đó nếu bạn không khởi tạo nó.
Nếu bạn đang tạo khởi tạo trên cùng một dòng, hãy để c thực hiện công
việc cho bạn, nó sẽ tự động đặt đúng kích thước và nó sẽ bao gồm dấu chấm dứt null đó.
Vì vậy, ví dụ, nếu bạn có một chuỗi ký tự được gọi
là hello, đây là hơn năm vị trí bộ nhớ, nó là sáu vì dấu chấm dứt rỗng ở cuối.
Đừng quên về kích thước của các mảng của bạn.
Đây là một vấn đề phổ biến với các con trỏ mà chúng ta chưa thảo luận nhiều về nó,
nhưng tôi chỉ muốn đề cập đến vì nó rất phổ biến.
Trong con trỏ, khi bạn muốn truy cập hoặc thậm chí chỉ dẫn, khi
bạn muốn truy cập một cái gì
đó bằng con trỏ, bạn phải sử dụng dấu gạch ngang lớn hơn biểu tượng.
Nó được sử dụng khi bạn đang truy cập một phần tử con trỏ.
Vì vậy, nếu bạn có một con trỏ trỏ đến một cấu trúc, đó là cách bạn truy cập nó.
Nếu bạn có một cấu trúc, nó không phải
là một con trỏ, thì bạn truy cập nó bằng cách sử dụng toán tử dấu chấm.
Rất nhiều lần toán tử dấu chấm này và dấu gạch ngang này sau đó lớn hơn
được sử dụng không chính xác.
Dấu chấm cho các con trỏ không phải con trỏ, con trỏ gạch ngang lớn hơn, điều này sẽ trở nên
rõ ràng hơn trong nhiều ví dụ của chúng tôi.
Bỏ qua dấu và trước các biến không phải là con trỏ trong lệnh gọi scanf.
Vì vậy, hãy nhớ cuộc gọi scanf của chúng ta mong đợi một con trỏ như một đối số thứ hai và
điều đó có nghĩa là một địa chỉ.
Khi chúng ta khai báo một kiểu dữ liệu là một biến kiểu int, đó không phải
là một con trỏ.
Vì vậy, để cho phép scanf lưu trữ dữ liệu đó trong biến int của chúng ta, chúng ta phải chuyển nó vào
ký hiệu và để nói rằng đó là một địa chỉ.
Vì vậy, điều này là
không chính xác, không có ký hiệu và trước số và quét f vì
đối số thứ hai không hợp lệ. Lần duy nhất bạn không có dấu và là nếu bạn đang sử dụng một con
trỏ, chẳng hạn như một mảng ký tự.
Tất cả các đối số xuất hiện sau chuỗi định dạng và scanf phải là con trỏ.
Sử dụng một biến con trỏ trước khi nó được khởi tạo.
Vì vậy, đây là một ví dụ về việc tạo một con trỏ và sau đó cố gắng gán cho nó.
Và đây là nhiệm vụ chính xác mà bạn đang chỉ định một giá trị mà bạn hủy tham chiếu nó.
Nhưng những gì chúng tôi chưa làm ở đây là chúng tôi đã khởi tạo con trỏ để thực sự có bất kỳ
bộ nhớ nào được cấp phát cho nó và bạn
không thể làm điều này trong c.
Bạn chỉ có thể áp dụng toán tử
hướng dẫn, là dấu hoa thị trước cho
một điểm hoặc biến sau khi bạn đã đặt biến trỏ đến đâu đó.
Vì vậy, nó phải được trỏ đến một nơi nào đó, ngay bây giờ nó rỗng, nó không trỏ đến bất cứ đâu vì bạn không
cấp phát bất kỳ bộ nhớ nào.
Vì vậy con trỏ char không bao giờ được đặt để trỏ tới bất cứ thứ gì nên việc gán không có ý nghĩa.
Điều này thực sự sẽ gây ra lỗi phân đoạn.
Một lỗi phổ biến khác là bỏ qua câu lệnh break ở cuối trường hợp trong câu lệnh switch.
Nếu break không được bao gồm ở cuối một trường hợp, thì việc thực thi được tiếp tục cho trường hợp tiếp theo.
Vì vậy, đây là những gì tôi đã đề cập nơi bạn có một trường hợp, nó được đánh giá.
Và nếu bạn không có bước đột nhập đó, nó sẽ chuyển ngay sang
trường hợp tiếp theo và sẽ thực thi mã bên trong trường hợp tiếp theo đó.
Vì vậy, bạn luôn muốn có khoảng nghỉ bên trong các câu lệnh tình huống của mình.
Đôi khi bạn muốn theo dõi từng trường hợp khác và họ làm điều
tương tự, trong trường hợp đó bạn sẽ không
có bất cứ thứ gì bên trong câu lệnh trường hợp.
Chèn dấu chấm phẩy vào cuối định nghĩa bộ tiền xử lý.
Định nghĩa tiền xử lý nhớ bắt đầu bằng con
số, ký hiệu bảng Anh. Bộ tiền xử lý được chạy trước trình biên dịch
thường để tối ưu hóa.
Cú pháp chính xác cho các định nghĩa về bộ xử lý trước là không bao gồm dấu chấm phẩy.
Tuy nhiên, ở c bạn hãy tập thói quen luôn đặt dấu chấm phẩy sau mọi thứ.
Nhưng bạn phải nhớ rằng nếu bạn xác định một số dữ liệu hằng số mà bạn
không cần dấu chấm phẩy, thì điều này không chính xác.
Điều này sẽ dẫn đến lỗi cú pháp nếu nó
được sử dụng một biểu thức như vậy.
như thế. Vì vậy, nếu bạn thực sự cố gắng
sử dụng nó để thấy rằng nó sẽ ổn nếu có dấu chấm phẩy đó ở cuối.
Nhưng khi bộ tiền xử lý chạy, nó sẽ chèn chính xác những gì có trong đó được xác định.
Vì vậy, nó sẽ phân phát vào cuối dấu hai chấm dữ liệu 999.
Đây là những gì trình biên dịch sẽ nhìn thấy nó và nó sẽ thực sự gây ra lỗi,
đó sẽ là lỗi cú pháp.
Việc bỏ qua dấu ngoặc đơn hoặc dấu ngoặc kép đóng trên bất kỳ
câu lệnh nào, rất phổ biến. Vì vậy, điều này cũng liên quan trực tiếp
đến dấu ngoặc, có một dấu ngoặc nhọn bắt đầu và sau đó không kết thúc dấu ngoặc nhọn, điều
tương tự với dấu ngoặc đơn. Trong trường hợp này, chúng
ta có hai hoặc ba dấu ngoặc đơn bắt đầu bên trái, nhưng chúng ta
chỉ có hai dấu ngoặc kết thúc. Chúng tôi thiếu một dấu ngoặc đơn bên phải kết thúc.
Đó sẽ là một lỗi cú pháp mà trình biên dịch sẽ tìm thấy.
Vì vậy, khi bạn đang sử dụng tính năng nhúng trong dấu ngoặc đơn để phân tách từng phần của một phương trình,
nó sẽ tạo ra một dòng mã dễ đọc hơn.
Bạn muốn sử dụng dấu ngoặc đơn.
Tuy nhiên, bạn muốn đảm bảo rằng tất cả chúng đều
khớp với bạn khi bắt đầu một dấu ngoặc đơn, bạn phải có một dấu ngoặc đóng kết thúc, giống với dấu ngoặc nhọn.
Bạn bắt đầu một dấu ngoặc nhọn, nó phải có một dấu ngoặc nhọn kết thúc.
Vì vậy, hoặc bạn có quá nhiều hoặc bạn có quá
ít nhưng trình biên dịch sẽ phàn nàn, và điều này rất, rất phổ biến.
Vì vậy, dòng thứ hai ở đây cũng thiếu dấu ngoặc kép đóng, câu lệnh in này.
Chúng tôi không có một trích dẫn kết thúc.
Trình biên dịch sẽ phàn nàn về điều đó.
Cả hai điều này sẽ tạo ra một lỗi biên dịch.
Đôi khi, mặc dù trình biên dịch rất sai lầm vì nó thực
sự không biết lỗi xảy ra ở đâu. Nó cho rằng lỗi có thể đã xảy ra ở dòng tiếp theo.
Vì vậy, dòng mà nó cho bạn biết lỗi có thể gây hiểu nhầm.
Vì vậy, tùy thuộc vào việc trình biên
dịch sử dụng dấu ngoặc đơn hoặc dấu ngoặc kép trên dòng tiếp
theo, nó sẽ thực sự hoàn thành biểu thức đó.
Vì vậy, nó sẽ chuyển lỗi xuống dòng khác.
Và đó là những gì nó sẽ phàn nàn và nói rằng đó là lỗi ở đâu. Nhưng lỗi thực
tế cao hơn ở trên nơi bạn định đặt nó.
Đây là một số lỗi phổ biến mà tôi thấy rất nhiều lập trình viên
c mắc phải.
Chúng rất dễ sửa chữa. Và nếu bạn hiểu chúng và
nghiên cứu điều này,
bạn sẽ biết không mắc phải chúng. Bạn có thể sử dụng chúng
như một người mới bắt đầu, nhưng khi bạn viết mã ngày càng nhiều
và thực hành nhiều hơn, bạn sẽ nhận ra, này, tôi quên dấu ngoặc, tôi
quên dấu ngoặc, tôi đã không sử dụng dấu bằng và dấu bằng một cách chính xác , Tôi đang
sử dụng con trỏ không chính xác, tôi không cấp phát bất kỳ bộ nhớ nào.
Tất cả những điều này sẽ đến bản chất thứ hai hơn. Cảm ơn bạn.