tek4

Tham chiếu trong C++

by - September. 26, 2021
Kiến thức
Học
<p>Tham chiếu trong C++ l&agrave; một trong những kh&aacute;i niệm quan trọng trong việc lập tr&igrave;nh. Trong b&agrave;i viết n&agrave;y, ta sẽ t&igrave;m hiểu về tham chiếu trong C++, c&aacute;ch hoạt động v&agrave; c&aacute;ch sử dụng n&oacute; một c&aacute;ch hiệu quả trong chương tr&igrave;nh.</p> <h1>Tham chiếu</h1> <p>Trong C ++, c&oacute; hai kiểu loại biến gồm:</p> <ol> <li>Một biến th&ocirc;ng thường l&agrave; một biến chứa gi&aacute; trị. V&iacute; dụ, ch&uacute;ng ta tạo một biến kiểu int, c&oacute; nghĩa l&agrave; biến đ&oacute; c&oacute; thể giữ gi&aacute; trị kiểu số nguy&ecirc;n.</li> <li>Con trỏ l&agrave; một biến lưu trữ địa chỉ của một biến kh&aacute;c. N&oacute; c&oacute; thể được tham chiếu bởi con trỏ để truy xuất gi&aacute; trị của n&oacute;.</li> </ol> <p>Ngo&agrave;i ra, c&oacute; một kiểu biến kh&aacute;c m&agrave; C++ cũng hỗ trợ, đ&oacute; l&agrave; tham chiếu, hoạt động gần giống với con trỏ. N&oacute; l&agrave; một biến hoạt động như một b&iacute; danh cho một biến kh&aacute;c. Trong lập tr&igrave;nh C ++, ta kh&ocirc;ng chỉ c&oacute; thể chuyển c&aacute;c gi&aacute; trị bằng c&aacute;ch tham chiếu đến một h&agrave;m m&agrave; c&ograve;n c&oacute; thể trả về một gi&aacute; trị bằng tham chiếu. Khi một biến được khai b&aacute;o l&agrave; một tham chiếu, n&oacute; sẽ trở th&agrave;nh một t&ecirc;n kh&aacute;c thay thế cho biến hiện c&oacute; (Đ&atilde; khai b&aacute;o). Một biến c&oacute; thể được khai b&aacute;o như một tham chiếu bằng c&aacute;ch sử dụng k&yacute; tự &amp; để khai b&aacute;o.</p> <p>Trước khi đi v&agrave;o b&agrave;i, bạn n&ecirc;n xem qua về biến to&agrave;n cục trong C++.</p> <p>V&iacute; dụ:</p> <pre class="language-cpp"><code>#include &lt;iostream&gt; using namespace std; int con_so; int&amp; phep_gan(); int main(){ phep_gan() = 1; cout &lt;&lt; con_so; return 0; } int&amp; phep_gan(){ return con_so; }</code></pre> <p>Kết quả:</p> <pre class="language-markup"><code>1</code></pre> <p>Trong chương tr&igrave;nh tr&ecirc;n, kiểu trả về của h&agrave;m phep_gan () l&agrave; kiểu int&amp;. Do đ&oacute;, h&agrave;m n&agrave;y sẽ trả về một tham chiếu của biến to&agrave;n cục con_so.</p> <p>C&acirc;u lệnh trả về l&agrave; return con_so;. Kh&ocirc;ng giống như trả về theo gi&aacute; trị, c&acirc;u lệnh n&agrave;y kh&ocirc;ng trả về gi&aacute; trị của con_so, m&agrave; n&oacute; trả về địa chỉ của con_so. V&igrave; vậy, khi biến được trả về, n&oacute; sẽ g&aacute;n một gi&aacute; trị được thực hiện trong c&acirc;u lệnh g&aacute;n phep_gan () = 1; Điều n&agrave;y sẽ truyền gi&aacute; trị 1 v&agrave;o biến con_so, được hiển thị tr&ecirc;n m&agrave;n h&igrave;nh.</p> <p><strong>Ch&uacute; &yacute;: H&agrave;m b&igrave;nh thường sẽ trả về gi&aacute; trị nhưng h&agrave;m n&agrave;y th&igrave; kh&ocirc;ng, n&oacute; trả về gi&aacute; trị địa chỉ. Do đ&oacute;, ta sẽ kh&ocirc;ng thể trả về một gi&aacute; trị hằng số cho h&agrave;m.</strong></p> <p>V&iacute; dụ: Đoạn m&atilde; b&ecirc;n dưới đ&acirc;y sẽ bị b&aacute;o c&oacute; lỗi</p> <pre class="language-cpp"><code>int &amp; phep_gan () { return 2; }</code></pre> <p>Ta kh&ocirc;ng thể trả về một biến cục bộ cho h&agrave;m.</p> <p>V&iacute; dụ: Đoạn m&atilde; b&ecirc;n dưới đ&acirc;y sẽ bị b&aacute;o lỗi</p> <pre class="language-cpp"><code>int &amp;phep_gan() { int a = 1; return a; }</code></pre> <h2>Đặc điểm của tham chiếu</h2> <p><em>1. Tham chiếu gi&uacute;p sửa đổi c&aacute;c tham số được truyền v&agrave;o trong một h&agrave;m: Nếu một h&agrave;m nhận được tham chiếu đến một biến, n&oacute; c&oacute; thể sửa đổi gi&aacute; trị của biến đ&oacute;.</em></p> <p>V&iacute; dụ:</p> <pre class="language-cpp"><code>#include&lt;iostream&gt; using namespace std; void phep_cong (int&amp; a, int&amp; b) { a++; b++; } int main() { int a = 2, b = 3; phep_cong(a,b); cout &lt;&lt; a &lt;&lt; " " &lt;&lt; b; return 0; }</code></pre> <p>Kết quả:</p> <pre class="language-markup"><code>3 4</code></pre> <p><em>2. Tham chiếu gi&uacute;p tr&aacute;nh việc phải sao ch&eacute;p c&aacute;c cấu tr&uacute;c c&oacute; k&iacute;ch thước lớn: Nếu một h&agrave;m phải nhận một đối tượng c&oacute; k&iacute;ch thước lớn v&agrave; ch&uacute;ng ta truyền n&oacute; l&agrave;m tham số m&agrave; kh&ocirc;ng sử dụng tham chiếu, một bản sao ch&eacute;p mới của đối tượng n&agrave;y sẽ được tạo ra, g&acirc;y l&atilde;ng ph&iacute; thời gian v&agrave; bộ nhớ của CPU.</em></p> <p>V&iacute; dụ:</p> <pre class="language-cpp"><code>#include&lt;iostream&gt; #include &lt;bits/stdc++.h&gt; using namespace std; struct sinh_vien { string ten; int ID_sv; }; void in_thong_tin(sinh_vien &amp;sv) { cout &lt;&lt; sv.ten &lt;&lt; " " &lt;&lt; sv.ID_sv; } int main() { sinh_vien sv; sv.ten = "Nguyen A"; sv.ID_sv = 1; in_thong_tin(sv); return 0; }</code></pre> <p>Kết quả:</p> <pre class="language-markup"><code>Nguyen A 1</code></pre> <p>Trong đoạn m&atilde; tr&ecirc;n, nếu ta kh&ocirc;ng sử dụng tham chiếu trong h&agrave;m void in_thong_tin(sinh_vien &amp;sv), tr&igrave;nh bi&ecirc;n dịch sẽ phải tạo một bản sao ch&eacute;p cho biến sv v&agrave; in ra th&ocirc;ng tin.</p> <p><em>3. Tham chiếu phải được khởi tạo ở thời điểm khai b&aacute;o</em></p> <p>V&iacute; dụ:</p> <pre class="language-cpp"><code>#include &lt;iostream&gt; using namespace std; int main() { int a = 21; int &amp;b = a; return 0; }</code></pre> <p>Trong đoạn m&atilde; tr&ecirc;n, nếu ta kh&ocirc;ng khởi tạo int &amp;b = a;, tr&igrave;nh bi&ecirc;n dịch sẽ b&aacute;o lỗi.</p> <p><em>4. Tham chiếu sau khi được g&aacute;n cho một biến, n&oacute; sẽ kh&ocirc;ng thể g&aacute;n được cho một biến kh&aacute;c</em></p> <p>V&iacute; dụ:</p> <pre class="language-cpp"><code>#include &lt;iostream&gt; using namespace std; int main() { int a = 21, c = 5; int &amp;b = a; &amp;b = c; return 0; }</code></pre> <p>Đoạn m&atilde; tr&ecirc;n sẽ bị b&aacute;o c&oacute; lỗi bởi, tham chiếu &amp;b đ&atilde; được g&aacute;n bởi biến a, do vậy khi ta thực hiện &amp;b = c; sẽ bị b&aacute;o lỗi trong chương tr&igrave;nh.</p> <h2>Sự kh&aacute;c biệt giữa tham chiếu v&agrave; con trỏ</h2> <p>Cả tham chiếu v&agrave; con trỏ đều c&oacute; thể được sử dụng để thay đổi c&aacute;c biến cục bộ của một h&agrave;m b&ecirc;n trong một h&agrave;m kh&aacute;c. Cả hai đều c&oacute; thể được sử dụng để nhằm tiết kiệm t&agrave;i nguy&ecirc;n trong việc sao ch&eacute;p c&aacute;c đối tượng c&oacute; k&iacute;ch thước lớn khi được truyền l&agrave;m đối số cho c&aacute;c h&agrave;m hoặc trả về từ c&aacute;c h&agrave;m. Tuy nhi&ecirc;n, ch&uacute;ng c&oacute; một số sự kh&aacute;c biệt sau:</p> <p><em>1. Một con trỏ c&oacute; thể được khai b&aacute;o l&agrave; void nhưng một tham chiếu th&igrave; kh&ocirc;ng bao giờ.</em></p> <p>V&iacute; dụ: Đoạn m&atilde; sau đ&acirc;y sẽ bị b&aacute;o c&oacute; lỗi.</p> <pre class="language-cpp"><code>#include &lt;iostream&gt; using namespace std; int main() { int a = 23; void *con_tro = &amp;a; //con trỏ void &amp;tham_chieu = a; //tham chiếu return 0; }</code></pre> <p><em>2. Con trỏ c&oacute; thể tham chiếu tới c&aacute;c biến kh&aacute;c sau khi n&oacute; tham chiếu tới một biến trước đ&oacute;. Tuy nhi&ecirc;n, tham chiếu th&igrave; kh&ocirc;ng.</em></p> <p>V&iacute; dụ: Đoạn m&atilde; dưới đ&acirc;y sẽ b&aacute;o c&oacute; lỗi bởi ta đ&atilde; g&aacute;n tham chiếu &amp;tham_chieu cho biến a, do đ&oacute; n&oacute; sẽ kh&ocirc;ng thể được g&aacute;n bởi biến c.</p> <pre class="language-cpp"><code>#include &lt;iostream&gt; using namespace std; int main() { int a = 23, b =1,c = 2; int *con_tro = &amp;b; //con trỏ con_tro = &amp;a; int &amp;tham_chieu = a; //tham chiếu &amp;tham_chieu = c; return 0; }</code></pre> <p><em>3. Tham chiếu kh&ocirc;ng được ph&eacute;p nhận gi&aacute; trị NULL. Nhưng, con trỏ c&oacute; thể được g&aacute;n với NULL để chỉ rằng ch&uacute;ng kh&ocirc;ng trỏ đến bất kỳ đối tượng n&agrave;o.</em></p> <p><em>4. Tham chiếu bắt buộc phải khởi tạo khi được khai b&aacute;o, con trỏ th&igrave; kh&ocirc;ng.</em></p> <p>Tr&ecirc;n đ&acirc;y l&agrave; kh&aacute;i niệm v&agrave; v&iacute; dụ cơ bản về tham chiếu trong C++. Hy vọng mọi người c&oacute; thể &aacute;p dụng v&agrave;o trong chương tr&igrave;nh của m&igrave;nh. Mọi người h&atilde;y tiếp tục theo d&otilde;i c&aacute;c b&agrave;i mới nhất tr&ecirc;n <a href="http://tek4.vn">tek4</a> nh&eacute;!</p>