Trong C, bạn có thể truyền cả hai loại dữ liệu đơn giản như int
, float
và trỏ tới các loại này. Bây giờ tôi đã giả định rằng nếu bạn muốn chuyển đổi từ một con trỏ thành một loại thành giá trị của một loại khác (ví dụ: từ *float
đến int
), thứ tự truyền và dereferencing không thành vấn đề. I E. cho biến số float* pf
, bạn có (int) *pf == *((int*) pf)
. Sắp xếp như tính tương đối trong toán học ...Trong C, nếu tôi bỏ & dereference một con trỏ, nó có vấn đề gì tôi làm đầu tiên?
Tuy nhiên, điều này có vẻ không đúng. Tôi đã viết một chương trình thử nghiệm:
#include <stdio.h>
int main(int argc, char *argv[]){
float f = 3.3;
float* pf = &f;
int i1 = (int) (*pf);
int i2 = *((int*) pf);
printf("1: %d, 2: %d\n", i1, i2);
return 0;
}
và trên hệ thống của tôi đầu ra là
1: 3, 2: 1079194419
Vì vậy, đúc con trỏ dường như làm việc khác với đúc giá trị.
Tại sao lại như vậy? Tại sao các phiên bản thứ hai không làm những gì tôi nghĩ rằng nó nên?
Và điều này phụ thuộc vào nền tảng hay tôi bằng cách nào đó gọi hành vi không xác định?
Thông thường nó hiển thị dưới dạng vi phạm "bí danh nghiêm ngặt" dẫn đến việc đọc sai dữ liệu hoặc không có dữ liệu, ít nhất là trên gcc hiện đại. –
Nó không xuất hiện, nó là một vi phạm, và có, gcc thường cảnh báo bạn về nó (nó không bắt tất cả các trường hợp, afaik). Tôi nói nó không được xác định, tôi chỉ giải thích những gì xảy ra trong trường hợp của anh ấy - bạn có thể dễ dàng kiểm tra điều đó, ví dụ: với một đoạn trích nhỏ '[3.3] .pack ("f"). giải nén ("I") => [1079194419] ' – etarion
Chỉ để biết thông tin, chương trình ví dụ của tôi ở trên biên dịch mà không có cảnh báo trong' -Wall', vì vậy có, gcc không bắt tất cả các trường hợp ;-). – sleske