Câu trả lời đã chọn của Adam Rosenfield là sai. Câu trả lời của coobird cũng vậy. Vì lý do đó tôi đã bỏ phiếu bình chọn cả hai câu trả lời.
Giải thích Adam Markowitz của *lineptr++
là đúng, nhưng anh ấy không trả lời câu hỏi chính cho dù đây là mã C99 hợp pháp hay không. Chỉ Tom Future mới có; không may là anh ấy không giải thích được *lineptr++
. Tôi đã cho họ một điểm.
Vì vậy, trong ngắn hạn, lineptr
là một biến và có thể được thao tác như một con trỏ. Do đó, hợp pháp để tăng con trỏ.
lineptr
là một con trỏ vào một chuỗi các con trỏ tới chuỗi các ký tự. Nói cách khác, nó là một con trỏ đến chuỗi đầu tiên của một mảng chuỗi. Theo mã, chúng ta có thể giả định rằng các chuỗi là null ('\ 0') kết thúc chuỗi char. nlines
là số chuỗi trong mảng.
Biểu thức kiểm tra trong khi là nlines-- > 0
. nlines--
là một bài đăng giảm (vì --
nằm ở bên phải của biến). Do đó, nó được thực hiện sau kiểm tra đã được thực hiện và bất kể kết quả thử nghiệm, vì vậy trong mọi trường hợp.
Vì vậy, nếu giá trị nlines
được cho làm đối số là 0
, thử nghiệm được thực hiện trước và trả về false
; các lệnh trong vòng lặp không được thực hiện. Lưu ý rằng kể từ khi nlines
bị giảm sút, giá trị của nlines
sau vòng lặp while
sẽ là -1
.
Nếu nlines == 1
, kiểm tra sẽ trả lại true
và nlines
sẽ bị giảm; các lệnh trong vòng lặp sẽ được thực hiện một lần. Lưu ý rằng mặc dù các hướng dẫn này được thực thi giá trị của nlines
là 0
. Khi thử nghiệm được thực hiện lại, chúng tôi quay lại trường hợp khi nlines == 0
.
Hướng dẫn printf
sử dụng biểu thức *lineptr++
. Nó là một sự gia tăng bài của con trỏ (++
là ở bên phải của biến). Điều này có nghĩa là biểu thức được đánh giá đầu tiên và gia số được thực hiện sau khi sử dụng. Vì vậy, trên thực hiện đầu tiên printf
nhận được một bản sao của phần tử đầu tiên của mảng chuỗi, đó là một con trỏ đến char đầu tiên của chuỗi. lineptr
chỉ được tăng lên sau đó. Lần sau, printf
sẽ được thực hiện, lineptr
điểm trên phần tử thứ hai và sẽ di chuyển đến phần tử thứ ba khi chuỗi thứ hai được in. Điều này có ý nghĩa bởi vì chúng tôi rõ ràng muốn in chuỗi đầu tiên. Nếu Adam Rosenfield đã đúng, chuỗi đầu tiên sẽ bị bỏ qua và cuối cùng chúng tôi sẽ cố gắng in chuỗi vượt quá chuỗi cuối cùng mà rõ ràng là một điều xấu để làm.
Vì vậy, hướng dẫn printf
là một hình thức ngắn gọn về hai hướng dẫn sau đây
printf("%s\n", *lineptr);
++lineptr; // or lineptr++, which is equivalent but not as good. lineptr += 1; is ok too.
Lưu ý, như một quy luật của, mà khi trước và sau tăng tương đương trong hành động của họ, trước tăng là thích hợp hơn vì lý do hiệu suất. Các trình biên dịch sẽ cẩn thận để chuyển đổi nó cho bạn. Vâng, hầu hết thời gian. Nó là tốt hơn cho các nhà điều hành tiền thân mình, bất cứ khi nào có thể, vì vậy nó được sử dụng luôn. Lý do trở nên rõ ràng hơn khi bạn thực hiện một bài đăng và tự tăng giá trong C++.
Cảm ơn bạn đã làm rõ ... Tôi đã tự hỏi liệu mình có phát điên hay không :) –