2011-12-14 34 views
6

Tôi có một đoạn mã được viết bằng C trong đó một số số học con trỏ được thực hiện. Tôi muốn biết làm thế nào đầu ra đến được điều này?Đầu ra của chương trình này ra sao?

#include <stdio.h> 
int main() 
{ 
    char arr[] = "gookmforgookm"; 
    char *ptr1 = arr; 
    char *ptr2 = ptr1 + 3; 
    printf ("ptr2 - ptr1 = %d\n", ptr2 - ptr1); 
    printf ("(int*)ptr2 - (int*) ptr1 = %d", (int*)ptr2 - (int*)ptr1); 
    getchar(); 
    return 0; 
} 

Output là dưới đây:

ptr2 - ptr1 = 3 
(int*)ptr2 - (int*) ptr1 = 0 
+1

thú vị. Tôi sẽ cố gắng tìm một giải pháp. +1 – ApprenticeHacker

Trả lời

6

Nói đúng, bạn đang gọi hành vi không xác định và bất kỳ kết quả nào mà chương trình tạo ra đều OK theo tiêu chuẩn C.

Tuy nhiên, có thể bạn đang ở trên máy nơi sizeof(int) == 4 (ngược lại với câu nói 2). Vì có 4 byte cho một số nguyên, hai địa chỉ cách nhau 3 byte là một phần của cùng một số nguyên, do đó sự khác biệt giữa các địa chỉ là 0 * sizeof(int). Bạn có thể tìm thấy một câu trả lời khác nếu bạn chọn ptr1 = arr + 1; hoặc bạn có thể không. Nhưng đó là vẻ đẹp của hành vi không xác định - nó sẽ là 'đúng' một trong hai cách.

+0

Nó sẽ không phải là _wrong_ một trong hai cách? :) – Lundin

0

Khi bạn trừ hai con trỏ, miễn là họ chỉ vào cùng một mảng, kết quả là số phần tử tách chúng.

Pointer Subtraction and Comparison

+0

Tôi quan tâm hơn đến việc tìm kiếm câu trả lời cho phần thứ hai !! –

4

Sau khi trừ bạn cần phải phân chia kết quả trong kích thước của các loại nhọn.

(int*)ptr2 - (int*)ptr1 == (0x1000003 - 0x1000000)/sizeof(int) 
(int*)ptr2 - (int*)ptr1 == (0x1000003 - 0x1000000)/4 == 0 
+0

Cảm ơn @MByD Nhưng giả sử statment của tôi giống như printf này ("(char *) ptr2 - (char *) ptr1 =% d", (char *) ptr2 - (char *) ptr1); và ptr1 và ptr2 thuộc loại int lúc bắt đầu sau đó chúng ta sẽ phân chia hoặc bỏ qua? –

1

ptr1ptr2 đều char * loại, có nghĩa là một byte một con trỏ.

char *ptr2 = ptr1 + 3; 

nên

ptr2 - ptr1 = 3 

Tiếp theo, bạn cast cả con trỏ đến gõ int *, int loại cần 4 byte, vì vậy cả hai mục tiêu trỏ cùng int, cả hai con trỏ có cùng giá trị thông qua các class nhớ , bạn sẽ nhận được kết quả 0.

0

Địa chỉ bộ nhớ của các phần tử của cùng một mảng luôn là tuần tự. tức là nếu địa chỉ bộ nhớ của myarray [0] là:

0x4000000 

sau đó địa chỉ bộ nhớ của myarray [2] chắc chắn sẽ

0x4000002 

Vì vậy, khi bạn lưu trữ các địa chỉ của arr vào ptr1 giả nó là x và sau đó khi bạn đặt địa chỉ ptr2, ba đơn vị cao hơn so với ptr1, nó sẽ là x + 3. Vì vậy, khi bạn trừ đi ptr1 từ ptr2 câu trả lời sẽ là:

(x 3) - x = 3

Do đó câu trả lời.

Trong giây printf() tuyên bố, nếu bạn muốn nó hiển thị kết quả tương tự như trên (3), bạn phải chuyển đổi con trỏ để int và không int*.

char *myvar; // given contents somewhere 
int addr = (int)myvar; // addr now = the char pointer 

Vì vậy, Trong trường hợp của bạn:

printf ("(int)ptr2 - (int) ptr1 = %d", (int)ptr2 - (int)ptr1); 
Các vấn đề liên quan