2012-05-10 83 views
5

xác định biến float a, chuyển đổi thành phao & và int &, điều này có nghĩa là gì? Sau khi chuyển đổi, a là một tham chiếu của chính nó? Và tại sao hai kết quả lại khác nhau?Điều này có nghĩa là gì? (int &) a

#include <iostream> 
using namespace std; 
int 
main(void) 
{ 
    float a = 1.0; 
    cout << (float &)a <<endl; 
    cout << (int &)a << endl; 

    return 0; 
} 


thinkpad ~ # ./a.out 
1 
1065353216 
+0

Đây có phải là bài tập về nhà không? – caskey

Trả lời

14
cout << (float &)a <<endl; 
cout << (int &)a << endl; 

Người đầu tiên xử lý các bit trong một như đó là một phao. Điều thứ hai xử lý các bit trong một giống như nó là một int. Các bit cho phao 1.0 chỉ tình cờ lại là bit cho số nguyên 1065353216.

Đó là về cơ bản tương đương với:

float a = 1.0; 
int* b = (int*) &a; 
cout << a << endl; 
cout << *b << endl; 

(int &) a phôi a đến một tham chiếu đến một số nguyên. Nói cách khác, một tham chiếu số nguyên đến a. (Mà, như tôi đã nói, xử lý nội dung của một số nguyên.)

Chỉnh sửa: Tôi đang tìm kiếm ngay bây giờ để xem điều này có hợp lệ không. Tôi nghi ngờ rằng nó không phải. Nó phụ thuộc vào loại nhỏ hơn hoặc bằng kích thước thực tế.

+4

Thật thú vị.Tôi không biết rằng việc truyền tới một kiểu tham chiếu có hiệu quả tương đương với việc thực hiện một diễn giải diễn giải lại. –

+0

@OliCharlesworth Tôi không thể nói nếu bạn nghiêm túc hay mỉa mai, vì vậy hãy giải thích nếu bạn không nghiêm túc. (Tôi không chắc liệu điều này có hợp lệ hay không. Trước đây, tôi chưa bao giờ thấy một diễn viên tham chiếu đến một loại không liên quan. Tôi đang cố gắng tìm kiếm mọi thứ từ tiêu chuẩn nhưng không có nhiều may mắn.) Chỉnh sửa: Để làm rõ một chút, trong bài viết của tôi, tôi đang giải thích những gì đang xảy ra, không phải những gì được đảm bảo sẽ xảy ra. Tôi cho rằng tôi nên làm rõ điều đó trong câu trả lời. – Corbin

+0

bây giờ, phần đầu tiên tôi hiểu. nhưng phần thứ hai, (int &) a, tôi là một littel nhầm lẫn, bởi vì khi chúng ta định nghĩa một tham chiếu, chúng ta phải khởi tạo tham chiếu, đúng không? như int &a = b; nhưng trường hợp này, làm thế nào để giải thích? (int &) a bây giờ là một tham chiếu số nguyên, nhưng chúng ta không biết biến mà nó tham chiếu? –

2

Các giá trị khác nhau vì giải thích một float như một int & (tham chiếu đến int) ném những cánh cửa rộng mở. a không phải là int, vì vậy, hầu như mọi thứ có thể thực sự xảy ra khi bạn làm điều đó. Khi điều đó xảy ra, hãy xem số float như đó là một int cung cấp cho bạn 1065353216, nhưng tùy thuộc vào kiến ​​trúc máy cơ bản, nó có thể là 42 hoặc một con voi trong bộ tutu màu hồng hoặc thậm chí là hỏng.

Lưu ý rằng điều này không giống như truyền tới int, hiểu cách chuyển đổi từ float thành int. Truyền tới int & chỉ cần nhìn vào các bit trong bộ nhớ mà không hiểu ý nghĩa ban đầu là gì.

+0

Bạn có nói rằng đây là hành vi không xác định hoặc chỉ được xác định là được triển khai thực hiện? –

+0

@OliCharlesworth Tôi không biết anh ấy nói gì, nhưng tiêu chuẩn nói rõ ràng đó là hành vi không xác định. (Tiêu chuẩn cũng làm cho nó khá rõ ràng rằng mục đích là một thực hiện làm những gì một người quen thuộc với kiến ​​trúc của máy sẽ mong đợi. Điều gì trên một số kiến ​​trúc có thể có nghĩa là crashing cho một số giá trị dấu chấm động. nơi mà tôi mong đợi một con voi trong một tutu màu hồng, tuy nhiên.) –

+0

Tôi có nghĩa là nó không xác định hành vi, có.Các con voi trong tutu màu hồng là không, nhưng được cho phép theo tiêu chuẩn ... –

9

Nó có nghĩa là hành vi không xác định :-).

Nghiêm túc đấy, đây là một hình thức xảo quyệt. afloat, nhưng a cũng là một khối bộ nhớ (thường là bốn byte) với các bit trong đó. (float&)a có nghĩa là để xử lý khối bộ nhớ đó như thể nó là một float (nói cách khác, nó thực sự là gì); (int&)a có nghĩa là coi nó là int. Chính thức, truy cập một đối tượng (chẳng hạn như a) thông qua một biểu thức lvalue với một loại khác với loại thực tế của đối tượng là hành vi không xác định, trừ khi loại là một loại ký tự. Thực tế, nếu hai loại có cùng kích thước, tôi sẽ mong đợi kết quả là sự diễn giải lại mẫu bit.

Trong trường hợp của float, mẫu bit chứa bit cho dấu, số mũ và số nguyên. Thông thường,, số mũ sẽ sử dụng một số ký hiệu thừa, và chỉ 0.0 sẽ có 0 làm số mũ. (Một số biểu diễn, kể cả biểu diễn được sử dụng trên PC, sẽ không lưu trữ bit thứ tự cao của mantissa, vì ở dạng bình thường trong cơ số 2, nó luôn luôn là 1. Trong trường hợp đó, phần lưu trữ cho 1.0 sẽ có tất cả bit 0.) Cũng thường (và tôi không biết bất kỳ ngoại lệ nào ở đây), số mũ sẽ được lưu trữ trong các bit thứ tự cao. Kết quả là khi bạn "gõ pun" một giá trị dấu chấm động cho một số nguyên có cùng kích thước, giá trị sẽ khá lớn, bất kể giá trị dấu phẩy động.

+0

Nhưng viết tắt tương tự cho reinterpret_cast, Hoặc, tôi có sai không? –

+1

@VJovic Trong trường hợp này, nó là 'reinterpret_cast'. Bản thân chuyển đổi được xác định nhiều hơn hoặc ít hơn (không cung cấp ràng buộc liên kết). chuyển đổi là hành vi chính thức không xác định (nhưng mục đích là chúng làm những gì mà một người quen thuộc với kiến ​​trúc cơ bản mong đợi). –

Các vấn đề liên quan