Truyền theo giá trị C++
Có hai phương pháp để truyền dữ liệu vào hàm trong ngôn ngữ C, tôi. e. , gọi theo giá trị và gọi theo tham chiếu Show
Hãy hiểu từng cuộc gọi theo giá trị và cuộc gọi theo tham chiếu trong ngôn ngữ c Gọi theo giá trị trong C
Hãy thử hiểu khái niệm gọi theo giá trị trong ngôn ngữ c bằng ví dụ dưới đây đầu raBefore function call x=100 Before adding value inside function num=100 After adding value inside function num=200 After function call x=100 Gọi theo giá trị Ví dụ. Hoán đổi giá trị của hai biếnđầu raBefore swapping the values in main a = 10, b = 20 After swapping values in function a = 20, b = 10 After swapping values in main a = 10, b = 20 Gọi theo tham chiếu trong C
Xem xét ví dụ sau cho cuộc gọi theo tham chiếu đầu raBefore function call x=100 Before adding value inside function num=100 After adding value inside function num=200 After function call x=200 Gọi theo tham chiếu Ví dụ. Hoán đổi giá trị của hai biếnđầu raBefore swapping the values in main a = 10, b = 20 After swapping values in function a = 20, b = 10 After swapping values in main a = 20, b = 10 Sự khác biệt giữa cuộc gọi theo giá trị và cuộc gọi theo tham chiếu trong cKhông. Gọi theo giá trị Gọi theo tham chiếu Một bản sao của giá trị được truyền vào hàm Một địa chỉ của giá trị được truyền vào hàm Những thay đổi được thực hiện bên trong hàm chỉ giới hạn trong hàm. Các giá trị của các tham số thực tế không thay đổi bằng cách thay đổi các tham số chính thức. Các thay đổi được thực hiện bên trong chức năng cũng xác thực bên ngoài chức năng. Các giá trị của các tham số thực sự thay đổi bằng cách thay đổi các tham số hình thức. 3Các đối số chính thức và thực tế được tạo ở các vị trí bộ nhớ khác nhau Các đối số chính thức và thực tế được tạo ở cùng một vị trí bộ nhớTheo nghĩa chặt chẽ nhất của từ này, mọi thứ trong C đều là giá trị truyền qua. Điều này thường gây nhầm lẫn cho những người mới bắt đầu lập trình C, đặc biệt khi nói đến con trỏ, mảng và cấu trúc. Vì vậy, chúng ta có ý gì khi nói truyền theo giá trị và truyền theo tham chiếu Khi chúng ta chuyển theo giá trị, chúng ta đang chuyển một bản sao của biến cho một hàm. Khi chúng ta chuyển qua tham chiếu, chúng ta đang chuyển một bí danh của biến cho một hàm. C có thể truyền một con trỏ vào một hàm nhưng đó vẫn là truyền theo giá trị. Nó đang sao chép giá trị của con trỏ, địa chỉ, vào hàm. Trong C++, một tham chiếu là bí danh cho một biến khác. C không có khái niệm này Trong C khi truyền một con trỏ, cú pháp yêu cầu áp dụng một dereference để lấy giá trị, trong khi ở các ngôn ngữ truyền qua tham chiếu thực sự như Pascal (tham số được khai báo bằng var) và C++ (tham số được khai báo bằng &), yêu cầu đó không . Sẽ đúng hơn nếu gọi cơ chế C là “chuyển tham chiếu”. Hãy xem bài viết wiki này giải thích thêm về Pass by Reference Hãy xem xét một số mã để làm rõ tất cả những điều này Truyền nguyên hàm cho các hàmHãy xem ví dụ cổ điển về hàm hoán đổi để chuyển nguyên hàm cho hàm C1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 void hoán đổi(int a, int b);
void hoán đổi(int a, int b) { int tmp = a; a = b; b = tmp; }
int chính() { int a = 1; int b = 2; printf("before swap a = %d\n", a); printf("before swap b = %d\n", b); hoán đổi(a, b); printf("after swap a = %d\n", a); printf("after swap b = %d\n", b); } Chạy nó và đầu ra trông như thế này before swap a = 1 before swap b = 2 after swap a = 1 after swap b = 2 Các giá trị giống nhau được in trước khi hàm hoán đổi được gọi và sau khi nó được gọi. Hàm hoán đổi không ảnh hưởng đến các biến a và b cục bộ của chúng tôi. Tại sao? . Đó là các bản sao được hoán đổi bên trong hàm chứ không phải các biến ban đầu Bây giờ hãy xem xét một chức năng hơi khác sử dụng con trỏ C1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 void hoán đổi(int *a, int *b);
void hoán đổi(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; }
int chính() { int a = 1; int b = 2; printf("before swap a = %d\n", a); printf("before swap b = %d\n", b); hoán đổi(&a, &b); printf("after swap a = %d\n", a); printf("after swap b = %d\n", b); } Chạy nó và đầu ra trông như thế này before swap a = 1 before swap b = 2 after swap a = 2 after swap b = 1 Trong ví dụ này, chúng tôi sử dụng địa chỉ của các biến a và b làm đầu vào cho hàm hoán đổi. Đầu ra cho thấy các giá trị a và b ban đầu đã được hoán đổi thành công. Mặc dù chúng tôi đang sử dụng con trỏ, đây vẫn là giá trị truyền qua. Các bản sao của các con trỏ tới các biến a và b đang được truyền vào hàm. Bản thân hàm thay đổi các giá trị tại các địa chỉ đó nhưng nó vẫn được truyền một bản sao của con trỏ vào hàm, đó là giá trị truyền qua Truyền cấu trúc cho hàmTruyền cấu trúc tương tự như truyền nguyên hàm. Nếu một cấu trúc được truyền cho một hàm, các byte của cấu trúc được sao chép dưới dạng tham số của hàm. Bất cứ điều gì được thực hiện với cấu trúc đó trong hàm sẽ thay đổi bản sao, không phải cấu trúc ban đầu C1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 struct foo { int chiều rộng; int chiều cao; };
void hoán đổi(struct foo input);
void hoán đổi(struct foo input) { int tmp = đầu vào.chiều rộng; đầu vào. chiều rộng = đầu vào. chiều cao; đầu vào. chiều cao = tmp; }
int chính() { struct foo first; đầu tiên. chiều rộng = 1; đầu tiên. chiều cao = 2; < printf("before swap first.chiều rộng = %d\ . n", first.chiều rộng); printf("before swap first.chiều cao = %d\ . n", first.chiều cao); hoán đổi(đầu tiên); printf("after swap first.chiều rộng = %d\ . n", first.chiều rộng); printf("after swap first.chiều cao = %d\ . n", first.chiều cao); } Bạn sẽ nhận được đầu ra before swap first.width = 1 before swap first.height = 2 after swap first.width = 1 after swap first.height = 2 Đầu ra cho thấy thể hiện cấu trúc ban đầu không bị thay đổi. Các byte của thể hiện cấu trúc đã được sao chép vào hàm. Chức năng hoạt động trên bản sao đó. Ví dụ cấu trúc ban đầu không thay đổi Điều gì xảy ra khi chúng ta sử dụng con trỏ tới cấu trúc? C1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 struct foo { int chiều rộng; int chiều cao; };
void hoán đổi(struct foo *input);
void hoán đổi(struct foo *input) { int tmp = đầu vào->width; đầu vào->width = input->height; đầu vào->height = tmp; }
int chính() { struct foo first; đầu tiên. chiều rộng = 1; đầu tiên. chiều cao = 2; < printf("before swap first.chiều rộng = %d\ . n", first.chiều rộng); printf("before swap first.chiều cao = %d\ . n", first.chiều cao); hoán đổi(&first); printf("after swap first.chiều rộng = %d\ . n", first.chiều rộng); printf("after swap first.chiều cao = %d\ . n", first.chiều cao); } Bây giờ đầu ra đã khác before swap first.width = 1 before swap first.height = 2 after swap first.width = 2 after swap first.height = 1 Sử dụng con trỏ, chúng tôi thấy rằng các giá trị trong cấu trúc ban đầu đã được hoán đổi thành công. Tương tự như nguyên thủy, một bản sao của con trỏ đã được chuyển vào hàm. Sau đó, hàm sử dụng con trỏ đó để hoán đổi các giá trị thành viên cấu trúc. Khi sử dụng con trỏ tới cấu trúc, chỉ giá trị con trỏ được sao chép và đây vẫn là giá trị truyền qua Truyền mảng cho hàmKhi một mảng được truyền cho một hàm, một con trỏ tới địa chỉ của phần tử đầu tiên của mảng được sao chép vào hàm. Không giống như các cấu trúc, việc truyền một mảng sẽ không sao chép tất cả các byte của mảng vào hàm. Chỉ con trỏ được sao chép C1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 void hoán đổi(int *nums);
void hoán đổi(int *nums) { int tmp = *nums; int *tiếp theo = nums + 1; *nums = *next; *tiếp theo = tmp; }
int chính() { int nums[3] = {1,2}; printf("before swap nums[0] = %d\n", nums[0]); printf("before swap nums[1] = %d\n", nums[1]); hoán đổi(số); printf("after swap nums[0] = %d\n", nums[0]); printf("after swap nums[1] = %d\n", nums[1]); } Đầu ra của cái này là ________số 8Ở đây, chúng tôi khởi tạo một mảng gồm hai int, in ra các giá trị của các chỉ số, chuyển mảng vào hàm hoán đổi và sau đó chúng tôi in lại các giá trị của các chỉ số. Những gì đang được truyền vào hàm hoán đổi là một bản sao của biến mảng, nghĩa là một bản sao địa chỉ của phần tử đầu tiên trong mảng. Sử dụng địa chỉ đó, hàm hoán đổi trao đổi các giá trị của chỉ mục thứ nhất và thứ hai của mảng. Đây vẫn là giá trị truyền qua vì địa chỉ là thứ được sao chép vào hàm hoán đổi Mặc dù về mặt kỹ thuật, có một cách để sao chép các byte của một mảng làm tham số cho một hàm, nhưng nó liên quan đến việc khởi tạo một mảng bên trong một cấu trúc và sau đó chuyển cấu trúc đó cho một hàm và theo ý kiến của tôi thì hơi phức tạp. Và ngay cả khi làm điều đó, nó vẫn là giá trị truyền qua về mặt kỹ thuật Phần kết luậnTôi hy vọng bài đăng này đã giúp làm rõ cách mọi thứ được truyền theo giá trị trong C. Như mọi khi tôi mở cho ý kiến và đề xuất C có sử dụng pass by value không?C luôn sử dụng 'truyền theo giá trị' để truyền đối số cho hàm (một thuật ngữ khác là 'gọi theo giá trị', có nghĩa giống như vậy), có nghĩa là mã trong một .
Truyền theo giá trị với ví dụ là gì?"Truyền theo giá trị" có nghĩa là bạn chuyển giá trị thực của biến vào hàm . Vì vậy, trong ví dụ của bạn, nó sẽ vượt qua giá trị 9. "Chuyển theo tham chiếu" có nghĩa là bạn chuyển chính biến đó vào hàm (không chỉ giá trị). Vì vậy, trong ví dụ của bạn, nó sẽ truyền một đối tượng số nguyên có giá trị là 9.
Giá trị đi qua là gì?Theo định nghĩa, truyền theo giá trị có nghĩa là bạn đang tạo một bản sao trong bộ nhớ của giá trị của tham số thực được truyền vào, một bản sao nội dung của tham số thực. Use pass by value when when you are only "using" the parameter for some computation, not changing it for the client program.
Có vượt qua giá trị sử dụng con trỏ trong C không?Trong C, tất cả các tham số hàm được truyền theo giá trị. Chỉ là một số giá trị có thể là con trỏ . |