2009-03-22 33 views
19

Đối với những người bạn có kinh nghiệm phát triển chương trình giảng dạy: chiến lược tốt nhất về mảng là gì?Khi dạy C, tốt hơn là dạy các mảng trước hoặc sau con trỏ?

Tôi đã thấy một số trường dạy mảng sau biến và cấu trúc điều khiển, thường trước khi thậm chí chức năng giảng dạy. Điều này cho phép giảng dạy của một số thuật toán thô sơ, vv Tuy nhiên, nó sau đó mang lại cho vấn đề làm thế nào để vượt qua mảng để chức năng, vì vậy nó là cần thiết để quay trở lại mảng con trỏ được dạy và vá những thứ lên.

Một tùy chọn khác là chuyển từ biến và điều khiển cấu trúc sang hàm, sau đó dạy con trỏ, và khi bạn có con trỏ, hãy dạy mảng từ đầu và sau đó sử dụng để phân bổ bộ nhớ động.

Với tôi lựa chọn thứ hai có ý nghĩa hơn, vì không giống như các biến đơn giản, với mảng dễ “thoát khỏi giới hạn”, nhưng những sinh viên chưa học về trí nhớ và con trỏ có thể không hiểu những gì nằm ngoài giới hạn này .

Tuy nhiên, tôi muốn biết suy nghĩ của người khác.

Trả lời

34

Tôi nghĩ cách tiếp cận tốt nhất là giới thiệu 1 khái niệm tại một thời điểm. Bạn không cần phải giải thích 100% mảng trong mô-đun đầu tiên. Bạn có thể detangle gần như bất cứ điều gì bằng cách giới thiệu 1 khái niệm tại một thời điểm.

Tôi sẽ dạy chúng theo thứ tự này: Mảng, Con trỏ, Mảng + Con trỏ, KhácStuff [N].


Mảng:

Bạn có thể dạy cho mảng đơn giản đầu tiên để họ hiểu được những khả năng có nhiều khe cắm dữ liệu truy cập từ một tên biến duy nhất.

//The following doesn't need an understanding of pointers 
int x[10]; 
x[0] = 5; 

Pointers:

Sau đó, bạn có thể dạy về con trỏ và cách họ làm việc, bắt đầu với một số ví dụ đơn giản:

int y = 5; 
int *p = &y; 
*p = 6; 
printf("%i\n", y); 

Hãy chắc chắn để đưa ra một tầm quan trọng đặc biệt một con trỏ giống như bất kỳ biến nào khác. Nó lưu trữ một địa chỉ bộ nhớ.

Không cần phải tham gia ngăn xếp so với heap.


Mảng + Pointers:

Làm thế nào để lặp qua mảng với con trỏ:

int x[10]; 
x[0] = 5; 
x[1] = 6; 
int *y = x; 
printf("%i\n", *y);//prints the first element 
y++; 
printf("%i\n", *y);//prints the second element 

Sau đó, bạn có thể dạy cho những điều phức tạp hơn ...

  • Cách thực hiện số học con trỏ.
  • Mảng + i viết tắt cho mảng [i]
  • Passing arrays to functions as array pointets vs pointer param + size param
  • Làm thế nào mảng là một khối liên tục của bộ nhớ
  • Giải thích xâu, vùng đệm, ...
  • Làm thế nào sizeof làm việc với con trỏ vs loại mảng (kích thước con trỏ vs kích thước bộ đệm)
  • Giải thích các khái niệm phức tạp hơn như phân bổ bộ nhớ, the stack, and the heap
  • nhiều mức gián tiếp
  • R eferences
  • Làm thế nào mảng đa chiều làm việc
  • ...

Trong suốt tất cả các ví dụ sử dụng nhiều địa chỉ sizeof và in ấn. Nó thực sự giúp hiểu những gì đang xảy ra.

+2

