2012-02-20 60 views
5

Ai đó có thể giải thích kết quả của đoạn mã sauCon trỏ trỏ tới con trỏ số học

char* a[] = {"ABC123", "DEF456", "GHI789"}; 
char **p = a; 
cout<<++*p<<std::endl; 
cout<<*p++<<std::endl; 
cout<<++*p<<std::endl; 

Output:

BC123 
BC123 
EF456 

gì là khó hiểu với tôi là hành vi khác nhau của ++ * p và * p ++. Tôi đã chờ đợi kết quả là:

ABC123 
DEF456 
GHI789 
+6

điều hành được ưu tiên. Thêm một số dấu ngoặc đơn và nó sẽ trở nên rõ ràng ... – jrok

Trả lời

3
char* a[] = {"ABC123", "DEF456", "GHI789"}; 
char **p = a; 
cout<<++*p<<std::endl; // 1 
cout<<*p++<<std::endl; // 2 
cout<<++*p<<std::endl; // 3 

On line 1 đầu tiên *p sẽ được trỏ đến phần tử trong mảng "ABC123"++ di chuyển một về phía trước và như vậy 'BC123' được in ra.

Trên dòng 2 *p vẫn trỏ đến BC123 để in này và sau đó khi in ++ được thực hiện. Điều này di chuyển con trỏ đến phần tử thứ 2 trong mảng

Trên dòng 3 nó giống như dòng 1. Bạn đã lấy nội dung của p (Bây giờ là phần tử thứ 2 trong mảng) và di chuyển một ký tự trong chuỗi đó, do đó in EF456

(Cũng có một cái nhìn tại đây Pointer arithmetic on string type arrays, how does C++ handle this? như tôi nghĩ rằng nó có thể có ích để có được một sự hiểu biết về những gì đang xảy ra)

để in những gì bạn mong đợi những điều sau đây sẽ làm việc:

cout<<*p++<<std::endl; 
cout<<*p++<<std::endl; 
cout<<*p++<<std::endl; 

Hoặc

cout<<*p<<std::endl; 
cout<<*(++p)<<std::endl; 
cout<<*(++p)<<std::endl; 

Hoặc nhiều cách khác (có tính đến ưu tiên tài khoản như những người khác đã nói)

0

++*p được thực hiện trước khi in. Vì vậy, con trỏ tăng, sau đó in. *p++ được thực hiện sau khi in. In, sau đó tăng.

0

Chỉ cần đoán, nhưng tôi nghĩ vì bạn đang tăng con trỏ trì hoãn bằng cách sử dụng cout<<++*p<<std::endl;, những gì bạn đang thực sự làm là tăng ký tự ở đầu chuỗi mà p trỏ đến sau đó xuất kết quả này vào đầu ra tiêu chuẩn.

Tương tự, cout<<*p++<<std::endl; sẽ tăng ký tự sau khi xuất, do đó kết quả cuối cùng là cout<<++*p<<std::endl; sẽ tăng theo hai lần tăng.

Bạn nên cố gắng này để thay thế và xem nếu nó hoạt động

cout<<*(++p)<<std::endl; 
cout<<*(p++)<<std::endl; 
cout<<*(++p)<<std::endl; 
+1

Dòng cuối cùng của đầu ra đó làm cho nó phát triển không may. Các '+ + p' là di chuyển nó để vượt ra ngoài kết thúc của mảng – Firedragon

4

lẽ điều này sẽ giúp. Bạn ví dụ là tương đương với điều này:

++(*p); 
cout << *p << '\n'; 

cout << *p << '\n'; 
++p; 

++(*p); 
cout << *p << '\n'; 

Nếu không có dấu ngoặc đơn, *p++ được phân tách như *(p++) từ increment hậu tố đã có ưu tiên cao hơn toán tử tham chiếu. Sự gia tăng vẫn được thực hiện sau toàn bộ biểu hiện.

Mặt khác, tăng tiền tố và * có cùng mức ưu tiên, do đó, ++*p được phân tích cú pháp từ phải sang trái là ++(*p). Biết rằng tăng tiền tố phải được thực hiện trước khi biểu thức, bây giờ bạn có thể đặt toàn bộ hình ảnh lại với nhau.

+0

Tôi đã nhận nó ... Tôi đã chỉ được ưu tiên vận hành vào hình ảnh, quên hoàn toàn về associativity .. Cảm ơn –

1

Theo bảng ưu tiên toán tử C++, ưu tiên tăng sau cao hơn toán tử dereference (*) và toán tử tăng trước và dereference có cùng mức ưu tiên. Ngoài ra toán tử pre-increment và dereference là liên kết từ phải sang trái.

Vì vậy, trong dòng đầu tiên (cout<<++*p<<std::endl;), * và ++ được đánh giá từ phải sang trái (dereference đầu tiên, sau đó tăng). Bây giờ p vẫn trỏ đến mảng đầu tiên (vì nó không thay đổi), nhưng (* p) trỏ đến chữ cái thứ hai của chuỗi đầu tiên (đầu ra cho thấy thực tế này).

Trong dòng thứ hai (cout<<*p++<<std::endl;) tuy nhiên sau tăng được đánh giá đầu tiên (sau khi lấy các giá trị cũ của p) và p được tăng lên và bây giờ chỉ vào mảng thứ hai. Nhưng trước khi tăng, giá trị của p được sử dụng trong biểu thức và đầu ra của dòng thứ hai là chính xác như dòng đầu tiên.

Trong dòng thứ ba, đầu tiên p bị hủy tham chiếu (trỏ tới chữ cái thứ nhất của mảng thứ hai), sau đó được tăng lên (trỏ tới chữ cái thứ hai của mảng thứ hai) và giá trị được in.