2010-01-18 37 views
7

Tôi là một lập trình viên khá mới và tôi xin lỗi nếu thông tin này có sẵn một cách dễ dàng, tôi chưa thể tìm thấy nó.Số ma thuật trong mảng? - C++

Đây là câu hỏi của tôi:

Được coi là số ma thuật khi bạn sử dụng một chữ số để truy cập một phần tử cụ thể của một mảng?

Ví dụ:

arrayOfNumbers[6] // Is six a magic number in this case? 

Tôi hỏi câu hỏi này bởi vì một trong những giáo sư của tôi khẳng định rằng tất cả các số chữ trong một chương trình là những con số kỳ diệu. Nó sẽ được tốt đẹp cho tôi chỉ để truy cập vào một phần tử của một mảng bằng cách sử dụng một số thực, thay vì sử dụng một hằng số được đặt tên cho mỗi phần tử.

Cảm ơn!

+1

'#define ONE 1' ...' i + = ONE; ' –

+2

để tránh điều đó, Thiên Chúa đã cho chúng tôi i + +: P – Leo

+1

Có. 6 là một số ma thuật. Nó luôn luôn là tốt hơn để tránh số ma thuật trong mã, ví dụ: '#define PI 3.1416', mà là tốt hơn so với sử dụng' 3.1416' trên tất cả các mã của bạn, nên giá trị của pi thay đổi. –

Trả lời

22

Điều đó thực sự phụ thuộc vào ngữ cảnh. Nếu bạn có mã như sau:

arr[0] = "Long"; 
arr[1] = "sentence"; 
arr[2] = "as"; 
arr[3] = "array."; 

... thì 0..3 không được coi là số ma thuật. Tuy nhiên, nếu bạn có:

int doStuff() 
{ 
    return my_global_array[6]; 
} 

... thì 6 là dứt khoát là số ma thuật.

+0

Ahh, O.K. Điều đó có ý nghĩa. – Alex

5

Bạn nên tự hỏi tại sao bạn truy cập vào vị trí cụ thể đó. Trong trường hợp này, tôi giả định rằng nếu bạn đang làm arrayOfNumbers[6] vị trí thứ sáu có một số ý nghĩa đặc biệt. Nếu bạn nghĩ ý nghĩa đó là gì, bạn có thể nhận ra rằng đó là một con số ma thuật che giấu điều đó.

0

Nếu bạn cần truy cập vào phần tử cụ thể của mảng, rất có thể bạn đang làm sai.

Bạn hầu như luôn phải lặp lại toàn bộ mảng.

6

Khá là kỳ diệu.

Ý tôi là, tại sao bạn đang truy cập phần tử thứ 6? Các ngữ nghĩa cần được áp dụng cho số đó là gì? Vì nó đứng tất cả chúng ta biết là "số 6 (không dựa trên số)". Nếu chúng tôi biết tuyên bố của arrayOfNumbers, chúng tôi sẽ biết thêm về loại hình này (ví dụ: int hoặc double).

Nhưng nếu bạn nói:

arrayOfNumbers[kDistanceToSaturn]; 

... bây giờ nó có ý nghĩa nhiều hơn nữa cho người đọc mã.

Nói chung một lần lặp qua một mảng, thực hiện một số thao tác trên mỗi phần tử, bởi vì không biết mảng đó dài bao nhiêu và bạn không thể truy cập nó theo cách được mã hóa cứng.

Tuy nhiên, đôi khi các phần tử mảng có ý nghĩa cụ thể, ví dụ như trong lập trình đồ họa. Đôi khi một mảng luôn có cùng kích thước vì dữ liệu yêu cầu nó (ví dụ: một số ma trận biến đổi). Trong những trường hợp này, có thể hoặc không thể truy cập yếu tố cụ thể theo số: các chuyên gia miền sẽ biết bạn đang làm gì, nhưng những người tổng quát có lẽ sẽ không làm như vậy. Cho số chỉ số ma thuật một tên làm cho nó rõ ràng hơn cho những người có để duy trì mã của bạn, và giúp bạn ngăn chặn gõ nhầm một cách vô tình.

Trong ví dụ trên, tôi giả sử mảng của bạn giữ khoảng cách từ mặt trời đến một hành tinh. Mặt trời sẽ là yếu tố zeroth, do đó arrayOfNumbers [kDistanceToSun] = 0. Khi bạn tăng, mỗi phần tử chứa khoảng cách đến hành tinh xa nhất tiếp theo: thủy ngân, venus, v.v. Điều này dễ đọc hơn nhiều so với việc gõ số hành tinh bạn muốn. Trong trường hợp này mảng có kích thước cố định bởi vì có một số lượng cố định các hành tinh (tốt, ngoại trừ toàn bộ Pluto debacle).