Đối với chủ đề nâng cao, mảng đa chiều có thể hữu ích. Sự cân bằng về biểu diễn cấu trúc 2D là "int ** arr" với chỉ mục 2D rõ ràng hoặc "int * arr" với lập chỉ mục thủ công có thể hữu ích khi sinh viên sẵn sàng. –

+0

Heh, đây là cách tôi được dạy. Nó hoạt động tốt. –

+0

@Mr Fooz: Cảm ơn thêm –

2

Họ nên được dạy cùng một lúc.

Ví dụ về mảng đơn chiều được truy cập dưới dạng con trỏ tới cơ sở có bù trừ (chỉ số phân loại *) sẽ xuất hiện.

ví dụ:

a[i] is equivalent to *(a + i) 
+0

Đó là một dấu chấm, trừ khi bộ nhớ biến động hoặc bạn kỳ vọng điều kiện chủng tộc. =] – strager

+0

@strager: bạn có muốn giải thích không? –

+0

@Mitch, bạn đã viết bài tập. Có thể bạn muốn nói ==. –

9

Tôi sẽ dạy con trỏ đầu tiên. Chúng có thể được giải thích mà không cần dạy mảng. Trong khi dạy mảng, tôi có thể tham chiếu đến con trỏ khi giải thích biểu thức a[i] và khi giải thích cách người ta có thể truyền chúng đến hàm.

8

Đừng đánh lừa quá nhiều thứ.

Dạy những khái niệm này một cách rõ ràng và engagingly càng tốt là FAR quan trọng hơn để những gì bạn làm cho họ ở.

tôi sẽ đề nghị chạm vào những điều cơ bản của mảng đầu tiên, và làm con trỏ và xem xét lại các mảng (đầy đủ hơn này thời gian xung quanh) sau đó.

0

Phụ thuộc vào những gì họ biết. Bạn đang dạy C, hoặc lập trình-và-C?

Tôi đã thấy rất ít thành công với cái sau. C đơn giản không phải là một ngôn ngữ rất trực quan hoặc tha thứ. Tôi chưa từng thấy sinh viên biết ơn vì đã bắt đầu với nó, mặc dù tôi đã thấy sinh viên thất vọng với việc lập trình cho nó.

Những người sẽ gắn bó với lập trình sẽ ra ngoài và học C trong thời gian rảnh rỗi. Không cần phải đẩy nó lên đầu tiên.

Nếu bạn chỉ dạy C, và họ đã biết con trỏ và mảng, sau đó dạy cách con trỏ và mảng hoạt động trong C có thể được thực hiện trong một bài học.

8

Bạn nên dạy mảng trước tiên, vì chúng tồn tại ở hầu hết mọi ngôn ngữ khác và dễ hiểu hơn. Con trỏ, hoặc một số khía cạnh của con trỏ, xây dựng trên những gì đã học về mảng. Đây là thứ tự hữu cơ, imho, và tôi đã học được cách đó khi nào.

2

Tôi giả sử bạn đang dạy C cho sinh viên đã biết cách lập trình bằng ngôn ngữ khác như Java (hoặc ngược lại trong ngày của tôi, Pascal). Tôi không nghĩ C là một ngôn ngữ tốt để sử dụng cho việc dạy lập trình để hoàn thành những người mới.

Tôi sẽ dạy con trỏ trước. Đây là một trong những ý tưởng mới quan trọng mà sẽ được học tập trong C. Họ sẽ biết khái niệm về mảng từ các ngôn ngữ khác, vì vậy không có sự cấp bách để dạy điều này trước tiên. Vì vậy, khi bạn thực hiện các mảng trong C, bạn có thể nói về cách chúng về cơ bản là cú pháp đường cho số học con trỏ, một khái niệm mà chúng đã quen thuộc.

+0

Bạn dường như ngụ ý rằng Pascal không có con trỏ. Tôi đã không làm việc với Pascal trong nhiều năm, nhưng trở lại trong ngày của tôi Pascal đã có con trỏ. Tôi đã học về chúng ở đó đầu tiên, vì tôi đã không đến C trong vài năm nữa. – GreenMatt

