2016-02-19 23 views
5

Vì vậy, tôi đã xem một vài ví dụ về cách có thể tìm thấy tính cuối của kiến ​​trúc. Giả sử chúng ta có một con trỏ nguyên trỏ đến một kiểu dữ liệu int. Và giả sử giá trị int là 0x010A0B12. Trong một chút kiến ​​trúc cuối cùng, byte ít quan trọng nhất, tức là, 12, sẽ được lưu trữ trong địa chỉ bộ nhớ thấp nhất, phải không? Vì vậy, byte thấp nhất trong một số nguyên 4 byte sẽ là 12.Nhập con trỏ char vào con trỏ nguyên

Bây giờ, trên séc. Nếu chúng ta khai báo một con trỏ char, và gõ cast con trỏ nguyên vào một char * và lưu nó vào p, và in giá trị dereferenced của p, chúng ta sẽ nhận được một đầu mối về endianness của kiến ​​trúc. Nếu đó là 12, chúng ta sẽ rất ít người kết thúc; 01 biểu thị người lớn cuối cùng. Điều này nghe có vẻ thực sự gọn gàng ...

int a = 0x010A0B12; 
int *i = &a; 
char *p = (char*)i; 
printf("%d",*p); // prints the decimal equivalent of 12h! 

Vài câu hỏi ở đây, thực sự. Vì con trỏ được đánh máy mạnh, không phải con trỏ ký tự sẽ trỏ tới một kiểu dữ liệu char? Và những gì với in ấn với% d? Chúng ta không nên in với% c, cho nhân vật?

+0

Related: http://stackoverflow.com/questions/34826036/confused-about-pointer-dereferencing?noredirect = 1 & lq = 1 –

Trả lời

6

Vì con trỏ được nhập mạnh, không phải con trỏ ký tự sẽ trỏ đến loại dữ liệu char?

C có quy tắc rằng bất kỳ con trỏ nào cũng có thể được chuyển đổi an toàn thành char* và thành void*. Chuyển đổi một int* thành char*, do đó, được cho phép, và nó cũng là di động. Con trỏ sẽ trỏ đến byte ban đầu của biểu diễn bên trong của int.

Chúng ta không nên in bằng %c, cho ký tự?

Một thứ khác ở đây: danh sách đối số có độ dài thay đổi là printf. Khi bạn chuyển một số char đến thông số không được nhập của printf, chuyển đổi mặc định sẽ áp dụng: char được chuyển đổi thành int. Đó là lý do tại sao định dạng %d lấy số chỉ tốt và in ra như bạn mong đợi.

Bạn cũng có thể sử dụng %c. Mã xử lý thông số %c đọc đối số dưới dạng int và sau đó chuyển đổi thành số char. Tuy nhiên, 0x12 là một ký tự đặc biệt, vì vậy bạn sẽ không thấy bản in đồng nhất cho nó.

+0

Cảm ơn, mặc dù, "tham số không được phân loại của printf" mà bạn đang nói đến là gì? – nirvanaswap

+0

@nirvanaswap Ba dấu chấm '...' ở cuối chữ ký 'in', nghĩa là' int printf (const char * format, ...) 'chỉ định rằng bạn có thể chuyển các đối số bổ sung của bất kỳ loại nào. – dasblinkenlight

-2

Vì con trỏ được nhập mạnh, không phải con trỏ ký tự sẽ trỏ đến loại dữ liệu char?

Đây là loại hành vi không xác định - nhưng như vậy hầu hết các triển khai lành mạnh sẽ làm điều bạn muốn nói. Vì vậy, hầu hết mọi người sẽ nói ok với nó.

Và có chuyện gì với in bằng% d?

Định dạng% d đối số dự đoán của loại int và giá trị thực tế của loại char được thăng cấp theo quy tắc C thông thường. Vì vậy, điều này là ok một lần nữa. Bạn có thể không muốn sử dụng% c vì nội dung của byte được trỏ bởi p có thể là bất kỳ byte nào, không phải lúc nào cũng là một ký tự văn bản hợp lệ.

+1

Tôi dereferencing nó, vì vậy rõ ràng% p không phải là những gì tôi đang tìm kiếm phải không? – nirvanaswap

+2

Không có hành vi không xác định trong mã OP. – dasblinkenlight

+0

@nirvanaswap: vâng, xin lỗi, tôi đã chỉnh sửa nội dung này. Để dasblinkenlight: Có hành vi không xác định, đó là giả định rằng bất kỳ byte trong bộ nhớ có thể được giải quyết riêng và truy cập. Thông thường điều này là đúng, nhưng hãy tưởng tượng rằng OP cố gắng truy cập vào một byte giữa trong (nói) 32-bit phần cứng đăng ký có thể được đọc chỉ là toàn bộ 32 bit và tại địa chỉ liên kết chỉ. Nó sẽ gây ra ngoại lệ thời gian chạy. – ddbug

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