2014-04-15 27 views
7

Con trỏ là một điều mới đối với tôi và tôi đang cố gắng để hiểu nó, nhưng tôi sẽ không cho và hy vọng tìm hiểu nó.Sự khác biệt giữa scanf ("% d", * p) và scanf ("% d", p) là gì?

Sự khác nhau giữa scanf ("%d", *p)scanf ("%d", p) là gì?

Trong ví dụ tôi thấy rằng nếu tôi muốn nhập một số giá trị trong một biến, tôi nên sử dụng scanf ("%d", p). Điều đó không có ý nghĩa với tôi. Không phải là scanf ("%d", *p)?

Tôi giải thích nó là: "đặt một số giá trị nguyên mà con trỏ trỏ tới" và ví dụ nó trỏ trên biến x và sau đó nó phải là x = 10, nhưng nó không phải là. Và làm thế nào để sử dụng scanf() và con trỏ để đặt giá trị trong một mảng?

Tôi đang gặp phải vấn đề gì và ở đâu? Tôi đang cố gắng học điều này bằng ngôn ngữ C, vì nó là thứ mà tôi phải sử dụng trong lớp của mình.

Ví dụ:

#include <stdio.h> 
int main() { 
    float x[10], *p; 
    int i; 
    p = &x[0]; 
    for (i = 0; i < 10; i++) { 
     scanf("%d", p + i); 
    } 
    for (i = 0; i < 10; i++) { 
     printf("%d", *(p + i)); 
    } 
    return 0; 
} 

Tại sao chỉ p + i trong for() {} đầu tiên và *(p + i) trong vòng lặp thứ hai? Tôi sẽ đặt *(p + i) cũng trong for() {} đầu tiên. *(p + i) với tôi giống như: "thành phần thứ (p + i) là gì và làm cho nó bằng một số giá trị".

+1

Có lẽ bạn nên thêm các loại ... – Deduplicator

+0

'p' là gì? Nếu 'p' không phải là một con trỏ, bạn nên sử dụng' scanf ("% d", & p) ' – slugonamission

+0

BTW: Kiểm tra giá trị trả về của' scanf() 'trước khi sử dụng những gì được hy vọng đọc. 'scanf ("% d ", p + i)! = 1) Rất tiếc();' – chux

Trả lời

18

*p phương tiện đi đến nơi p điểm để
&p phương tiện lấy địa chỉ của p, hoặc "có được một con trỏ đến" p

int i; 
scanf("%d", &i); // gives scanf a pointer to i 

int i; 
int *p = &i; 
scanf("%d", p); // a more contrived way to say the same thing 

Các nghĩa vụ giải thích thị giác là Pointer Fun with Binky.

Bạn có thể đọc các loại từ phải sang trái:

int *p => "p có kiểu int *" =>p là một con trỏ đến một int
int *p => "*p đã gõ int" =>*pint được trỏ đến bởi p

1

Nếu p là biến (giả sử, int), bạn sẽ sử dụng & p để chuyển con trỏ tới quétf. p một mình không phải là một con trỏ, và * p hợp chất vấn đề.

12

Một là đúng, điều còn lại là sai. (Hoặc cả hai có thể sai, tùy thuộc vào những gì p là.)

Nếu bạn gọi

scanf("%d", SOMETHING); 

sau đó SOMETHINGphải là một con trỏ đến một int.

Nếu bạn có một đối tượng int, sử dụng unary & để có được địa chỉ của nó (ví dụ, một con trỏ đến đối tượng):

int n; 
scanf("%d", &n); 

Nếu p sẽ xảy ra là một int*, sau đó bạn có thể sử dụng giá trị của nó:

int *p; 
scanf("%d", p); 

nhưng ở đây tôi đã không được gán một giá trị cho p, vì vậy đây biên dịch nhưng đã không xác định hành vi. Đây là ok:

int n; 
int *p = &n; 
scanf("%d", p); 

Đối với sử dụng *p, điều đó sẽ chỉ có giá trị nếu p là một con trỏ đến một con trỏ đến một int:

int n; 
int *p0 = &n; 
int **p = &p0; 
scanf("%d", *p); 

Nhưng nó sẽ hiếm khi làm cho tinh thần để làm điều đó. Phần lớn thời gian, đối số sẽ chỉ đơn giản là địa chỉ của một số đối tượng int, như &n.

Nếu n là một int, sau đó chỉ cần chuyển n đến scanf sẽ không có ý nghĩa. Bạn chỉ muốn chuyển giá trị hiện tại của n. Vấn đề là bạn muốn cho phép scanf lưu trữ một giá trị mới trong n và để làm điều đó, scanf cần có địa chỉ là n.

2

Cuộc gọi hàm trong đối số truyền C theo giá trị, không phải theo tham chiếu. Điều này có nghĩa là khi bạn gọi hàm với các đối số, hàm nhận được các bản sao của các đối số và hàm đó không thể sửa đổi trực tiếp các đối số ban đầu từ các cuộc gọi. Đó là:

int x = 42; 
foo(x); 
printf("%d\n", x); 

foo không thể thay đổi biến x, và mã sẽ luôn in 42.

Nhưng có nhiều trường hợp một hàm có thể muốn sửa đổi các đối số từ người gọi. scanf là một trong những trường hợp như vậy. Để thực hiện việc này, các chức năng này yêu cầu sử dụng mức độ gián đoạn. Thay vì chuyển biến được sửa đổi trực tiếp đến hàm, người gọi thay vì chuyển một con trỏ tới biến đó. Hàm này sau đó nhận được một bản sao của con trỏ, và bởi dereferencing nó, có thể truy cập và có thể sửa đổi biến nó trỏ đến.

Tôi khuyên bạn nên dành thời gian đọc Câu hỏi thường gặp về comp.lang.c. Chủ đề này đã được thảo luận trong:

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