2

Tôi dạy con trỏ trước khi tôi lo lắng về mảng. Tuy nhiên, thông thường, các sinh viên tôi thấy, họ đã được tiếp xúc với mảng trong lớp CS đầu tiên của họ trong một số ngôn ngữ khác. Tuy nhiên, ngay cả khi tôi đang dạy C trong lớp CS đầu tiên, tôi sẽ làm con trỏ trước mảng và mô tả mảng về con trỏ. Chỉ vì nó là thời trang những ngày này để suy nghĩ "không ai sẽ bao giờ cần hoặc muốn biết làm thế nào máy tính thực sự làm việc" không có nghĩa là nó là sự thật.

1

Như đã nêu ở trên, tôi không nghĩ thứ tự quan trọng, nhưng đây là thứ tự tôi muốn ai đó cho tôi xem nội dung.

  1. Mảng
  2. Pointers
  3. Làm thế nào Mảng và con trỏ đều giống nhau
  4. Tại sao Mảng và con trỏ không giống nhau

Để biết thêm về điểm 4 Tôi thực sự khuyên chương 4 "Sự thật gây sốc: C mảng và con trỏ KHÔNG giống nhau!" trong "Chuyên gia C, bí mật sâu C".

/Johan


Cập nhật:

Một số liên kết đến các cuốn sách, và đó cũng là một bản xem trước của cuốn sách. http://books.google.se - Expert C, deep C secrets

Và những ý kiến ​​người dùng về cuốn sách này là đúng: http://www.amazon.co.uk/Expert-Programming-Peter-van-Linden/dp/0131774298

+0

Tôi không quen thuộc với cuốn sách đó. Sự khác biệt chính mà nó nổi bật là gì? (Tôi có rất ít thời gian để đầu tư vào điều đó, nhưng tôi muốn thể hiện một lý lẽ thuyết phục) – Uri

+0

Không có phép thuật trong cuốn sách này, nhưng đó là một cuốn sách đã cho tôi một trong những khoảnh khắc "mở mắt". Cuốn sách đi qua mảng và con trỏ theo một cách khác. – Johan

0

Bạn có dạy con trỏ trước khi chuỗi?

Có thể là không. Và hầu hết các đối số giống nhau đều áp dụng.

(Nhưng nói chung tôi đồng ý với @legion — không overthink nó.)

1

Nếu họ đã được tiếp xúc với Assembler trước, dạy con trỏ đầu tiên.

Nếu họ đã tiếp xúc với các ngôn ngữ cấp cao hơn (tức là về bất kỳ thứ gì) trước tiên hãy dạy mảng.

Trong kinh nghiệm của tôi, mọi người đến với C mà không cần phải tiếp xúc với lập trình cấp độ lắp ráp (sổ đăng ký, địa chỉ, "nguyên tắc cơ bản về máy tính") sắp bước vào thế giới đau đớn. IMHO bạn thực sự tốt hơn off giảng dạy cấp độ lắp ráp mã hóa đầu tiên, sau đó giới thiệu C như là một lắp ráp tốt hơn.

+0

Có, đó là nói ngắn gọn hơn những gì tôi đã suy nghĩ. –

0

Tôi nghĩ sẽ tốt hơn khi bắt đầu với mảng, vì khái niệm mảng đơn giản và trực quan, nhưng trong C nó sẽ xem xét lại mảng quan trọng sau khi dạy ponters, như 'Legion' được đề xuất trước đó.

0

Câu hỏi này có thể được yêu cầu cho bất kỳ ngôn ngữ hướng đối tượng nào thực sự.

Khi tôi được dạy Java, lần đầu tiên tôi được hiển thị mảng và con trỏ, như phần cuối của mảng, để chứng minh sự khác biệt giữa bản sao sâu và bản sao nông.

1

Câu hỏi thú vị - Tôi hy vọng không quá muộn để trả lời.

