In địa chỉ hoặc con trỏ cho giá trị trong C


80

Tôi muốn làm một cái gì đó có vẻ khá đơn giản. Tôi nhận được kết quả nhưng vấn đề là, tôi không có cách nào để biết kết quả có chính xác hay không.

Tôi đang làm việc ở C và tôi có hai gợi ý; Tôi muốn in nội dung của con trỏ. Tôi không muốn tham chiếu đến con trỏ để nhận giá trị được trỏ vào, tôi chỉ muốn địa chỉ mà con trỏ đã lưu trữ.

Tôi đã viết đoạn mã sau và những gì tôi cần biết là nếu nó đúng và nếu không, làm thế nào tôi có thể sửa nó.

/* item one is a parameter and it comes in as: const void* item1   */
const Emp* emp1 = (const Emp*) item1; 

printf("\n comp1-> emp1 = %p; item1 = %p \n", emp1, item1 );

Trong khi tôi đăng bài này (và lý do điều quan trọng là nó chính xác) là cuối cùng tôi cần thực hiện việc này cho một con trỏ đến một con trỏ. Đó là:

const Emp** emp1 = (const Emp**) item1; 

Những gì bạn đã viết là chính xác, chính xác là bạn đang gặp phải vấn đề gì?
Luca Matteis

Như tôi đã mô tả, tôi đang nhận được kết quả nhưng không có cách nào để biết liệu kết quả có chính xác hay không hoặc nó có mang lại cho tôi một chút gì không. Don và những người khác bên dưới (cũng như chính bạn) đã xác nhận rằng những kết quả này là hợp lệ.
Frank V

Câu trả lời:


29

Những gì bạn có là chính xác. Tất nhiên, bạn sẽ thấy rằng emp1 và item1 có cùng giá trị con trỏ.


1
Chúng sẽ không giống nhau nếu kiểu của item1 là một phần của đa kế thừa và / hoặc là tổ tiên của Emp, tùy thuộc vào cách trình biên dịch đưa ra từng lớp tạo nên kiểu của item1.
Jim Buck

2
@Jim: Thẻ "C" gợi ý ngược lại
Hasturkun

1
@Jim: Hasturkun nói đúng. Tôi đang làm việc ở C. Tôi lẽ ra nên đăng cái đó.
Frank V

39

Để in địa chỉ trong con trỏ tới con trỏ:

printf("%p",emp1)

để bỏ qua một lần và in địa chỉ thứ hai:

printf("%p",*emp1)

Bạn luôn có thể xác minh bằng trình gỡ lỗi, nếu bạn đang sử dụng linux dddvà bộ nhớ hiển thị, hoặc đơn giản gdb, bạn sẽ thấy địa chỉ bộ nhớ để bạn có thể so sánh với các giá trị trong con trỏ của mình.


16

Tôi tin rằng điều này sẽ đúng nhất.

printf("%p", (void *)emp1);
printf("%p", (void *)*emp1);

printf()là một hàm đa dạng và phải được truyền các đối số đúng loại. Tiêu chuẩn nói rằng %pmất void *.


Tôi sẽ tưởng tượng họ được thăng chức? Không chắc chắn, ai đó có thể làm rõ?
RastaJedi

4
Sau một số nghiên cứu, không, chúng không tự động được thăng cấp. Một diễn viên void *thực sự được yêu cầu.
RastaJedi

10

Vì dường như bạn đã giải quyết được cách hiển thị địa chỉ con trỏ cơ bản, đây là cách bạn kiểm tra địa chỉ của con trỏ kép:

char **a;
char *b;
char c = 'H';

b = &c;
a = &b;

Bạn sẽ có thể truy cập địa chỉ của con trỏ kép abằng cách thực hiện:

printf("a points at this memory location: %p", a);
printf("which points at this other memory location: %p", *a);

printf("which contains this value: %c\n" **a);chỉ muốn thêm điều đó ^. ^.
RastaJedi

4
char c = 'A';
printf("ptr: %p,\t value: %c,\t and also address: %zu",&c, c,&c);

kết quả:

ptr: 0xbfb4027f, value: A, và cả địa chỉ: 3216245375


0

Tôi đã ở vị trí này, đặc biệt là với phần cứng mới. Tôi khuyên bạn nên viết một quy trình kết xuất hex nhỏ của riêng bạn. Bạn sẽ có thể xem dữ liệu và địa chỉ của chúng, được hiển thị cùng nhau. Đó là một thực hành tốt và một người xây dựng sự tự tin.


3
với cái giá là nghe có vẻ thiếu hiểu biết - bạn có thể giải thích thêm về cách người ta viết một thói quen như vậy không?
Faisal Vali

1
Ngoài ra câu trả lời này có thể phù hợp hơn như một bình luận?
RastaJedi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.