{"id":13,"date":"2020-09-03T23:55:40","date_gmt":"2020-09-03T23:55:40","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=13"},"modified":"2021-07-14T00:43:02","modified_gmt":"2021-07-14T00:43:02","slug":"understanding-pointers","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=13","title":{"rendered":"Understanding Pointers"},"content":{"rendered":"\n<p>Every variable in a firmware has a name and a value associated with it. When a variable is declared, a specific block of memory within the microcontroller is allocated to hold the value of that variable. The size of the allocated block depends on the data type.<\/p>\n\n\n\n<p>This works the same way with computers.<\/p>\n\n\n\n<p> Consider the following statement.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bohobiom.com\/wp-content\/uploads\/2020\/01\/Slide15-1024x576.jpg\" alt=\"\" class=\"wp-image-337\" width=\"689\" height=\"388\"\/><\/figure><\/div>\n\n\n\n<p> When this statement executes, the compiler sets aside 1 byte or 8-bits of memory to hold the value 10.<\/p>\n\n\n\n<p>It also sets up a symbol table in which it adds the symbol x and the relative address in the memory X where that 1 byte was set aside.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Thus every\nvariable has a value and also a memory location commonly known as address\nassociated with it.<\/p>\n\n\n\n<p>Lets use the term rvalue, meaning real value to denote the variable and the term lvalue, meaning location value to denote the address of the variable.<\/p>\n\n\n\n<p>The rvalue appears\non the right side of the assignment statement (10 in the above statement)<\/p>\n\n\n\n<p>and cannot be\nused on the left side of the assignment statement.<\/p>\n\n\n\n<p>This brings us\nto pointers. A pointer is a variable that contains the memory location of\nanother variable.<\/p>\n\n\n\n<p>Therefore, a\npointer is a variable that represents the location of a data item, such as a<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"http:\/\/bohobiom.com\/wp-content\/uploads\/2020\/01\/Slide19-1024x576.jpg\" alt=\"understanding_pointers\" class=\"wp-image-339\"\/><\/figure>\n\n\n\n<p>variable or an\narray element. We use pointers quite a lot in C.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Pointers are used to pass information back and forth between\nfunctions.<\/li><li>Pointers enable the programmers to return multiple data items from a\nfunction via function<\/li><\/ul>\n\n\n\n<p>arguments.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Pointers provide an alternate way\nto access the individual elements of an array.<\/li><li>Pointers are used to pass arrays\nand strings as function arguments. We will discuss this in<\/li><\/ul>\n\n\n\n<p>subsequent\nchapters.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Pointers are used to create\ncomplex data structures, such as trees, linked lists, linked stacks,linked\nqueues, and graphs.<\/li><\/ul>\n\n\n\n<ul class=\"wp-block-list\"><li>Pointers are used for the dynamic\nmemory allocation of a variable.<\/li><\/ul>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bohobiom.com\/wp-content\/uploads\/2020\/01\/Slide18-1024x576.jpg\" alt=\"pointer_arithmetic\" class=\"wp-image-338\" width=\"696\" height=\"392\"\/><\/figure><\/div>\n\n\n\n<p>In these\nexamples a pointer variable is declared to point to a variable of the specified\ndata type.<\/p>\n\n\n\n<p>Although all\nthese pointers <\/p>\n\n\n\n<p>point to\ndifferent data types,<\/p>\n\n\n\n<p>they will\noccupy the same amount of space in the memory.<\/p>\n\n\n\n<p>t how much\nspace they will occupy<\/p>\n\n\n\n<p>will depend on the platform where the code is going to run. On ARM microcontrollers they will occupy 4bytes, in other words 32-bits. Remember 1 byte is equal to 8-bits.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bohobiom.com\/wp-content\/uploads\/2020\/01\/Slide23-1024x576.jpg\" alt=\"pointers\" class=\"wp-image-340\" width=\"704\" height=\"395\"\/><\/figure><\/div>\n\n\n\n<p>In this\nstatement, ptr is the name of the pointer variable. The * informs the compiler\nthat<\/p>\n\n\n\n<p>ptr is a\npointer variable and the int32_t<\/p>\n\n\n\n<p>specifies that\nit will store the address of a 32-bit&nbsp;\ninteger variable.<\/p>\n\n\n\n<p>A 32-bit\ninteger pointer variable, therefore, \u2018points to\u2019 a 32-bit integer variable. In\nthe last statement,<\/p>\n\n\n\n<p>ptr is assigned\nthe address of x. The &amp; operator retrieves the lvalue (meaning address) of\nx, and copies that to the<\/p>\n\n\n\n<p>contents of the pointer ptr. Consider the memory cells<\/p>\n\n\n\n<p>Lets take a\nlook at this diagram. Since x is a 32-bit&nbsp;\nor 4-bytes integer variable it will be allocated 4byts of memory. Assuming\nthat the compiler<\/p>\n\n\n\n<p>assigns it\nmemory locations 1003,1004,1005 and 1006,<\/p>\n\n\n\n<p>the address of\nx (written as &amp;x) is equal to 1003, that<\/p>\n\n\n\n<p>is the\nstarting address of x in the memory. When we write, ptr = &amp;x, then ptr =\n1003.<\/p>\n\n\n\n<p>We can\n\u2018dereference\u2019 a pointer, meaning, we can refer to the value of the variable to\nwhich it points<\/p>\n\n\n\n<p>by using the unary * operator as in *ptr. That is, *ptr = 10, since 10 is the value of x.<\/p>\n\n\n\n<p>Like other\nvariables, pointer variables can also be used in expressions. For instance, if\nptr1 and ptr2 are pointers, then following statements here are valid.<\/p>\n\n\n\n<p>We can add\nintegers or subtract integers from pointers as well as subtract one pointer\nfrom another.<\/p>\n\n\n\n<p>We can also\ncompare pointers by using relational operators in the expressions, such as, is\npointer1 &gt; pointer2 and so on.<\/p>\n\n\n\n<p>Postfix unary increment which is written as plus-plus and decrement which written as minus-minus operators have greater precedence than the dereference operator which is written as asterisk.<\/p>\n\n\n\n<p>Therefore, the expression *ptr++ is equivalent to *(ptr++), as plus-plus has greater operator precedence than asterisk. Thus, the expression will increase the value of ptr so that it now points to the next memory location. This means that the statement *ptr++ does not do the intended task. Therefore, to increment the value of the variable whose address is stored in ptr, we must write (*ptr)++.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/bohobiom.com\/wp-content\/uploads\/2020\/01\/Slide21-1024x576.jpg\" alt=\"void_pointer\" class=\"wp-image-341\" width=\"715\" height=\"404\"\/><figcaption><br><\/figcaption><\/figure><\/div>\n\n\n\n<p>A generic\npointer is a pointer variable that has void as its data type. The void pointer,\nor the generic<\/p>\n\n\n\n<p>pointer, is a\nspecial type of pointer that can point to variables of any data type. It is\ndeclared like<\/p>\n\n\n\n<p>a normal\npointer variable but using the<\/p>\n\n\n\n<p>keyword as the\npointer\u2019s data type. Like this is :<\/p>\n\n\n\n<p>Anim1:<\/p>\n\n\n\n<p>Since we\ncannot have a variable of type void, the void pointer will therefore not point\nto any data and, thus cannot be dereferenced. We need to cast a void pointer to\nanother kind of pointer before using it.<\/p>\n\n\n\n<p>We use this\ntype of pointer when we want a pointer to point to data of different types at\ndifferent times.<\/p>\n\n\n\n<p>We can also use pointers that point to pointers. The pointers in turn point to data or even other pointers. To declare pointers to pointers, we simply need to add an asterisk for each level of reference.<\/p>\n\n\n\n<p>If we assume\nthe memory locations of x,px and pxx are as shown in this diagram, then when we\nexecute asterisk-asterisk ppx we get the answer 10.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Every variable in a firmware has a name and a value associated with it. When a variable is declared, a specific block of memory within the microcontroller is allocated to hold the value of that variable. The size of the allocated block depends on the data type. This works the same way with computers. Consider [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[5],"class_list":["post-13","post","type-post","status-publish","format-standard","hentry","category-data-structures","tag-data-structures"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/13"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=13"}],"version-history":[{"count":6,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/13\/revisions"}],"predecessor-version":[{"id":19,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/13\/revisions\/19"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=13"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=13"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=13"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}