{"id":263,"date":"2025-05-15T09:43:24","date_gmt":"2025-05-15T01:43:24","guid":{"rendered":"https:\/\/sy-blog.moe\/?p=263"},"modified":"2025-05-26T10:23:04","modified_gmt":"2025-05-26T02:23:04","slug":"eie111-lecture-2-%e6%8c%87%e9%92%88%e5%92%8c%e7%bb%93%e6%9e%84-pointer-and-structure","status":"publish","type":"post","link":"https:\/\/sy-blog.moe\/en\/263.html","title":{"rendered":"EIE111 Lecture 2 Pointer and Structure"},"content":{"rendered":"<h1 class=\"wp-block-heading\">Table of contents<\/h1>\n\n\n<ul class=\"lcp_catlist\" id=\"lcp_instance_0\"><li class=\"current\"><a href=\"https:\/\/sy-blog.moe\/en\/263.html\">EIE111 Lecture 2 Pointer and Structure<\/a><\/li><li><a href=\"https:\/\/sy-blog.moe\/en\/223.html\">EIE111 Lecture 11 Error Handling<\/a><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">What is an address?<\/h2>\n\n\n\n<p>In memory<em>(See<\/em><a href=\"https:\/\/zh.wikipedia.org\/wiki\/%E9%9A%8F%E6%9C%BA%E5%AD%98%E5%82%A8%E5%99%A8\" target=\"_blank\" rel=\"noreferrer noopener\" >Wikipedia<\/a><em>\uff09<\/em>In the memory, the smallest addressable unit is the byte. In order to operate memory efficiently, we introduce a unique address for each byte. Usually expressed in hexadecimal, such as 0x000001 (hexadecimal is usually expressed in<code>0x<\/code>At the beginning, used to distinguish, see<a href=\"https:\/\/stackoverflow.com\/questions\/2670639\/why-are-hexadecimal-numbers-prefixed-with-0x\" target=\"_blank\"  rel=\"nofollow\" >https:\/\/stackoverflow.com\/questions\/2670639\/why-are-hexadecimal-numbers-prefixed-with-0x<\/a>\uff09<\/p>\n\n\n\n<p>(For security reasons, in most cases, the address is not the real address in physical memory, but a virtual address assigned by the operating system)<\/p>\n\n\n\n<p>For example, you have a 4GiB memory stick with 2<sup>32<\/sup>Bytes (4 \u00d7 2<sup>10<\/sup> \u00d7 2<sup>10<\/sup> \u00d7 2<sup>10<\/sup>), so its address starts from 0 and goes to 2<sup>32<\/sup>-1. A 32-bit computer uses 32 bits for addressing, so a 32-bit computer can only support up to 4 GiB of memory; while a 64-bit computer uses 64-bit addresses, so its maximum memory is 2<sup>64<\/sup>Byte = 2<sup>24<\/sup>TiB = 2<sup>14<\/sup>PiB = 2<sup>4<\/sup>EiB = 17179869184 GiB<\/p>\n\n\n\n<p><em>Explanation of storage units: We use two different measurement methods, one is based on decimal, such as GB (Gigabyte) MB (Megabyte), the conversion method is 1GB = 1000MB; the other is based on binary, such as GiB (Gibibyte) MiB (Mebibyte), the conversion method is 1GiB = 2<sup>10<\/sup>MiB = 1024MiB. GB displayed in Windows is actually GiB. See<a href=\"https:\/\/en.wikipedia.org\/wiki\/Gigabyte\" target=\"_blank\"  rel=\"nofollow\" >https:\/\/en.wikipedia.org\/wiki\/Gigabyte<\/a><\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">pointer<\/h2>\n\n\n\n<p>Pointers are similar to variables, but they store addresses instead of specific values.<\/p>\n\n\n\n<p>Operators<\/p>\n\n\n\n<p><code>&amp;<\/code>Reference: used to obtain an address.<\/p>\n\n\n\n<p><code>*<\/code>Dereference: Get the contents.<\/p>\n\n\n\n<p>for example:<\/p>\n\n\n\n<pre class=\"wp-block-code cpp\" data-no-translation=\"\"><code>int myAge = 43;     \/\/ int\u53d8\u91cf<br>int* ptr = &amp;myAge;  \/\/ ptr\u662f\u4e00\u4e2a\u6307\u9488\u53d8\u91cf\uff0c\u5b58\u50a8\u4e86myAge\u7684\u5730\u5740<br><br>\/\/ \u8f93\u51faage\u7684\u503c (43)<br>printf(\"%d\\n\", myAge);<br><br>\/\/ \u8f93\u51famyage\u7684\u5730\u5740 (0x7ffe5367e044)<br>printf(\"%p\\n\", &amp;myAge);<br><br>\/\/ \u8f93\u51faptr\u5b58\u50a8\u7684\u5730\u5740 (0x7ffe5367e044)<br>printf(\"%p\\n\", ptr);<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">How do pointers work?<\/h3>\n\n\n\n<pre class=\"wp-block-code cpp\" data-no-translation=\"\"><code>int main(){\n    int num = 10;\n    int *p1, *p2;\n    p1 = &amp;num;\n    p2 = &amp;num;\n    *p1 = 20;\n    *p2 = 30;\n    cout &lt;&lt; &amp;num &lt;&lt; p1 &lt;&lt; p2 &lt;&lt; &amp;p1 &lt;&lt; &amp;p2;\n}<\/code><\/pre>\n\n\n\n<p>Output: 0x61fe1c, 0x61fe1c, 0x61fe10, 0x61fe08<\/p>\n\n\n\n<p>It can be seen from this that<strong>Pointers are also variables<\/strong>, the pointer also has its own address.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Pointers in arrays<\/h3>\n\n\n\n<p>Previously we used [] to access elements in an array. In fact, an array variable is a pointer to the first element of the array.<\/p>\n\n\n\n<pre class=\"wp-block-code cpp\" data-no-translation=\"\"><code>int a&#091;5] = {1, 2, 3, 4, 5};\ncout &lt;&lt; a &lt;&lt; endl; \/\/ \u8f93\u51fa\uff1a0x31e6fffc80\uff08\u6570\u7ec4\u9996\u4f4d\u7684\u5730\u5740\uff09\ncout &lt;&lt; *a &lt;&lt; endl; \/\/ \u8f93\u51fa\uff1a1\uff08\u6570\u7ec4\u9996\u4f4d\u7684\u503c\uff09\ncout &lt;&lt; a + 1 &lt;&lt; endl; \/\/ \u8f93\u51fa\uff1a0x31e6fffc84\ncout &lt;&lt; *(a + 1) &lt;&lt; endl; \/\/ \u8f93\u51fa\uff1a2<\/code><\/pre>\n\n\n\n<p>Pointers can also perform operations, for example, a+1 represents the second element of a, as shown above<\/p>\n\n\n\n<p>The offset caused by pointer operation (a+1 followed by address+4) is the size of the data type. Here a is of type int, so each array element occupies 4 bytes, and the offset is also 4 bytes.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Difference between pointer and array<\/h3>\n\n\n\n<p><strong>The array is a constant pointer<\/strong>, which means it cannot be modified (reassigned)<\/p>\n\n\n\n<pre class=\"wp-block-code cpp\" data-no-translation=\"\"><code>int numbers&#091;4] = {0, 1, 2, 3};\nint *p = numbers; \/\/ \u5408\u6cd5\np = p + 1; \/\/ \u5408\u6cd5\n\nnumbers = p; \/\/ \u9519\u8bef: array names cannot be reassigned<\/code><\/pre>\n\n\n\n<p>Use the sizeof() function to return the size of the array (occupied space) in Bytes<\/p>\n\n\n\n<pre class=\"wp-block-code cpp\" data-no-translation=\"\"><code>int a&#091;5] = {1, 2, 3, 4, 5};\ncout &lt;&lt; sizeof(a) &lt;&lt; endl; \/\/ \u8f93\u51fa: 20 \uff084Byte \u00d7 5\uff09<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Memory Operation<\/h2>\n\n\n\n<p>In the previous C, we used malloc to allocate memory space and free to release memory space. This method can also be used in C++.<\/p>\n\n\n\n<p>In C++, there are two new operators: new and delete, which have some new features<\/p>\n\n\n\n<pre class=\"wp-block-code cpp\" data-no-translation=\"\"><code>int * p1 = new int; \/\/allocate an int, default initializer (do nothing)\nint * p2 = new int(); \/\/allocate an int, initialized to 0\nint * p3 = new int(5); \/\/allocate an int, initialized to 5\nint * p4 = new int{};\/\/C++11 allocate an int, initialized to 0\nint * p5 = new int {5};\/\/C++11 allocate an int, initialized to 5\nStudent * ps1 = new Student; \/\/allocate a Student object, default initializer\n\/\/allocate a Student object, initialize the members\nStudent * ps2 = new Student {\"Yu\", 2020, 1}; \/\/C++11<\/code><\/pre>\n\n\n\n<p>For arrays:<\/p>\n\n\n\n<pre class=\"wp-block-code cpp\" data-no-translation=\"\"><code>\/\/allocate 16 int, default initializer (do nothing) \nint * pa1 = new int&#091;16];\n\/\/allocate 16 int, zero initialized \nint * pa2 = new int&#091;16]();\n\/\/allocate 16 int, zero initialized \nint * pa3 = new int&#091;16]{}; \/\/C++11\n\/\/allocate 16 int, the first 3 element are initialized to 1,2,3, the rest 0\nint * pa4 = new int&#091;16]{1,2,3}; \/\/C++11\n\n\/\/allocate memory for 16 Student objects, default initializer\nStudent * psa1 = new Student&#091;16];\n\/\/allocate memory for 16 Student objects, the first two are explicitly initialized\nStudent * psa2 = new Student&#091;16]{{\"Li\", 2000,1}, {\"Yu\", 2001,1}}; \/\/C++11\n<\/code><\/pre>\n\n\n\n<p>Use the delete keyword to release memory. For a single variable, use<code>delete<\/code>; For arrays, use<code>delete[]<\/code><\/p>\n\n\n\n<pre class=\"wp-block-code\" data-no-translation=\"\"><code>\/\/deallocate memory\ndelete p1;\n\/\/deallocate memory\ndelete ps1;\n\/\/deallocate the memory of the array\ndelete &#091;]pa2;\n\/\/deallocate the memory of the array, and call the destructors of all the elements\ndelete &#091;]psa2;\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Two-dimensional array<\/h2>\n\n\n\n<p>Since memory is linear, in C++ we use the following method (row-major layout) to store a two-dimensional array.<\/p>\n\n\n\n<p>Row-major order means that multidimensional arrays (such as two-dimensional arrays) are stored in memory row-first. That is, the elements of the array are stored in row order: all elements of the first row are stored first, then all elements of the second row, and so on.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"95\" src=\"https:\/\/sy-blog.moe\/wp-content\/uploads\/2025\/05\/1747271266-image-1024x95.png\" alt=\"\" class=\"wp-image-274\" srcset=\"https:\/\/sy-blog.moe\/wp-content\/uploads\/2025\/05\/1747271266-image-1024x95.png 1024w, https:\/\/sy-blog.moe\/wp-content\/uploads\/2025\/05\/1747271266-image-300x28.png 300w, https:\/\/sy-blog.moe\/wp-content\/uploads\/2025\/05\/1747271266-image-768x71.png 768w, https:\/\/sy-blog.moe\/wp-content\/uploads\/2025\/05\/1747271266-image.png 1246w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Definition: int A[3][3];<\/p>\n\n\n\n<p>If d has N rows and M columns, then d[i][j] is synonymous with ptr[i*M+j].<\/p>\n\n\n\n<p>We can also use A[1] to access the address of the first element in each row and use it as a one-dimensional array.<\/p>\n\n\n\n<pre class=\"wp-block-code cpp\" data-no-translation=\"\"><code>int a&#091;2]&#091;2] = {{1,2},{3,4}};\ncout &lt;&lt; a&#091;0] &lt;&lt; endl; \/\/ \u8f93\u51fa0x5f33dff750\ncout &lt;&lt; a&#091;1] &lt;&lt; endl; \/\/ \u8f93\u51fa0x5f33dff758<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Command Line Parameters<\/h1>\n\n\n\n<p>In practical usage, sometimes we need to pass parameters to a program. For example, when using the MinGW compiler, we add the -o parameter to specify the name of the executable file.<\/p>\n\n\n\n<pre class=\"wp-block-code cpp\" data-no-translation=\"\"><code>int main(int argc, char *argv&#091;]) {\n    cout &lt;&lt; argc &lt;&lt; endl;\n    for (int i = 0; i &lt; argc; i++) {\n        cout &lt;&lt; argv&#091;i] &lt;&lt; endl;\n    }\n    return 0;\n}<\/code><\/pre>\n\n\n\n<p>After compilation, run the following command in the command line:<\/p>\n\n\n\n<pre class=\"wp-block-code cmd\" data-no-translation=\"\"><code>PS C:\\Users\\sy\\Desktop\\test&gt; .\/a.exe arg1 arg2 arg3\n4\nC:\\Users\\sy\\Desktop\\test\\a.exe\narg1\narg2\narg3<\/code><\/pre>\n\n\n\n<p>It can be seen that the parameters entered in the command line are passed as arguments to the main function. The first parameter is the count, and the second parameter is a C-style string array. The first element represents the execution location, and the subsequent elements store the input parameters.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Data Structures<\/h1>\n\n\n\n<p>Todo<\/p>","protected":false},"excerpt":{"rendered":"Explore the mysteries of pointers and structures! Uncover the operation of memory addresses and master the core skills of pointer dereferencing. The relationship between arrays and pointers, new memory management operators, storage logic of two-dimensional arrays, and the passing of command line parameters reveal the underlying logic of data processing within the program.","protected":false},"author":1,"featured_media":753,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"emotion":"","emotion_color":"","title_style":"","license":"","footnotes":""},"categories":[24],"tags":[25],"class_list":["post-263","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cpp","tag-notes"],"_links":{"self":[{"href":"https:\/\/sy-blog.moe\/en\/wp-json\/wp\/v2\/posts\/263","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sy-blog.moe\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/sy-blog.moe\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/sy-blog.moe\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sy-blog.moe\/en\/wp-json\/wp\/v2\/comments?post=263"}],"version-history":[{"count":36,"href":"https:\/\/sy-blog.moe\/en\/wp-json\/wp\/v2\/posts\/263\/revisions"}],"predecessor-version":[{"id":312,"href":"https:\/\/sy-blog.moe\/en\/wp-json\/wp\/v2\/posts\/263\/revisions\/312"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/sy-blog.moe\/en\/wp-json\/wp\/v2\/media\/753"}],"wp:attachment":[{"href":"https:\/\/sy-blog.moe\/en\/wp-json\/wp\/v2\/media?parent=263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/sy-blog.moe\/en\/wp-json\/wp\/v2\/categories?post=263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/sy-blog.moe\/en\/wp-json\/wp\/v2\/tags?post=263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}