Tôi không thực sự chắc chắn thứ tự ở đây là gì. Là nó: 1) dereference giá trị của con trỏ p sau khi tăng nó 2) dereference giá trị của con trỏ p trước khi tăng nóLiệu * p ++ tăng sau khi dereferencing?
Trả lời
Không có thứ tự nào giữa số gia tăng và dereference.Tuy nhiên, toán tử *
áp dụng cho kết quả của p++
, là giá trị ban đầu của p
trước số gia tăng.
Với q = *p++;
, q được giá trị mà p trỏ đến trước khi tăng. Một cách khác để nói rằng giá trị của biểu thức *p++
là giá trị p trỏ đến trước khi được tăng lên.
Có thể tìm '* p', gia tăng' p' và gán giá trị '* p' (được tính trước) thành' q' – asaelr
@asaelr Đó là điểm công bằng mà bài tập thực sự có thể xảy ra sau khi tăng, nhưng hiệu ứng là như nhau: q nhận giá trị của * p trước khi p được tăng lên. – Caleb
Hiệu quả là như nhau, nhưng câu hỏi là những gì xảy ra trước tiên. – asaelr
Các toán tử postfix ++ và - chủ yếu có quyền ưu tiên cao hơn các toán tử đơn vị tiền tố. Do đó, * p ++ tương đương với * (p ++); nó tăng p và trả về giá trị p trỏ đến trước khi p được tăng lên.
Để tăng giá trị được trỏ tới bởi p, hãy sử dụng (* p) ++ (hoặc có thể ++ * p, nếu thứ tự đánh giá tác dụng phụ không quan trọng).
Hãy dùng thử. Chương trình
#include <stdio.h>
int main(void) {
int p[2];
int *q = p;
p[0] = 10;
p[1] = 100;
printf("%d\n", *q++);
printf("%d\n", *q);
return 0;
}
in
10
100
cho thấy ++
áp dụng cho p
, không *p
, và rằng thặng dư sẽ xảy ra sau khi dereference.
EDIT: (Nhờ @EricLippert đã thuyết phục tôi phải rút ra khỏi K & R)
Không chỉ có thể có được một xảy ra, sau khi mối quan hệ, nhưng theo K & R trang 203, có phải là:
Biểu thức hậu tố theo sau bởi toán tử ++ hoặc - là biểu thức postfix. Giá trị của biểu thức của biểu thức là giá trị của toán hạng. Sau khi giá trị được ghi chú khác, các toán hạng được tăng (++) hay giảm (-) bằng 1.
(tôi nhấn mạnh)
Cấp, tôi không tin rằng K & R nói bất cứ điều gì về ngữ nghĩa của C trong sự hiện diện của đa luồng (theo Wikipedia các đặc điểm kỹ thuật pthreads đã được phát hành vào năm 1995), nhưng đối với một chương trình đơn luồng K & R là khá rõ ràng.
Chờ một chút tại đây. Trong ** C **, chắc chắn có thể có mối quan hệ "xảy ra sau"; cho dù có hay không là một chi tiết thực hiện của trình biên dịch. Một trình biên dịch C có toàn quyền quyết định trong việc lựa chọn cách đặt hàng các hiệu ứng phụ trong một chuỗi điểm, và nó có thể chọn để thực hiện tác dụng phụ của ++ sau mọi thứ khác nếu nó muốn. Trình biên dịch C# không có cùng một mức độ; đặc điểm kỹ thuật C# rất rõ ràng về chính xác khi nào mà hiệu ứng phụ đó phải được quan sát. (Quan sát trong một luồng thực hiện; thứ tự mà một luồng khác quan sát tác dụng phụ không được chỉ định.) –
Trong operators table, bạn có thể thấy toán tử hậu tố ++
có vị trí cao hơn so với toán tử đơn nhất *
.
Do đó, *p++
tăng p
(và không *p
), và trả về giá trị nếu địa chỉ đó p
chứa trước khi thặng dư (vì đó là suffix ++
).
Nhưng đơn đặt hàng phụ thuộc vào triển khai. Nó có thể bắt đầu bằng dereferencing p, và sau đó tăng nó, và nó có thể lưu trữ giá trị cũ của p
, tăng nó, và sau đó dereference giá trị cũ.
"các toán tử tăng sau và tăng giảm (hoặc giảm) giá trị toán hạng của chúng bằng 1, nhưng giá trị của biểu thức là giá trị ban đầu của toán hạng trước thao tác tăng (hoặc giảm) "https://en.wikipedia.org/wiki/Increment_and_decrement_operators – Blas