2010-01-12 39 views

Trả lời

27

Phụ thuộc vào triển khai thực hiện. Thông thường, nó được gọi mỗi lần, nhưng, nếu trình biên dịch có thể thấy rằng word không bao giờ thay đổi và rằng strlen là một hàm thuần túy (không có tác dụng phụ), nó có thể nâng cuộc gọi.

Xem: http://underhanded.xcott.com/?page_id=15 để biết ví dụ nổi tiếng về điều này đang được khai thác. :-)

+0

Đây là câu trả lời đúng ... thực sự, nó phụ thuộc vào trình biên dịch thông minh như thế nào. – Noldorin

+0

Trong ví dụ được cung cấp, điều này được thực hiện trên một 'char *' có nghĩa là cả con trỏ lẫn dữ liệu được trỏ đến đều không đổi. Gcc có thực sự làm việc này không? Nó có vẻ vô cùng nguy hiểm. –

+0

@PP: Giả sử 'từ' của bạn không được chuyển qua bất kỳ nơi nào khác trong vòng lặp (hoặc chỉ được chuyển đến một hàm lấy' char const * '), và mã của bạn được coi là đơn luồng, và không có răng cưa liên quan (hoặc là bởi vì hàm là unary, hoặc bởi vì con trỏ được khai báo 'restricted'). Trong trường hợp đó, tôi muốn nói rằng đó là một giả định khá an toàn rằng dữ liệu sẽ không thay đổi. –

8

Nó sẽ được đánh giá cho mỗi lần lặp của vòng lặp (chỉnh sửa: nếu cần thiết).

Như Tatu đã nói, nếu word sẽ không thay đổi về độ dài, bạn có thể thực hiện cuộc gọi strlen trước vòng lặp for. Nhưng như Chris đã nói, trình biên dịch có thể đủ tốt để nhận ra rằng word không thể thay đổi và loại bỏ các cuộc gọi trùng lặp.

Nhưng nếu word có thể thay đổi chiều dài trong vòng lặp, thì tất nhiên bạn sẽ cần phải giữ cuộc gọi strlen trong điều kiện vòng lặp.

+1

thực sự, hầu hết các trình biên dịch nên tối ưu hóa điều này miễn là 'từ' không được thay đổi trong phần thân vòng hoặc được khai báo là' biến động '; như mọi khi, bạn có thể kiểm tra (dis-) lắp ráp để xem những gì sẽ xảy ra ... – Christoph

+0

Bah, đây là xa câu trả lời đầy đủ. Nếu trình biên dịch là một nửa waqy phong nha, nó thực sự nên tối ưu hóa các cuộc gọi để nó chỉ được đánh giá một lần. – Noldorin

+0

Đúng vậy, trình biên dịch có thể đủ thông minh để tối ưu hóa và tránh cuộc gọi mỗi lần. –

0

strlen kiểm tra chiều dài của chuỗi được cung cấp. Điều đó có nghĩa là nếu chiều dài là 10. Lặp lại của bạn sẽ tiếp tục miễn là tôi ở dưới 10.

Và trong trường hợp đó. 10 lần.

Read more about loops

+0

-1 vì chuỗi có thể được sửa đổi trong vòng lặp và do đó 'strlen' có thể được gọi là số lần vô hạn (giả sử trình biên dịch không lưu trong bộ nhớ đệm kết quả của' strlen() '). –

+0

Ngoài ra không có sự đảm bảo nào trong ví dụ rằng 'i' cũng không bị sửa đổi. –

+0

Đó là một lý do ngu ngốc để bỏ phiếu. Giả sử rằng anh ta không làm xáo trộn chuỗi. Đó là một sự giải thích rất cơ bản về cách nó trông như thế nào trên một cái nhìn đầu tiên và sau đó là một tham chiếu về cách vòng lặp hoạt động. –

6

tôi sẽ thỉnh thoảng mã mà như ...

for (int i = 0, n = strlen(word); i < n; ++i) { /* do stuff */ } 

... do đó, strlen mà chỉ được gọi một lần (để cải thiện hiệu suất).

0

Nó sẽ được gọi cho mỗi lần lặp lại. Đoạn mã sau chỉ gọi hàm strlen một lần.

for (i = 0, j = strlen(word); i < j i++) 
{ /* do stuff */ } 
1

Số lần strlen(word) được thực hiện phụ thuộc vào:

  1. Nếu word được khai báo là không đổi (các dữ liệu là hằng số)
  2. Hoặc trình biên dịch có thể phát hiện rằng word là không thay đổi.

Lấy ví dụ sau đây:

char word[256] = "Grow"; 

for (i = 0; i < strlen(word); ++i) 
{ 
    strcat(word, "*"); 
} 

Trong ví dụ này, biến word được sửa đổi withing vòng lặp:
0) "Grow" - chiều dài == 4
1) "Grow * "- length == 5
2)" Grow ** "- length == 6

Tuy nhiên, trình biên dịch có thể yếu tố ra lệnh gọi strlen, vì vậy nó được gọi một lần, nếu biến ble word được khai báo là hằng số:

void my_function(const char * word) 
{ 
    for (i = 0; i < strlen(word); ++i) 
    { 
    printf("%d) %s\n", i, word); 
    } 
    return; 
} 

Chức năng đã tuyên bố rằng biến word là dữ liệu liên tục (trên thực tế, một con trỏ đến dữ liệu liên tục). Do đó độ dài sẽ không thay đổi, do đó trình biên dịch chỉ có thể gọi strlen một lần.

Khi nghi ngờ, bạn luôn có thể tự thực hiện tối ưu hóa, có thể hiển thị mã dễ đọc hơn trong trường hợp này.

+3

Con trỏ có đủ điều kiện 'const' chỉ là lời hứa rằng con trỏ sẽ không bị thay đổi thông qua biến cụ thể đó (mà không cần truyền), không phải là dữ liệu tự nó không thay đổi. – jamesdlin

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