Khi tôi dạy chương trình tại Đại học Boston vào đầu những năm 80, đồng nghiệp và tôi đã vật lộn với những vấn đề này hàng năm, và chúng tôi tiếp tục tinh chỉnh cách tiếp cận của mình. C là một ngôn ngữ mới sau đó, vì vậy sự tiến triển của chúng tôi đã trải qua Basic cho Pascal. Tôi nhớ suy nghĩ vào thời điểm khó dạy C chỉ vì nó lỏng lẻo hơn, có nhiều cách để sinh viên rối tung lên, và nhiều thứ khó hiểu hơn như sự phân biệt giữa mảng và con trỏ mà bạn phải dạy .

Điều tôi thấy hữu ích nhất là cố gắng cụ thể, không trừu tượng. Ví dụ, trong khóa học lập trình giới thiệu, tôi đã sử dụng một trình thông dịch cho một máy tính thập phân đơn giản mà bạn sẽ lập trình bằng ngôn ngữ máy "thập phân". Nó có địa chỉ đi từ 0 đến 999, và opcodes như 1234, với "1" có nghĩa là "thêm vào accumulator", và "234" là địa chỉ của nơi để tìm số để thêm. Học sinh sẽ viết các chương trình thực sự đơn giản, như để thêm một danh sách các số, và họ sẽ thực hiện một bước, quan sát những gì xảy ra ở mỗi bước.

Tôi sẽ yêu cầu họ chơi trò chơi này trong khoảng 3 tuần và sau đó bắt đầu vào BASIC. Trong khóa học thứ hai, họ sẽ đi vào Pascal. Có gì mà thập phân nhỏ "máy tính" thực hiện là để truyền đạt một số khái niệm cụ thể mà làm cho "trừu tượng" trong ngôn ngữ "thật" dễ dàng hơn rất nhiều để hiểu, chẳng hạn như:

  • nhớ gì, và những địa chỉ là, và cách cả dữ liệu và chương trình chỉ là số ở các địa chỉ trong bộ nhớ. Điều đó làm cho khái niệm "biến" và "mảng" và "con trỏ" dễ dàng hơn nhiều để giải thích sau này.
  • Cách mô hình tính toán cơ bản là các bước rất đơn giản được thực hiện theo thứ tự và trước khi mỗi bước có thể bắt đầu, bước trước đó phải kết thúc. Tôi biết mọi người sẽ phản đối rằng các máy tính được song song hóa cao và hiện đại, nhưng tôi phải giải thích rằng bạn cần phải bắt đầu thực sự đơn giản, bởi vì khi người mới xem một chương trình chạy, nó sẽ tìm kiếm tất cả mọi thứ trên thế giới. tâm trí của bạn trong quá trình này.
  • Làm thế nào, bằng cách kết hợp một vốn từ vựng rất nhỏ của hướng dẫn, bao gồm nhảy và nhảy có điều kiện, bạn có thể làm cho máy tính thực hiện hầu hết mọi thứ bạn muốn.

Bây giờ, liên quan đến C, tôi đã nghe nó bị phân biệt như một ngôn ngữ lắp ráp ở trên, nhưng tôi nghĩ đó là một điều tốt. Nó luôn luôn đánh tôi như một ngôn ngữ của các chuyên gia cho các chuyên gia. Tôi nghĩ rằng các ý tưởng của mảng và con trỏ và cấu trúc rất dễ dàng để giải thích nếu bạn chỉ có thể tham khảo lại máy tính cơ bản. Tương tự cho C++ và lập trình hướng đối tượng. Vì vậy, để tóm tắt, nếu học sinh hiểu khái niệm cơ bản về cách thức hoạt động của máy tính, ngay cả khi nó là một máy tính thực sự nhân tạo, thì việc giải thích các khái niệm cấu trúc dữ liệu ở cấp độ cao hơn sẽ dễ dàng hơn rất nhiều.

Các vấn đề liên quan