{"id":3969,"date":"2020-04-01T22:19:42","date_gmt":"2020-04-02T02:19:42","guid":{"rendered":"https:\/\/www.circuitcrush.com\/?p=3969"},"modified":"2021-06-30T13:49:47","modified_gmt":"2021-06-30T17:49:47","slug":"c-programming-tutorial-8-pointers-intro","status":"publish","type":"post","link":"https:\/\/www.circuitcrush.com\/c-programming-tutorial-8-pointers-intro\/","title":{"rendered":"An Intro to Pointers in C"},"content":{"rendered":"<p>Pointers in C are one of the most difficult things for many programmers to wrap their minds around and understand. I\u2019m no exception, so this C tutorial on pointers was a re-learning experience for me.<\/p>\n<p>Pointers are a powerful mechanism to work on any array data type. They are also one of the most dangerous tools a programmer can use and a source of a large share of frustrating programming bugs.<\/p>\n<p>In fact, some languages, like Java, have banned their use altogether.<\/p>\n<p>Also, arrays and pointers in C share many similarities, and can be used interchangeably in a lot of instances, as we\u2019ll soon see.<\/p>\n<p>In spite of all this, once you learn how to use pointers you\u2019ll be glad you took the time to do so.<\/p>\n<p><!--more--><\/p>\n<h1><strong>Pointers in C<br \/>\n<\/strong><\/h1>\n<h2><strong>What are Pointers?<br \/>\n<\/strong><\/h2>\n<p>A pointer in C is a variable whose value is a memory address. Pointers indirectly refer to (or point to) other variables or part of their contents. While a variable normally contains a specific value, a pointer contains the address of a variable that contains a specific value. So, a variable name directly references a value, and a pointer in C indirectly references a value. Figure 1 sheds some light on this concept.<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"size-full wp-image-3971 alignnone\" src=\"http:\/\/www.circuitcrush.com\/wp-content\/uploads\/Pointers-in-C.jpg\" alt=\"Pointers-in-C\" width=\"555\" height=\"250\" srcset=\"https:\/\/www.circuitcrush.com\/wp-content\/uploads\/Pointers-in-C.jpg 555w, https:\/\/www.circuitcrush.com\/wp-content\/uploads\/Pointers-in-C-300x135.jpg 300w, https:\/\/www.circuitcrush.com\/wp-content\/uploads\/Pointers-in-C-150x68.jpg 150w\" sizes=\"(max-width: 555px) 100vw, 555px\" \/><\/p>\n<p><strong><em>Figure 1: how pointers in C work. While variables directly reference a value (like \u201ccount\u201d directly references 7), pointers indirectly reference a variable by \u2018pointing to\u2019 the address of a variable (like \u201ccountPtr\u201d points to the variable \u201ccount\u201d which contains the value 7).<\/em><\/strong><\/p>\n<p>Pointers enable programs to create and manipulate dynamic data structures (data structures that grow and shrink) like queues, stacks, linked lists and more.<\/p>\n<p>Because the hardware instructions of computers and microcontrollers rely heavily on addresses, pointers enable you to express yourself in a way that is close to how the machine expresses itself. This makes programs with pointers efficient.<\/p>\n<p>Pointers also offer an efficient way to deal with arrays. In fact, arrays are simply pointers in disguise. More on this shortly.<\/p>\n<h2><strong>Declaring Pointers in C<br \/>\n<\/strong><\/h2>\n<p>Like other variables, you must declare a pointer before using it. For example, the declaration<\/p>\n<pre>int *pointing, number;<\/pre>\n<p>declares the variable <strong>pointing<\/strong> to be of type int. You can read the declaration to say \u201c<strong>pointing<\/strong> is a pointer to an integer.\u201d The variable <strong>number <\/strong>is just a standard integer, not a pointer to an integer. The asterisk (*) in the declaration applies only to <strong>pointing<\/strong>. Each variable you want to declare as a pointer needs to be preceded by an asterisk. So, if I want to declare two pointers, I need to do something like the example below.<\/p>\n<pre>int *ptr1, *ptr2;<\/pre>\n<p>The * is known as the indirection operator or the dereferencing operator. The type specification identifies the type of variable the pointer points to and the * identifies the variable itself as a pointer. It is not enough to say that a variable is a pointer; you need to tell the compiler what kind of variable the pointer points to. The reason for this is that different variable types take up different amounts of storage and some pointer operations (more on these later) need knowledge of that storage size.<\/p>\n<p>One thing to note is that using a space between the * and the name of the pointer is optional. Some programmers will use the space in a declaration (which I did not do) and omit it when dereferencing a pointer. If you\u2019re not sure what dereferencing means, we\u2019ll talk about it a bit later.<\/p>\n<p>You can use pointers to reference (or point to) floats, longs, chars, and a host of other data types, not just ints.<\/p>\n<p>Consider the declaration below.<\/p>\n<pre>char *broil; \/\/ broil is a pointer to a character variable<\/pre>\n<p>The value of what <strong>broil <\/strong>points to is of type char but what about <strong>broil<\/strong> itself? The value of <strong>broil <\/strong>is an address which many systems represent as an unsigned integer. However, don\u2019t think of a pointer as an integer type. You can do things with pointers you can\u2019t do with integers and vice versa. For example, you can divide one integer by another, but you can\u2019t divide one pointer by another. We\u2019ll talk about what kind of arithmetic you can do with pointers a bit later.<\/p>\n<h2><strong>The Address Operator<br \/>\n<\/strong><\/h2>\n<p>Before we venture deeper into the thickets of pointer forest, a few words on the address operator are in order.<\/p>\n<p>In many languages, the address of any given variable is the computer\u2019s business and the programmer does not get that information. However, in C you can access the address of a variable using the address operator which is an ampersand (&).<\/p>\n<p>Though you can print the address of a variable if you\u2019re really that curious about it that\u2019s not the main use of the address operator. Using the address operator with pointers in C gives you the ability to manipulate addresses and their contents symbolically.<\/p>\n<h3 style=\"text-align: center;\">Become the Maker you were born to be. Try <a href=\"https:\/\/learnarduinonow.com\">Arduino Academy<\/a> for FREE!<\/h3>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-4238\" src=\"https:\/\/www.circuitcrush.com\/wp-content\/uploads\/FB_Cover2.png\" alt=\"\" width=\"373\" height=\"142\" srcset=\"https:\/\/www.circuitcrush.com\/wp-content\/uploads\/FB_Cover2.png 828w, https:\/\/www.circuitcrush.com\/wp-content\/uploads\/FB_Cover2-300x114.png 300w, https:\/\/www.circuitcrush.com\/wp-content\/uploads\/FB_Cover2-150x57.png 150w, https:\/\/www.circuitcrush.com\/wp-content\/uploads\/FB_Cover2-768x292.png 768w\" sizes=\"(max-width: 373px) 100vw, 373px\" \/><\/p>\n<p>When followed by a variable name, the address operator gives the address of that variable. For example, <strong>&myHouse<\/strong> gives the memory address of the variable <strong>myHouse<\/strong>.<\/p>\n<p>Suppose we declare a pointer with the name <strong>ptr<\/strong>. We can write a statement like the one below:<\/p>\n<pre>ptr = &myHouse; \/\/ this assigns myHouse\u2019s address to ptr<\/pre>\n<p>We can say that <strong>ptr<\/strong> points to <strong>myHouse.<\/strong> However, the actual value of <strong>ptr <\/strong>is the memory address, in hexadecimal, of the variable <strong>myHouse<\/strong>. If you\u2019re unfamiliar with hexadecimal numbers I suggest you read <a href=\"https:\/\/www.circuitcrush.com\/hexadecimal-numbers-tutorial\/\" target=\"_blank\" rel=\"noopener noreferrer\">Breaking the Hex: Understanding Hexadecimal Numbers<\/a>.<\/p>\n<p>Let\u2019s say <strong>myHouse<\/strong> is an integer whose value is 1234. If we use the indirection operator, we can dereference pointer <strong>ptr<\/strong> this way:<\/p>\n<pre>num = *ptr \/\/ assigns value at location ptr to num<\/pre>\n<p>by doing this, we assign the value 1234 to <strong>num<\/strong>.<\/p>\n<p>Let\u2019s look at a simple program that swaps 2 numbers to demonstrate pointers and the address operator.<\/p>\n<pre>#include <stdio.h>\r\n\r\nvoid swapper (int *a, int *b);\u00a0\u00a0\u00a0\u00a0\u00a0 \/* function prototype. For a review on functions see <a href=\"https:\/\/www.circuitcrush.com\/c-programming-c-functions-5\/\" target=\"_blank\" rel=\"noopener noreferrer\">C Programming Tutorial 5<\/a> *\/\r\n\r\nint main (void)\r\n\r\n{\r\n int y = 10, z = 20;\r\n\r\n \u00a0\u00a0\u00a0 printf(\u201cFirst y = %d and z = %d. \\n\u201d, y, z);\r\n\r\n \u00a0\u00a0\u00a0 swapper (&y, &z);\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/* call function and send it addresses of y and z *\/\r\n\r\n \u00a0\u00a0\u00a0 printf(\u201cNow y = %d and z = %d. \\n\u201d, y, z);\r\n\r\n \u00a0\u00a0\u00a0 return 0;\r\n}\r\n\r\nvoid swapper (int *a, int *b) \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/* start the function definition *\/\r\n\r\n{\r\n \u00a0\u00a0\u00a0 int temp; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ temporary storage spot\r\n\r\n \u00a0\u00a0\u00a0 temp = *a; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/* dereferencing a so temp gets value a points to *\/\r\n\r\n \u00a0\u00a0\u00a0 *a = *b;\r\n\r\n \u00a0\u00a0\u00a0 *b = temp;\r\n}<\/pre>\n<p>Notice that instead of passing the explicit values of <strong>y<\/strong> and <strong>z<\/strong> we pass the addresses of <strong>y<\/strong> and <strong>z<\/strong> to swapper() which indirectly references the variables. Though C does not explicitly support <strong><em>pass by reference<\/em><\/strong>, this is a way to closely emulate it. However, C++ <em>does<\/em> support pass by reference, but this is a C tutorial so we shall say no more about that for now.<\/p>\n<p>Also, we need a third variable in the function definition to temporarily hold the value of integer <strong>a<\/strong>.<\/p>\n<p>Finally, it may be tempting to write something like<\/p>\n<pre>temp = a;<\/pre>\n<p>instead of<\/p>\n<pre>temp = *a;<\/pre>\n<p>But <strong>a<\/strong> has the value of <strong>&y<\/strong>, so it points to <strong>y<\/strong> which means <strong>*a<\/strong> gives the value of <strong>y<\/strong> (in other words, we\u2019re dereferencing <strong>a<\/strong>). If we don\u2019t use the indirection operator, we\u2019ll likely get a memory address rather than the value we want.<\/p>\n<h2><strong>Arrays and Pointers in C<br \/>\n<\/strong><\/h2>\n<p>Earlier we made the claim that arrays and pointers we basically the same thing. Let\u2019s talk a bit more about that.<\/p>\n<p>First, if you need a review on arrays in C, check out <a href=\"https:\/\/www.circuitcrush.com\/c-programming-tutorial-6-arrays-intro\/\" target=\"_blank\" rel=\"noopener noreferrer\">C Programming Tutorials 6<\/a> and <a href=\"https:\/\/www.circuitcrush.com\/c-programming-tutorial-7-arrays-2\/\" target=\"_blank\" rel=\"noopener noreferrer\">7<\/a> which discuss arrays.<\/p>\n<p>Believe it or not, an array name is also the address of the first element of the array. So, if swagger is an array, then the following is true:<\/p>\n<pre>swagger == &swagger[0]; \/\/ name of array is the address of the first element<\/pre>\n<p>Both <strong>swagger<\/strong> and <strong>&swagger[0]<\/strong> represent the memory address of the first element.<\/p>\n<p>Various systems and platforms use different amounts of bytes to represent different data types. For example, in the Arduino IDE an integer takes up 2 bytes but on some other system it may take up 4 bytes.<\/p>\n<p>This is one reason why you have to declare the sort of object to which a pointer points. The address is not enough because the computer needs to know how many bytes it needs to store the data type. Figure 2 gives a simplified graphical depiction of this concept for clarification.<\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-3972 alignnone\" src=\"http:\/\/www.circuitcrush.com\/wp-content\/uploads\/Pointers-and-Arrays.png\" alt=\"Pointers in C 2\" width=\"537\" height=\"279\" srcset=\"https:\/\/www.circuitcrush.com\/wp-content\/uploads\/Pointers-and-Arrays.png 537w, https:\/\/www.circuitcrush.com\/wp-content\/uploads\/Pointers-and-Arrays-300x156.png 300w, https:\/\/www.circuitcrush.com\/wp-content\/uploads\/Pointers-and-Arrays-150x78.png 150w\" sizes=\"(max-width: 537px) 100vw, 537px\" \/><\/p>\n<p><strong><em>Figure 2: pointer ptr pointing to an array of integers. Notice it contains the address of the first element, not the value of the first element. Here, each integer takes up 4 bytes, so the address of the first integer is 3000, the second is 3004 and so on. Other systems may use 2 byte integers in which case the second element of the array would have address 3002, the third 3004 and so on.<\/em><\/strong><\/p>\n<p>The take-away is that the value of a pointer is the address of the object to which it points. How the address is represented internally is hardware dependent. That\u2019s why we need to use data types when declaring pointers.<\/p>\n<p>The relationship between arrays and pointers means that you can often use either one when writing a program. They\u2019re usually interchangeable. However, there may be instances where using one over the other can yield benefits such as execution speed.<\/p>\n<p>To show this is the case, consider the following program that prints the number of days in each month.<\/p>\n<pre>#include <stdio.h>\r\n\r\n#define MONTHS 12\r\n\r\nint main(void)\r\n\r\n{\r\n int days[MONTHS] = {31,28,31,30,31,30,31,31,30,31,30,31};\r\n\r\n for (int i = 0; i < MONTHS; i++)\r\n\r\n printf(\"Month %d has %2d days.\\n\", i+1, days[i]);\r\n\r\n return 0;\r\n}<\/pre>\n<p>We can change the code within the <strong>main()<\/strong> function and accomplish the same result, as we can see below.<\/p>\n<pre>int main(void)\r\n\r\n{\r\n int days[MONTHS] = {31,28,31,30,31,30,31,31,30,31,30,31};\r\n\r\n for (int i = 0; i < MONTHS; i++)\r\n\r\n printf(\"Month %d has %2d days.\\n\", i+1, *(days + i)); \/\/ *(days + i) is same as days[i]\r\n\r\n return 0;\r\n}<\/pre>\n<p>We still use an array to hold the number of days in each month, but when we print the days, we use a pointer instead. The addition in the pointer may be confusing to some. Let\u2019s talk about that.<\/p>\n<h2><strong>Pointer Operations and Arithmetic<br \/>\n<\/strong><\/h2>\n<p>Pointers in C are valid operands in arithmetic expressions, assignment expressions and comparison expressions. But not all operators that normally work with other data types work with pointers. For example, you can\u2019t multiply one pointer by another.<\/p>\n<p>Let\u2019s talk about what you <em>can<\/em> do with pointers in C.<\/p>\n<h3><strong>Dereferencing Pointers <\/strong><\/h3>\n<p>As we already know, a pointer can be dereferenced which gives the value in the address it points to. To dereference a pointer, we use the indirection operator (a.k.a. dereferencing operator) which is an asterisk (*).<\/p>\n<p>There is one caveat to watch for when dereferencing pointers. Be careful not to dereference an uninitialized pointer. As an example, consider the code snippet below.<\/p>\n<pre>int *ptr; \/\/ uninitialized pointer\r\n\r\n*ptr = 100; \/\/ error<\/pre>\n<p>This is a big no-no because the second line of code is telling the compiler to store the value 100 in the location to which <strong>ptr<\/strong> points. But <strong>ptr<\/strong> is uninitialized and has a random value, so there is no knowing where the 100 will go. It might end up somewhere harmless, it may overwrite data or code, or it might cause the program to completely crash.<\/p>\n<h3><strong>Getting an Address<br \/>\n<\/strong><\/h3>\n<p>We already know that we can use the address operator to get the memory address of a variable. Like all variables, pointers also have an address. The & operator can tell you where the pointer itself is stored.<\/p>\n<h3><strong>Assignment<br \/>\n<\/strong><\/h3>\n<p>You can assign an address to a pointer. Usually, you do this by using an array name or by using the address operator (&). The code fragment below illustrates this.<\/p>\n<pre>int array1[5] = {1,2,3,4,5};\r\n\r\nint *ptr1;\r\n\r\nptr1 = array1; \/\/ assigns an address to pointer ptr<\/pre>\n<p>When doing this the address should be compatible with the pointer type. In other words, don\u2019t try to assign the address of a float to a pointer to an integer.<\/p>\n<h3><strong>Adding an Integer to a Pointer<br \/>\n<\/strong><\/h3>\n<p>As our example program that prints the number of days in each month shows, you can add an integer to a pointer, and this can be quite useful. You can also add a pointer to an integer. In either case, the integer is multiplied by the number of bytes in the data type the pointer points to (refer to figure 2), and the result is added to the original address. The code fragment below shows this.<\/p>\n<pre>int array1[5] = {1,2,3,4,5};\r\n\r\nint *ptr1, *ptr2;\r\n\r\nptr1 = array1; \/\/ assigns an address to pointer ptr\r\n\r\nptr2 = ptr1 + 4; \/\/same as &array1[4]\r\n\r\n*ptr2 = ?????<\/pre>\n<p>In the fragment above we dereference <strong>ptr2<\/strong> which gives us the fourth element of <strong>array1<\/strong> giving us a value of 4.<\/p>\n<p>There is one caveat to be aware of when adding integers to pointers. The result is undefined if it lies outside of the array into which the original pointer points, except that the address one past the end element of the array is guaranteed to be valid. So, using the code fragment above, if I write<\/p>\n<pre>ptr2 = ptr1 + 17;<\/pre>\n<p>the result is meaningless since the array only has five elements.<\/p>\n<p>Just as we can add an integer to\u00a0 pointer, we can also subtract integers from pointers. As is similar to the addition case, the integer is multiplied by the number of bytes in the data type the pointer points to and the result is subtracted from the original address. And, as in addition, the result is undefined if it lies outside of the array into which the original pointer points, except that the address one past the end element of the array is guaranteed to be valid.<\/p>\n<h3><strong>Incrementing and Decrementing Pointers in C<br \/>\n<\/strong><\/h3>\n<p>Programmers can use the ++ or – – operators to increment or decrement pointers just like other variables. This is useful when using pointers to step through loops. Incrementing a pointer to an array element makes it move to the next element of the array. Similarly, decrementing a pointer to an array element makes it move to the previous element of the array. Keep in mind that when doing either\/or the actual address of the pointer itself remains the same.<\/p>\n<p>Finally, you can use both the prefix and postfix forms of the increment and decrement operators.<\/p>\n<p>Consider the code fragment below.<\/p>\n<pre>int array1[5] = {5,4,3,2,1};\r\n\r\nint *ptr1;\r\n\r\nptr1 = array1; \/\/ assigns an address to pointer ptr\r\n\r\nptr1++;<\/pre>\n<p>In the example above <strong>ptr1<\/strong> was originally equal to the first element of the array (5) but at the end of the code it increments by one and is now equal to the second element of the array (4).<\/p>\n<p>One last thing to note is that pointer arithmetic is meaningless unless you use a pointer that points to an array. Do not assume that two variables are contiguous (next\/near to each other) in memory unless they are adjacent elements of an array.<\/p>\n<h3><strong>Differencing Pointers in C<br \/>\n<\/strong><\/h3>\n<p>You can find the difference between two pointers. Normally, you do this for two pointers to elements that are in the same array to find out how far apart the elements are. The result is in the same units as the type size. Note that if you subtract one pointer from another and they point to integers, and, say the result is 2, this indicates they are separated by 2 integers not necessarily by 2 bytes.<\/p>\n<p>Applying this operation to pointers to two different arrays might produce a value or could lead to a runtime error.<\/p>\n<h3><strong>Comparisons<br \/>\n<\/strong><\/h3>\n<p>You can use the relational operators to compare the values of two pointers if the pointers are of the same type and in the same array. Pointer comparisons compare the addresses in the pointers. Such a comparison may show, for example, that one pointer points to a higher numbered element of the array then the other. One common use is determining if a pointer points to nothing (i.e. it is 0).<\/p>\n<h2><strong>Pointing Isn\u2019t so Rude After All<br \/>\n<\/strong><\/h2>\n<p>So now we some basics about pointers in C and how to use them. We\u2019ve seen that they\u2019re not so hard to understand after all and can be very useful in your programs.<\/p>\n<p>As usual, this is a somewhat deep subject which is capable of filling several posts. Because of this, I\u2019m sure pointers will come up again in future C tutorials and other articles.<\/p>\n<p>Until then, drop a comment and tell me about your thoughts on pointers. Do you use them? Do you prefer arrays, pointers, or use both equally? Is there any important information concerning pointers I left out? I\u2019d love to hear from you!<\/p>\n<h2 style=\"text-align: center;\">Become the Maker you were born to be. Try <a href=\"https:\/\/learnarduinonow.com\">Arduino Academy<\/a> for FREE!<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-4238\" src=\"https:\/\/www.circuitcrush.com\/wp-content\/uploads\/FB_Cover2.png\" alt=\"\" width=\"504\" height=\"192\" srcset=\"https:\/\/www.circuitcrush.com\/wp-content\/uploads\/FB_Cover2.png 828w, https:\/\/www.circuitcrush.com\/wp-content\/uploads\/FB_Cover2-300x114.png 300w, https:\/\/www.circuitcrush.com\/wp-content\/uploads\/FB_Cover2-150x57.png 150w, https:\/\/www.circuitcrush.com\/wp-content\/uploads\/FB_Cover2-768x292.png 768w\" sizes=\"(max-width: 504px) 100vw, 504px\" \/><\/p>\n<a target=\"_blank\" href=\"https:\/\/www.drpeterscode.com\/index.php\"><img src=\"https:\/\/www.circuitcrush.com\/wp-content\/plugins\/dpabottomofpostpage\/apixel1x1.jpg\" ><\/a><table><\/table>","protected":false},"excerpt":{"rendered":"<p>Pointers in C are one of the most difficult things for many programmers to wrap their minds around and understand. I\u2019m no exception, so this C tutorial on pointers was a re-learning experience for me. Pointers are a powerful mechanism to work on any array data type. They are also one of the most dangerous […]<\/p>\n","protected":false},"author":1,"featured_media":3978,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[118],"tags":[116,176],"class_list":{"0":"post-3969","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-c-programming","8":"tag-c-programming","9":"tag-pointers","10":"entry"},"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/www.circuitcrush.com\/wp-content\/uploads\/Learn-Pointers-in-C.jpg","_links":{"self":[{"href":"https:\/\/www.circuitcrush.com\/wp-json\/wp\/v2\/posts\/3969","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.circuitcrush.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.circuitcrush.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.circuitcrush.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.circuitcrush.com\/wp-json\/wp\/v2\/comments?post=3969"}],"version-history":[{"count":5,"href":"https:\/\/www.circuitcrush.com\/wp-json\/wp\/v2\/posts\/3969\/revisions"}],"predecessor-version":[{"id":4252,"href":"https:\/\/www.circuitcrush.com\/wp-json\/wp\/v2\/posts\/3969\/revisions\/4252"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.circuitcrush.com\/wp-json\/wp\/v2\/media\/3978"}],"wp:attachment":[{"href":"https:\/\/www.circuitcrush.com\/wp-json\/wp\/v2\/media?parent=3969"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.circuitcrush.com\/wp-json\/wp\/v2\/categories?post=3969"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.circuitcrush.com\/wp-json\/wp\/v2\/tags?post=3969"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}