Vấn đề khác là "arrayOfNumbers" không cho chúng tôi biết gì về nội dung của mảng.Chúng tôi đã biết một loạt các con số bởi vì chúng tôi đã nhìn thấy tờ khai ở đâu đó mà bạn nói int arrayOfNumers[12345]; hoặc tuy nhiên bạn đã khai báo nó. Thay vào đó, một cái gì đó như:

int distanceToPlanetsFromSol[kNumberOfPlanets]; 

... cho chúng ta một ý tưởng tốt hơn về những gì các dữ liệu thực sự là gì và ngữ nghĩa của nó là. Một trong những mục tiêu của bạn là một lập trình viên nên viết mã tự tài liệu theo cách này.

Và sau đó chúng ta có thể tranh luận ở nơi khác nếu kNumberOfPlanets nên 8 hoặc 9. :)

+0

Vâng nó phụ thuộc nếu bạn đếm sao Hỏa hai lần. –

0

Nó chỉ không phải là một con số kỳ diệu nếu chương trình của bạn đang làm một cái gì đó rất đặc biệt liên quan đến thứ sáu đặc biệt. Bạn có thể cung cấp một số ngữ cảnh?

1

Bạn sẽ phải cung cấp thêm ngữ cảnh cho câu trả lời có ý nghĩa. Không phải tất cả các chữ số đều là ma thuật, nhưng rất nhiều. Trong một trường hợp như vậy, không có cách nào để nói chắc chắn, mặc dù hầu hết các trường hợp, tôi có thể nghĩ rằng off-hand với một chỉ mục mảng rõ ràng >> 1 có thể đủ điều kiện là ma thuật.

0

Đó là vấn đề với các giáo sư, chúng thường quá học thuật. Về lý thuyết, anh ta đúng, như thường lệ, nhưng thường số ma thuật được sử dụng trong bối cảnh chặt chẽ hơn, khi số được nhúng vào luồng dữ liệu, cho phép bạn phát hiện các thuộc tính nhất định của luồng (như tiêu đề chữ ký của loại tệp cho ví dụ). Xem thêm this Wikipedia entry.

+0

Sau đó, bạn nên sử dụng các hằng số có tên, không phải số ma thuật. –

+0

Chết tiệt bạn đã viết những gì tôi sắp viết. +1. –

1

Không tất cả chữ trong chương trình thực sự đủ điều kiện là "số ma thuật" - nhưng điều này chắc chắn dường như. Các 6 cho chúng ta không có đầu mối về lý do tại sao bạn đang truy cập vào yếu tố cụ thể của mảng.

Để không là số ma thuật, bạn cần ý nghĩa của nó khá rõ ràng ngay cả trong lần kiểm tra đầu tiên (hoặc ít nhất là kiểm tra tối thiểu) tại sao giá trị đó đang được sử dụng. Ví dụ, rất nhiều mã sẽ làm những việc như: &x[0]. Trong trường hợp này, nó thường khá rõ ràng rằng '0' thực sự chỉ có nghĩa là "sự khởi đầu của mảng."

0

Thông thường không phải tất cả các giá trị không đổi trong phần mềm được gọi là số ma thuật. Một tệp lớp java luôn bắt đầu bằng giá trị hex 0xcafebabe một cửa sổ .exe tệp với MZ 0x4d, 0x5a, điều này cho phép bạn nhanh chóng (nhưng không chắc chắn) để xác định nội dung của tệp nhị phân .

2

một cách khác để xem:

Điều gì sẽ xảy ra nếu sau một số cơ hội, chương trình cần truy cập phần tử thứ 7 thay vì 6? HOw bạn hoặc người bảo trì có biết điều đó không? Nếu ví dụ nếu mục 6 là số lượng cây trong CA nó sẽ là một điều tốt để đặt

#define CA_STATE_ENTRY 6 

Sau đó, nếu ai đó tại bảng được sắp xếp lại có thể thấy rằng họ cần phải thay đổi điều này đến 9 (nói) .BTW Tôi không nói đây là cách tốt nhất để duy trì một mảng cho cây đếm bởi nhà nước - nó có lẽ là không.

Tương tự như vậy, nếu mọi người sau đó muốn thay đổi chương trình để đối phó với các loại cây trong oregon, sau đó họ biết để thay thế

trees[CA_STATE_ENTRY] 

với

trees[OR_STATE_ENTRY] 

Vấn đề là

trees[6] 

không tự ghi tài liệu

Tất nhiên đối với C++ nó phải là một enum không phải là #define

0

Trong hệ thống tương thích MISRA, tất cả các giá trị ngoại trừ 0 và 1 được coi là số ma thuật. Ý kiến ​​của tôi luôn luôn là nếu giá trị không đổi là rõ ràng hoặc có khả năng sẽ không thay đổi sau đó để nó như một con số. Nếu nghi ngờ tạo ra một hằng số duy nhất kể từ khi bảo trì dài hạn sẽ dễ dàng hơn.

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