Một lập trình viên C nên biết gì? [đóng cửa]


11

Một số khái niệm / kỹ thuật / tính năng ngôn ngữ mà mọi lập trình viên C giỏi nên biết / nhận biết (loại trừ kỹ thuật phần mềm nói chung và tương tự và chỉ tập trung vào công cụ cụ thể C). Tôi muốn biết để tôi có thể điền vào một số lỗ hổng có thể có trong kiến ​​thức C của tôi.


9
Bắt đầu với các câu hỏi C của Stack Overflow và xem liệu có bất cứ điều gì bạn không biết.
chrisaycock

3
Lập trình viên AC có lẽ nên biết điều đó2 + 2 = 4
Edward Strange

21
Họ nên biết về một cửa hàng bán giày chống đạn.
Adam Crossland

1
Có hàng trăm cuốn sách viết về chủ đề này. Câu hỏi của bạn thực sự khá mơ hồ. Bạn sẽ phải cụ thể hơn để có được câu trả lời xác thực mà không chỉ là một danh sách các công cụ. Và nhìn thấy các câu trả lời được nêu ra từ câu hỏi này, tôi sẽ nghĩ rằng nó cần phải được làm lại hoặc đóng lại.
Walter

2
Ngôn ngữ lập trình khác?
Muhammad Alkarouri

Câu trả lời:


19

Cụ thể với C? Ngoài các cấu trúc tiêu chuẩn phổ biến cho hầu hết các ngôn ngữ thủ tục, tôi phải nói:

  • (ab) sử dụng bộ tiền xử lý
  • trình liên kết vs trình biên dịch
  • Con trỏ Con trỏ Con trỏ!
  • Làm thế nào mảng là con trỏ là mảng
  • Cách chuỗi C hoạt động và cách chúng cũng là con trỏ và mảng
  • Làm thế nào xấu sử dụng chuỗi C có thể dẫn đến tràn bộ đệm
  • Làm thế nào để truyền bất cứ thứ gì vào bất cứ thứ gì (tất cả chỉ là 1 và 0 sau tất cả :))
  • Quản lý bộ nhớ malloc / miễn phí
  • Chồng vs Heap
  • Bí danh con trỏ, (tại sao nó bất hợp pháp trong C99)
  • Suy nghĩ về sự phát triển về mặt mô-đun (tệp .h / .c) với một tập hợp các hàm được hiển thị công khai thay vì các lớp nghiêm ngặt
  • Công đoàn
  • Tại sao chạy nước rút có thể thổi chân của bạn
  • Chức năng con trỏ

Tôi sẽ thêm "tràn bộ đệm" vào danh sách.
Aidan Cully

@Aidan, bắt tốt. Thêm.
Doug T.

2
Làm thế nào các mảng C và con trỏ không giống nhau: Books.google.ca/ Kẻ
Matthieu

con trỏ đáng lẽ phải được lặp lại ít nhất 3 lần nữa
Gaurav

8

Hiểu con trỏ và bạn sẽ hiểu máy tính.


12
Không, bạn chỉ đơn giản là sẽ ảo tưởng rằng bạn hiểu máy tính.
Công việc

4

Ngoài câu trả lời tuyệt vời của pythagras,

cách viết (hoặc ít nhất là đọc) các khai báo phức tạp, chẳng hạn như char (*(*funcs[4])())[10]

funcs là một mảng [4] con trỏ tới hàm trả về con trỏ thành mảng [10] của char


1
Nếu nó trở nên phức tạp, có lẽ điều này thuộc về một bình luận?
Công việc

7
Có lẽ anh nên học cách tránh viết như vậy?
FabianB

3
  1. Quy tắc khuyến mãi số nguyên
  2. Khởi tạo mọi thứ thành một giá trị đã biết
  3. GOTO không xấu, đặc biệt khi được sử dụng để xử lý các trường hợp ngoại lệ / thất bại
  4. malloc và / hoặc calloc có thể trả về NULL ... đảm bảo giá trị trả về kiểm tra của bạn
  5. Phân bổ bộ nhớ nhỏ thường xuyên có thể gây ra sự phân mảnh trên heap.
  6. Số học con trỏ
  7. Mặt nạ bit là bạn của bạn
  8. x >> 1 tương đương với x / 2 cho các số nguyên không dấu

+1 để GOTO không trở nên xấu xa :)
zvrba

2

Lập trình viên AC nên biết ... ngôn ngữ khác! ;-) Luôn luôn hiệu quả khi biết các khái niệm từ các ngôn ngữ khác của các mô hình khác nhau, như OOP, lập trình chức năng, v.v.

Nghiêm trọng hơn, nhìn vào cuộc thi lập trình bị xáo trộn là niềm vui và, tò mò, một trải nghiệm tốt quá.


2

Tôi đã đề cập đến "tràn bộ đệm" trong một bình luận cho câu trả lời của Pythagras, tôi có lẽ nên làm rõ những gì tôi muốn nói một chút. Trong C, không đủ để biết rằng làm việc trực tiếp với bộ nhớ là nguy hiểm - bạn cũng nên hiểu những cách chính xác mà nó nguy hiểm. Tôi thực sự không thích phép ẩn dụ "tự bắn vào chân mình" cho tất cả các trường hợp này - rất nhiều lần, không phải bạn bóp cò, mà thường là một diễn viên có sở thích trái ngược với bạn và / hoặc người dùng của bạn ' .

Ví dụ: trong một kiến ​​trúc có ngăn xếp giảm dần (hầu hết các kiến ​​trúc phổ biến phù hợp với hóa đơn này - x86 và ARM thường bao gồm), khi bạn gọi một hàm, địa chỉ trả về của hàm sẽ được đặt trên ngăn xếp sau các biến cục bộ được xác định trong cơ thể của chức năng. Vì vậy, nếu bạn khai báo bộ đệm là biến cục bộ và để biến biến đó ra thế giới bên ngoài mà không kiểm tra lỗi tràn bộ đệm, như sau:

void myFn(void) {
    char buf[256];
    gets(buf);
}

một người dùng bên ngoài có thể gửi cho bạn một chuỗi ghi đè địa chỉ trả về từ ngăn xếp - về cơ bản, anh ta có thể thay đổi ý tưởng thời gian chạy chương trình của bạn về biểu đồ cuộc gọi dẫn đến hàm hiện tại. Vì vậy, người dùng cung cấp cho bạn một chuỗi đó là biểu diễn nhị phân của một số mã thực thi cho kiến ​​trúc của bạn, đủ phần đệm để tràn vào ngăn xếp myFnvà một số dữ liệu bổ sung để ghi đè địa chỉ trả về myFnđể trỏ đến mã mà anh ta đã cung cấp cho bạn. Nếu điều này xảy ra, thì myFnthông thường sẽ trả lại quyền kiểm soát cho người gọi của nó, thay vào đó, nó sẽ phân nhánh để mã mà người dùng độc hại cung cấp. Nếu bạn viết mã C (hoặc C ++) có khả năng tiếp xúc với người dùng không tin cậy, bạn cần hiểu vectơ tấn công này. Bạn nên hiểu tại sao một bộ đệm tràn vào ngăn xếp thường (nhưng không phải luôn luôn) dễ dàng khai thác hơn so với bộ đệm và bạn nên hiểu cách bộ nhớ trong heap được đặt ra (không nhất thiết là quá nhiều chi tiết, nhưng ý tưởng rằng một malloc()khu vực có các cấu trúc điều khiển xung quanh nó có thể giúp hiểu lý do tại sao chương trình của bạn gặp sự cố ở một khu vực khác malloc()hoặc trong free()).

C cung cấp cho bạn các chi tiết cấp thấp về cách thức hoạt động của máy và nó cho phép bạn kiểm soát trực tiếp máy của mình nhiều hơn bất kỳ ngôn ngữ nào do người dùng chỉnh sửa khác sử dụng rộng rãi hiện nay. Với sức mạnh lớn đi kèm với trách nhiệm lớn - bạn thực sự cần phải hiểu những chi tiết cấp thấp đó để làm việc với C một cách an toàn và hiệu quả.


0

Ngoài các câu trả lời hay khác, tôi muốn thêm các kỹ thuật lập trình phòng thủ vào danh sách.

Ví dụ: sử dụng các xác nhận khi bắt đầu / kết thúc các chức năng để xác minh hợp đồng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.