Precedence, Parentheses, Pointers with iterative array functions












4















I'm teaching myself a little C and have run across an exercise that I want to make sure I understand completely. The exercise is asking me to pass a pointer to a multidimensional array of integers to a function and iterate through the array. So I started with a print function before moving on to one taking input to populate the array. I tried all sorts of things but after finding a bit of code on type casting and iterating pointers I have the below program that seems to work but I'm not quite understanding what is going on. In my comments I have questions labeled 1-3, referring to the questions below the code. I was hoping someone more intelligent than myself could enlighten me.



//passing multi-Array to a simple print function
#include <stdio.h>

//simple print function prototype
void printMyArr(int (*pt)[4]);

int main()
{
//declare and initialize a multi-array. I picked 4x4 and some arbitrary
//numbers for simplicity's sake

int myArr[4][4] = { {12, 16, 19, 20},
{5, 99, 102, 200},
{12, 20, 25, 600},
{65, 66, 999, 1000} };

//declare a pointer to an array of integers and an int for a loop counter
int (*pt)[4], counter;

//initialize the pointer
pt = myArr;

//for loop calling printMyArr function to iterate through arrays -- or this is what I understand it to mean
for(counter=0; counter<4; counter++)
printMyArr(pt++); //<-------------Question 1
return 0;
}

//function called to print array elements to the console
void printMyArr(int(*pt)[4])
{
//declare a counter....and apparently another pointer
int counter, *p;

//initialize new pointer to old pointer and type cast array as int
p = (int *)pt; //<-------------Question 2

//for loop to iterate through elements of array -- or this is what I understand it to mean
for(counter=0; counter<4; counter++)
printf("nnn%d", *p++); //<------Question 3
}


Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])? Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done, increment the pointer."?



Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?



Question 3: Am I correct thinking that I am incrementing each element here?



So



1: pass pointer as assigned -> myArr[0][0] then print the values in myArr[0][0], myArr[0][1], myArr[0][2], and myArr[0][3], then increment pointer myArr[1][0]



2: pass pointer as assigned ->myArr[1][0] then print the values in myArr[1][0], myArr[1][1], myArr[1][2] and myArr[1][3] increment pointer to myArr[2][0]



3: pass pointer as assigned ->myArr[2][0] then print the values in myArr[2][0], myArr[2][1], myArr[2][2] and myArr[2][3] increment pointer to myArr[3][0]



4: pass pointer as assigned ->myArr[3][0] then print the values in myArr[3][0], myArr[3][1], myArr[3][2] and myArr[3][3] increment pointer to myArr[4][0] and if this is the case what is the pointer pointing to since there shouldn't be a myArr[4][0]?










share|improve this question




















  • 2





    It's awesome to see such a thoroughly considered and well written question. Nicely done.

    – Daniel Farrell
    Jan 2 at 19:45








  • 1





    Understand, on access int myArr[3][5] the first level of indirection (e.g. the first [..]) is converted to a pointer to the first element in the array. With a 2D array the first element is a pointer to the first row (array). So it is converted (*myArr)[5] which is a pointer-to-array of int [5]. You can't just use *myArr[5] as [ ] binds tighter than '*' from a precedence standpoint which would result in an array-of-pointers to int (5 pointers). With (*myArr)[5] the pointer advances by 20-bytes (5-int) per-increment, with *myArr[5] the pointer advances by sizeof a_pointer.

    – David C. Rankin
    Jan 2 at 19:51








  • 2





    The reference in the standard is C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) (note the exceptions when it is NOT converted to a pointer)

    – David C. Rankin
    Jan 2 at 19:53
















4















I'm teaching myself a little C and have run across an exercise that I want to make sure I understand completely. The exercise is asking me to pass a pointer to a multidimensional array of integers to a function and iterate through the array. So I started with a print function before moving on to one taking input to populate the array. I tried all sorts of things but after finding a bit of code on type casting and iterating pointers I have the below program that seems to work but I'm not quite understanding what is going on. In my comments I have questions labeled 1-3, referring to the questions below the code. I was hoping someone more intelligent than myself could enlighten me.



//passing multi-Array to a simple print function
#include <stdio.h>

//simple print function prototype
void printMyArr(int (*pt)[4]);

int main()
{
//declare and initialize a multi-array. I picked 4x4 and some arbitrary
//numbers for simplicity's sake

int myArr[4][4] = { {12, 16, 19, 20},
{5, 99, 102, 200},
{12, 20, 25, 600},
{65, 66, 999, 1000} };

//declare a pointer to an array of integers and an int for a loop counter
int (*pt)[4], counter;

//initialize the pointer
pt = myArr;

//for loop calling printMyArr function to iterate through arrays -- or this is what I understand it to mean
for(counter=0; counter<4; counter++)
printMyArr(pt++); //<-------------Question 1
return 0;
}

//function called to print array elements to the console
void printMyArr(int(*pt)[4])
{
//declare a counter....and apparently another pointer
int counter, *p;

//initialize new pointer to old pointer and type cast array as int
p = (int *)pt; //<-------------Question 2

//for loop to iterate through elements of array -- or this is what I understand it to mean
for(counter=0; counter<4; counter++)
printf("nnn%d", *p++); //<------Question 3
}


Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])? Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done, increment the pointer."?



Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?



Question 3: Am I correct thinking that I am incrementing each element here?



So



1: pass pointer as assigned -> myArr[0][0] then print the values in myArr[0][0], myArr[0][1], myArr[0][2], and myArr[0][3], then increment pointer myArr[1][0]



2: pass pointer as assigned ->myArr[1][0] then print the values in myArr[1][0], myArr[1][1], myArr[1][2] and myArr[1][3] increment pointer to myArr[2][0]



3: pass pointer as assigned ->myArr[2][0] then print the values in myArr[2][0], myArr[2][1], myArr[2][2] and myArr[2][3] increment pointer to myArr[3][0]



4: pass pointer as assigned ->myArr[3][0] then print the values in myArr[3][0], myArr[3][1], myArr[3][2] and myArr[3][3] increment pointer to myArr[4][0] and if this is the case what is the pointer pointing to since there shouldn't be a myArr[4][0]?










share|improve this question




















  • 2





    It's awesome to see such a thoroughly considered and well written question. Nicely done.

    – Daniel Farrell
    Jan 2 at 19:45








  • 1





    Understand, on access int myArr[3][5] the first level of indirection (e.g. the first [..]) is converted to a pointer to the first element in the array. With a 2D array the first element is a pointer to the first row (array). So it is converted (*myArr)[5] which is a pointer-to-array of int [5]. You can't just use *myArr[5] as [ ] binds tighter than '*' from a precedence standpoint which would result in an array-of-pointers to int (5 pointers). With (*myArr)[5] the pointer advances by 20-bytes (5-int) per-increment, with *myArr[5] the pointer advances by sizeof a_pointer.

    – David C. Rankin
    Jan 2 at 19:51








  • 2





    The reference in the standard is C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) (note the exceptions when it is NOT converted to a pointer)

    – David C. Rankin
    Jan 2 at 19:53














4












4








4








I'm teaching myself a little C and have run across an exercise that I want to make sure I understand completely. The exercise is asking me to pass a pointer to a multidimensional array of integers to a function and iterate through the array. So I started with a print function before moving on to one taking input to populate the array. I tried all sorts of things but after finding a bit of code on type casting and iterating pointers I have the below program that seems to work but I'm not quite understanding what is going on. In my comments I have questions labeled 1-3, referring to the questions below the code. I was hoping someone more intelligent than myself could enlighten me.



//passing multi-Array to a simple print function
#include <stdio.h>

//simple print function prototype
void printMyArr(int (*pt)[4]);

int main()
{
//declare and initialize a multi-array. I picked 4x4 and some arbitrary
//numbers for simplicity's sake

int myArr[4][4] = { {12, 16, 19, 20},
{5, 99, 102, 200},
{12, 20, 25, 600},
{65, 66, 999, 1000} };

//declare a pointer to an array of integers and an int for a loop counter
int (*pt)[4], counter;

//initialize the pointer
pt = myArr;

//for loop calling printMyArr function to iterate through arrays -- or this is what I understand it to mean
for(counter=0; counter<4; counter++)
printMyArr(pt++); //<-------------Question 1
return 0;
}

//function called to print array elements to the console
void printMyArr(int(*pt)[4])
{
//declare a counter....and apparently another pointer
int counter, *p;

//initialize new pointer to old pointer and type cast array as int
p = (int *)pt; //<-------------Question 2

//for loop to iterate through elements of array -- or this is what I understand it to mean
for(counter=0; counter<4; counter++)
printf("nnn%d", *p++); //<------Question 3
}


Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])? Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done, increment the pointer."?



Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?



Question 3: Am I correct thinking that I am incrementing each element here?



So



1: pass pointer as assigned -> myArr[0][0] then print the values in myArr[0][0], myArr[0][1], myArr[0][2], and myArr[0][3], then increment pointer myArr[1][0]



2: pass pointer as assigned ->myArr[1][0] then print the values in myArr[1][0], myArr[1][1], myArr[1][2] and myArr[1][3] increment pointer to myArr[2][0]



3: pass pointer as assigned ->myArr[2][0] then print the values in myArr[2][0], myArr[2][1], myArr[2][2] and myArr[2][3] increment pointer to myArr[3][0]



4: pass pointer as assigned ->myArr[3][0] then print the values in myArr[3][0], myArr[3][1], myArr[3][2] and myArr[3][3] increment pointer to myArr[4][0] and if this is the case what is the pointer pointing to since there shouldn't be a myArr[4][0]?










share|improve this question
















I'm teaching myself a little C and have run across an exercise that I want to make sure I understand completely. The exercise is asking me to pass a pointer to a multidimensional array of integers to a function and iterate through the array. So I started with a print function before moving on to one taking input to populate the array. I tried all sorts of things but after finding a bit of code on type casting and iterating pointers I have the below program that seems to work but I'm not quite understanding what is going on. In my comments I have questions labeled 1-3, referring to the questions below the code. I was hoping someone more intelligent than myself could enlighten me.



//passing multi-Array to a simple print function
#include <stdio.h>

//simple print function prototype
void printMyArr(int (*pt)[4]);

int main()
{
//declare and initialize a multi-array. I picked 4x4 and some arbitrary
//numbers for simplicity's sake

int myArr[4][4] = { {12, 16, 19, 20},
{5, 99, 102, 200},
{12, 20, 25, 600},
{65, 66, 999, 1000} };

//declare a pointer to an array of integers and an int for a loop counter
int (*pt)[4], counter;

//initialize the pointer
pt = myArr;

//for loop calling printMyArr function to iterate through arrays -- or this is what I understand it to mean
for(counter=0; counter<4; counter++)
printMyArr(pt++); //<-------------Question 1
return 0;
}

//function called to print array elements to the console
void printMyArr(int(*pt)[4])
{
//declare a counter....and apparently another pointer
int counter, *p;

//initialize new pointer to old pointer and type cast array as int
p = (int *)pt; //<-------------Question 2

//for loop to iterate through elements of array -- or this is what I understand it to mean
for(counter=0; counter<4; counter++)
printf("nnn%d", *p++); //<------Question 3
}


Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])? Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done, increment the pointer."?



Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?



Question 3: Am I correct thinking that I am incrementing each element here?



So



1: pass pointer as assigned -> myArr[0][0] then print the values in myArr[0][0], myArr[0][1], myArr[0][2], and myArr[0][3], then increment pointer myArr[1][0]



2: pass pointer as assigned ->myArr[1][0] then print the values in myArr[1][0], myArr[1][1], myArr[1][2] and myArr[1][3] increment pointer to myArr[2][0]



3: pass pointer as assigned ->myArr[2][0] then print the values in myArr[2][0], myArr[2][1], myArr[2][2] and myArr[2][3] increment pointer to myArr[3][0]



4: pass pointer as assigned ->myArr[3][0] then print the values in myArr[3][0], myArr[3][1], myArr[3][2] and myArr[3][3] increment pointer to myArr[4][0] and if this is the case what is the pointer pointing to since there shouldn't be a myArr[4][0]?







c






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 2 at 22:41







Dan

















asked Jan 2 at 19:42









DanDan

384213




384213








  • 2





    It's awesome to see such a thoroughly considered and well written question. Nicely done.

    – Daniel Farrell
    Jan 2 at 19:45








  • 1





    Understand, on access int myArr[3][5] the first level of indirection (e.g. the first [..]) is converted to a pointer to the first element in the array. With a 2D array the first element is a pointer to the first row (array). So it is converted (*myArr)[5] which is a pointer-to-array of int [5]. You can't just use *myArr[5] as [ ] binds tighter than '*' from a precedence standpoint which would result in an array-of-pointers to int (5 pointers). With (*myArr)[5] the pointer advances by 20-bytes (5-int) per-increment, with *myArr[5] the pointer advances by sizeof a_pointer.

    – David C. Rankin
    Jan 2 at 19:51








  • 2





    The reference in the standard is C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) (note the exceptions when it is NOT converted to a pointer)

    – David C. Rankin
    Jan 2 at 19:53














  • 2





    It's awesome to see such a thoroughly considered and well written question. Nicely done.

    – Daniel Farrell
    Jan 2 at 19:45








  • 1





    Understand, on access int myArr[3][5] the first level of indirection (e.g. the first [..]) is converted to a pointer to the first element in the array. With a 2D array the first element is a pointer to the first row (array). So it is converted (*myArr)[5] which is a pointer-to-array of int [5]. You can't just use *myArr[5] as [ ] binds tighter than '*' from a precedence standpoint which would result in an array-of-pointers to int (5 pointers). With (*myArr)[5] the pointer advances by 20-bytes (5-int) per-increment, with *myArr[5] the pointer advances by sizeof a_pointer.

    – David C. Rankin
    Jan 2 at 19:51








  • 2





    The reference in the standard is C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) (note the exceptions when it is NOT converted to a pointer)

    – David C. Rankin
    Jan 2 at 19:53








2




2





It's awesome to see such a thoroughly considered and well written question. Nicely done.

– Daniel Farrell
Jan 2 at 19:45







It's awesome to see such a thoroughly considered and well written question. Nicely done.

– Daniel Farrell
Jan 2 at 19:45






1




1





Understand, on access int myArr[3][5] the first level of indirection (e.g. the first [..]) is converted to a pointer to the first element in the array. With a 2D array the first element is a pointer to the first row (array). So it is converted (*myArr)[5] which is a pointer-to-array of int [5]. You can't just use *myArr[5] as [ ] binds tighter than '*' from a precedence standpoint which would result in an array-of-pointers to int (5 pointers). With (*myArr)[5] the pointer advances by 20-bytes (5-int) per-increment, with *myArr[5] the pointer advances by sizeof a_pointer.

– David C. Rankin
Jan 2 at 19:51







Understand, on access int myArr[3][5] the first level of indirection (e.g. the first [..]) is converted to a pointer to the first element in the array. With a 2D array the first element is a pointer to the first row (array). So it is converted (*myArr)[5] which is a pointer-to-array of int [5]. You can't just use *myArr[5] as [ ] binds tighter than '*' from a precedence standpoint which would result in an array-of-pointers to int (5 pointers). With (*myArr)[5] the pointer advances by 20-bytes (5-int) per-increment, with *myArr[5] the pointer advances by sizeof a_pointer.

– David C. Rankin
Jan 2 at 19:51






2




2





The reference in the standard is C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) (note the exceptions when it is NOT converted to a pointer)

– David C. Rankin
Jan 2 at 19:53





The reference in the standard is C11 Standard - 6.3.2.1 Other Operands - Lvalues, arrays, and function designators(p3) (note the exceptions when it is NOT converted to a pointer)

– David C. Rankin
Jan 2 at 19:53












3 Answers
3






active

oldest

votes


















2















Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])?




more or less. pt starts at the address of myArr. You know there's 4 things in the array so you loop 4 times, incrementing pt after accessing it (read below) every time to pass to printMyArr each of the 4 elements of the "top level", "outer" array. Then printMyArr iterates over the 4 elements of the inner array to show each number.




Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done increment the pointer."?




Functionally, yes. Technically the order of operations looks like this:



1) get the value of pt
2) increment pt
3) call function, passing the previous value of pt from step 1



pt is incremented as part of the pt++ call, but pt++ evaluates to the old value. As an argument to a funciton, pt++ must be evaluated before the function it's passed to runs. But the timing looks the same as it evaluating directly after the function runs for your case.



Let's take questions 2 and 3 together because they're both part of the answer.




Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?



Question 3: Am I correct thinking that I am incrementing each element here?




p = (int *)pt;          
for(counter=0; counter<4; counter++)
printf("nnn%d", *p++);


p stores an address of an integer. You set it to the address of the first element of the inner array (which is the address of the inner array itself, so to speak). Then, knowing you have 4 elements in the array, you'r able to loop 4 times, doing a similar pointer post-increment operation on p that you did with pt on the outer array.



The first iteration, p is the same as pt, the address of the first of 4 integer values in memory. *p, dereferencing the pointer, gets the first integer. *p++, due to order of operations ( ++ being of the highest precedence, and dereferencing * being lower), returns the integer at p, leaving p pointing to the next integer address for the next loop.



In general, casting values in C should be avoidid whenever possible. You merely have to do a dereference here to point p to the set of integers. pt holds the address of one of 4 addresses ( outer array ) of contiguous sets of 4 integers (inner array) in memory. The value at *pt is the address of the "current" set of 4 contiguous integers in memory. So you can simply say,



int* p=*pt;


Which doesn't arbitrarily cast a type and is very straightforward and clear. (Thanks @WhozCraig)






share|improve this answer


























  • ...and on the last iteration? The compiler knows not to increment the pointer to point at the non-existent myArr[4][0] or is that included in the <? Seems like to me given the order of operations the pointer is incremented before the loop can test counter and evaluate it to <4

    – Dan
    Jan 2 at 20:13








  • 4





    Question #2: The proper syntax without the hard cast (avoided by seasoned programmers, nearly always a sign of misunderstanding or masking type issues by beginners), is to use int *p = *pt;

    – WhozCraig
    Jan 2 at 20:14








  • 1





    That's a great question. Actually pt and p are post-incremented to the first "non-existent" address on the last iteration of the loop, but they're not dereferenced again because the for loop's condition is violated on the 5th pass, when an out-of-bounds p or pt would be dereferenced . So though the last value of pt and p is an invalid one, that value is never actually accessed.

    – Daniel Farrell
    Jan 2 at 20:16











  • That's a great point @WhozCraig I'll add it to the answer.

    – Daniel Farrell
    Jan 2 at 20:16






  • 2





    @Dan First, pointers in C point to stuff (bear with me). You dereference a pointer to get to what it points to. The underlying type of the thing being pointed to dictates many things, among them outcome of pointer arithmetic. If you have some int *p, then *p gets you the int being pointed-to, and ++p (or p++ post-facto) advances the pointer to the next int. That said, your function argument is a pointer to an array [4] of int. That's important, because that mean ++p will advance to the next int[4] (not what you want to do). That's probably where the wheels came off.

    – WhozCraig
    Jan 2 at 20:34





















1














A multy D array is kept in memory as a continuous array so if you have an array [2][2] it will allocate 4 continuous sizeof(int). The reason you need to define array[COL] is to let the compiler know how the pointer arithmetic should be done.



so- for Q1- you are right, each time you increment you do so for(sizeof(int)*COL). so each time you move by a row.



Q2- now for each row you want to print one int value at a time, so when you have int* p- this means each increment is done by sizeof(int).



Q3- the increment is for the pointer- not the value- its easy to see for yourself if you do another print in your main.



Hope this help, good luck!






share|improve this answer



















  • 1





    I appreciate the help!!!

    – Dan
    Jan 2 at 20:44



















0














The in-memory view of 2D myArr array would be something like this:



        myArr
---------------------
myArr[0] | 12 | 16 | 19 | 20 |
---------------------
myArr[1] | 5 | 99 |102 |200 |
---------------------
myArr[2] | 12 | 20 | 25 |600 |
---------------------
myArr[3] | 65 | 66 |999 |1000|
---------------------



Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])? Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done, increment the pointer."?




Answer of question 1:



int (*pt)[4]


pt is pointer to an array of 4 integer. This statement



pt = myArr;


makes the pt pointing to first 1D array of myArr 2D array. It is similar to:



pt = &myArr[0];


The impact of both the statement will be like this:



pt--------|
|/
---------------------
myArr[0] | 12 | 16 | 19 | 20 |
---------------------


When you increment a pointer, it gets incremented in steps of the object size that the pointer can point to. Here



printMyArr(pt++);


first the pt pointer value passed to printMyArr() and then pt will be incremented and since its type is int (*)[4] that means it can point to an object which is an array of 4 integers, so after increment the pt will point to the address (which is address pointing to + size of array of 4 int) i.e. to myArr[1] address.



Note that this:



for(counter=0; counter<4; counter++)
printMyArr(pt++);


is same as this:



for(counter=0; counter<4; counter++)
printMyArr(&myArr[counter]);
^^^^^^^^^^^^^^^



Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?




Answer of question 2:



Here



p = (int *)pt;   // pt is pointer to an array of `4` integer


if you remove the (int *) cast, you will find that the compiler is giving a warning message on this statement. The reason is p and pt are not the compatible pointer types. The type of p is int * whereas the type of pt is int (*)[4]. This incompatible pointer assignment is working because the address of an array and address of first element of an array is numerically same though their type is different. Instead, you should do



p = &(*pt)[0];


From C Standards#6.5.2.1




The definition of the subscript operator is that E1[E2] is identical to (*((E1)+(E2)))




by this rule



&(*pt)[0] --> &(*((*pt)+(0))) --> ((*p)+(0)) --> *p


The operator & is used to get the address and the operator * is used for dereferencing. These operators cancel the effect of each other when used one after another.



Hence, this statement



p = &(*pt)[0];


is same as this statement



p = *pt;



Question 3: Am I correct thinking that I am incrementing each element here?




Answer of question 3:



Yes.
p is a pointer pointing to first element of array of 4 integer and its type is int * i.e. it can point to an object which is an int. When you are doing *p++, this will first dereference p and get the value at the address it is pointing to then the p will be incremented and pointing to next element of array.






share|improve this answer


























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54012242%2fprecedence-parentheses-pointers-with-iterative-array-functions%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    2















    Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])?




    more or less. pt starts at the address of myArr. You know there's 4 things in the array so you loop 4 times, incrementing pt after accessing it (read below) every time to pass to printMyArr each of the 4 elements of the "top level", "outer" array. Then printMyArr iterates over the 4 elements of the inner array to show each number.




    Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done increment the pointer."?




    Functionally, yes. Technically the order of operations looks like this:



    1) get the value of pt
    2) increment pt
    3) call function, passing the previous value of pt from step 1



    pt is incremented as part of the pt++ call, but pt++ evaluates to the old value. As an argument to a funciton, pt++ must be evaluated before the function it's passed to runs. But the timing looks the same as it evaluating directly after the function runs for your case.



    Let's take questions 2 and 3 together because they're both part of the answer.




    Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?



    Question 3: Am I correct thinking that I am incrementing each element here?




    p = (int *)pt;          
    for(counter=0; counter<4; counter++)
    printf("nnn%d", *p++);


    p stores an address of an integer. You set it to the address of the first element of the inner array (which is the address of the inner array itself, so to speak). Then, knowing you have 4 elements in the array, you'r able to loop 4 times, doing a similar pointer post-increment operation on p that you did with pt on the outer array.



    The first iteration, p is the same as pt, the address of the first of 4 integer values in memory. *p, dereferencing the pointer, gets the first integer. *p++, due to order of operations ( ++ being of the highest precedence, and dereferencing * being lower), returns the integer at p, leaving p pointing to the next integer address for the next loop.



    In general, casting values in C should be avoidid whenever possible. You merely have to do a dereference here to point p to the set of integers. pt holds the address of one of 4 addresses ( outer array ) of contiguous sets of 4 integers (inner array) in memory. The value at *pt is the address of the "current" set of 4 contiguous integers in memory. So you can simply say,



    int* p=*pt;


    Which doesn't arbitrarily cast a type and is very straightforward and clear. (Thanks @WhozCraig)






    share|improve this answer


























    • ...and on the last iteration? The compiler knows not to increment the pointer to point at the non-existent myArr[4][0] or is that included in the <? Seems like to me given the order of operations the pointer is incremented before the loop can test counter and evaluate it to <4

      – Dan
      Jan 2 at 20:13








    • 4





      Question #2: The proper syntax without the hard cast (avoided by seasoned programmers, nearly always a sign of misunderstanding or masking type issues by beginners), is to use int *p = *pt;

      – WhozCraig
      Jan 2 at 20:14








    • 1





      That's a great question. Actually pt and p are post-incremented to the first "non-existent" address on the last iteration of the loop, but they're not dereferenced again because the for loop's condition is violated on the 5th pass, when an out-of-bounds p or pt would be dereferenced . So though the last value of pt and p is an invalid one, that value is never actually accessed.

      – Daniel Farrell
      Jan 2 at 20:16











    • That's a great point @WhozCraig I'll add it to the answer.

      – Daniel Farrell
      Jan 2 at 20:16






    • 2





      @Dan First, pointers in C point to stuff (bear with me). You dereference a pointer to get to what it points to. The underlying type of the thing being pointed to dictates many things, among them outcome of pointer arithmetic. If you have some int *p, then *p gets you the int being pointed-to, and ++p (or p++ post-facto) advances the pointer to the next int. That said, your function argument is a pointer to an array [4] of int. That's important, because that mean ++p will advance to the next int[4] (not what you want to do). That's probably where the wheels came off.

      – WhozCraig
      Jan 2 at 20:34


















    2















    Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])?




    more or less. pt starts at the address of myArr. You know there's 4 things in the array so you loop 4 times, incrementing pt after accessing it (read below) every time to pass to printMyArr each of the 4 elements of the "top level", "outer" array. Then printMyArr iterates over the 4 elements of the inner array to show each number.




    Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done increment the pointer."?




    Functionally, yes. Technically the order of operations looks like this:



    1) get the value of pt
    2) increment pt
    3) call function, passing the previous value of pt from step 1



    pt is incremented as part of the pt++ call, but pt++ evaluates to the old value. As an argument to a funciton, pt++ must be evaluated before the function it's passed to runs. But the timing looks the same as it evaluating directly after the function runs for your case.



    Let's take questions 2 and 3 together because they're both part of the answer.




    Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?



    Question 3: Am I correct thinking that I am incrementing each element here?




    p = (int *)pt;          
    for(counter=0; counter<4; counter++)
    printf("nnn%d", *p++);


    p stores an address of an integer. You set it to the address of the first element of the inner array (which is the address of the inner array itself, so to speak). Then, knowing you have 4 elements in the array, you'r able to loop 4 times, doing a similar pointer post-increment operation on p that you did with pt on the outer array.



    The first iteration, p is the same as pt, the address of the first of 4 integer values in memory. *p, dereferencing the pointer, gets the first integer. *p++, due to order of operations ( ++ being of the highest precedence, and dereferencing * being lower), returns the integer at p, leaving p pointing to the next integer address for the next loop.



    In general, casting values in C should be avoidid whenever possible. You merely have to do a dereference here to point p to the set of integers. pt holds the address of one of 4 addresses ( outer array ) of contiguous sets of 4 integers (inner array) in memory. The value at *pt is the address of the "current" set of 4 contiguous integers in memory. So you can simply say,



    int* p=*pt;


    Which doesn't arbitrarily cast a type and is very straightforward and clear. (Thanks @WhozCraig)






    share|improve this answer


























    • ...and on the last iteration? The compiler knows not to increment the pointer to point at the non-existent myArr[4][0] or is that included in the <? Seems like to me given the order of operations the pointer is incremented before the loop can test counter and evaluate it to <4

      – Dan
      Jan 2 at 20:13








    • 4





      Question #2: The proper syntax without the hard cast (avoided by seasoned programmers, nearly always a sign of misunderstanding or masking type issues by beginners), is to use int *p = *pt;

      – WhozCraig
      Jan 2 at 20:14








    • 1





      That's a great question. Actually pt and p are post-incremented to the first "non-existent" address on the last iteration of the loop, but they're not dereferenced again because the for loop's condition is violated on the 5th pass, when an out-of-bounds p or pt would be dereferenced . So though the last value of pt and p is an invalid one, that value is never actually accessed.

      – Daniel Farrell
      Jan 2 at 20:16











    • That's a great point @WhozCraig I'll add it to the answer.

      – Daniel Farrell
      Jan 2 at 20:16






    • 2





      @Dan First, pointers in C point to stuff (bear with me). You dereference a pointer to get to what it points to. The underlying type of the thing being pointed to dictates many things, among them outcome of pointer arithmetic. If you have some int *p, then *p gets you the int being pointed-to, and ++p (or p++ post-facto) advances the pointer to the next int. That said, your function argument is a pointer to an array [4] of int. That's important, because that mean ++p will advance to the next int[4] (not what you want to do). That's probably where the wheels came off.

      – WhozCraig
      Jan 2 at 20:34
















    2












    2








    2








    Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])?




    more or less. pt starts at the address of myArr. You know there's 4 things in the array so you loop 4 times, incrementing pt after accessing it (read below) every time to pass to printMyArr each of the 4 elements of the "top level", "outer" array. Then printMyArr iterates over the 4 elements of the inner array to show each number.




    Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done increment the pointer."?




    Functionally, yes. Technically the order of operations looks like this:



    1) get the value of pt
    2) increment pt
    3) call function, passing the previous value of pt from step 1



    pt is incremented as part of the pt++ call, but pt++ evaluates to the old value. As an argument to a funciton, pt++ must be evaluated before the function it's passed to runs. But the timing looks the same as it evaluating directly after the function runs for your case.



    Let's take questions 2 and 3 together because they're both part of the answer.




    Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?



    Question 3: Am I correct thinking that I am incrementing each element here?




    p = (int *)pt;          
    for(counter=0; counter<4; counter++)
    printf("nnn%d", *p++);


    p stores an address of an integer. You set it to the address of the first element of the inner array (which is the address of the inner array itself, so to speak). Then, knowing you have 4 elements in the array, you'r able to loop 4 times, doing a similar pointer post-increment operation on p that you did with pt on the outer array.



    The first iteration, p is the same as pt, the address of the first of 4 integer values in memory. *p, dereferencing the pointer, gets the first integer. *p++, due to order of operations ( ++ being of the highest precedence, and dereferencing * being lower), returns the integer at p, leaving p pointing to the next integer address for the next loop.



    In general, casting values in C should be avoidid whenever possible. You merely have to do a dereference here to point p to the set of integers. pt holds the address of one of 4 addresses ( outer array ) of contiguous sets of 4 integers (inner array) in memory. The value at *pt is the address of the "current" set of 4 contiguous integers in memory. So you can simply say,



    int* p=*pt;


    Which doesn't arbitrarily cast a type and is very straightforward and clear. (Thanks @WhozCraig)






    share|improve this answer
















    Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])?




    more or less. pt starts at the address of myArr. You know there's 4 things in the array so you loop 4 times, incrementing pt after accessing it (read below) every time to pass to printMyArr each of the 4 elements of the "top level", "outer" array. Then printMyArr iterates over the 4 elements of the inner array to show each number.




    Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done increment the pointer."?




    Functionally, yes. Technically the order of operations looks like this:



    1) get the value of pt
    2) increment pt
    3) call function, passing the previous value of pt from step 1



    pt is incremented as part of the pt++ call, but pt++ evaluates to the old value. As an argument to a funciton, pt++ must be evaluated before the function it's passed to runs. But the timing looks the same as it evaluating directly after the function runs for your case.



    Let's take questions 2 and 3 together because they're both part of the answer.




    Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?



    Question 3: Am I correct thinking that I am incrementing each element here?




    p = (int *)pt;          
    for(counter=0; counter<4; counter++)
    printf("nnn%d", *p++);


    p stores an address of an integer. You set it to the address of the first element of the inner array (which is the address of the inner array itself, so to speak). Then, knowing you have 4 elements in the array, you'r able to loop 4 times, doing a similar pointer post-increment operation on p that you did with pt on the outer array.



    The first iteration, p is the same as pt, the address of the first of 4 integer values in memory. *p, dereferencing the pointer, gets the first integer. *p++, due to order of operations ( ++ being of the highest precedence, and dereferencing * being lower), returns the integer at p, leaving p pointing to the next integer address for the next loop.



    In general, casting values in C should be avoidid whenever possible. You merely have to do a dereference here to point p to the set of integers. pt holds the address of one of 4 addresses ( outer array ) of contiguous sets of 4 integers (inner array) in memory. The value at *pt is the address of the "current" set of 4 contiguous integers in memory. So you can simply say,



    int* p=*pt;


    Which doesn't arbitrarily cast a type and is very straightforward and clear. (Thanks @WhozCraig)







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Jan 2 at 20:29

























    answered Jan 2 at 20:01









    Daniel FarrellDaniel Farrell

    6,18711417




    6,18711417













    • ...and on the last iteration? The compiler knows not to increment the pointer to point at the non-existent myArr[4][0] or is that included in the <? Seems like to me given the order of operations the pointer is incremented before the loop can test counter and evaluate it to <4

      – Dan
      Jan 2 at 20:13








    • 4





      Question #2: The proper syntax without the hard cast (avoided by seasoned programmers, nearly always a sign of misunderstanding or masking type issues by beginners), is to use int *p = *pt;

      – WhozCraig
      Jan 2 at 20:14








    • 1





      That's a great question. Actually pt and p are post-incremented to the first "non-existent" address on the last iteration of the loop, but they're not dereferenced again because the for loop's condition is violated on the 5th pass, when an out-of-bounds p or pt would be dereferenced . So though the last value of pt and p is an invalid one, that value is never actually accessed.

      – Daniel Farrell
      Jan 2 at 20:16











    • That's a great point @WhozCraig I'll add it to the answer.

      – Daniel Farrell
      Jan 2 at 20:16






    • 2





      @Dan First, pointers in C point to stuff (bear with me). You dereference a pointer to get to what it points to. The underlying type of the thing being pointed to dictates many things, among them outcome of pointer arithmetic. If you have some int *p, then *p gets you the int being pointed-to, and ++p (or p++ post-facto) advances the pointer to the next int. That said, your function argument is a pointer to an array [4] of int. That's important, because that mean ++p will advance to the next int[4] (not what you want to do). That's probably where the wheels came off.

      – WhozCraig
      Jan 2 at 20:34





















    • ...and on the last iteration? The compiler knows not to increment the pointer to point at the non-existent myArr[4][0] or is that included in the <? Seems like to me given the order of operations the pointer is incremented before the loop can test counter and evaluate it to <4

      – Dan
      Jan 2 at 20:13








    • 4





      Question #2: The proper syntax without the hard cast (avoided by seasoned programmers, nearly always a sign of misunderstanding or masking type issues by beginners), is to use int *p = *pt;

      – WhozCraig
      Jan 2 at 20:14








    • 1





      That's a great question. Actually pt and p are post-incremented to the first "non-existent" address on the last iteration of the loop, but they're not dereferenced again because the for loop's condition is violated on the 5th pass, when an out-of-bounds p or pt would be dereferenced . So though the last value of pt and p is an invalid one, that value is never actually accessed.

      – Daniel Farrell
      Jan 2 at 20:16











    • That's a great point @WhozCraig I'll add it to the answer.

      – Daniel Farrell
      Jan 2 at 20:16






    • 2





      @Dan First, pointers in C point to stuff (bear with me). You dereference a pointer to get to what it points to. The underlying type of the thing being pointed to dictates many things, among them outcome of pointer arithmetic. If you have some int *p, then *p gets you the int being pointed-to, and ++p (or p++ post-facto) advances the pointer to the next int. That said, your function argument is a pointer to an array [4] of int. That's important, because that mean ++p will advance to the next int[4] (not what you want to do). That's probably where the wheels came off.

      – WhozCraig
      Jan 2 at 20:34



















    ...and on the last iteration? The compiler knows not to increment the pointer to point at the non-existent myArr[4][0] or is that included in the <? Seems like to me given the order of operations the pointer is incremented before the loop can test counter and evaluate it to <4

    – Dan
    Jan 2 at 20:13







    ...and on the last iteration? The compiler knows not to increment the pointer to point at the non-existent myArr[4][0] or is that included in the <? Seems like to me given the order of operations the pointer is incremented before the loop can test counter and evaluate it to <4

    – Dan
    Jan 2 at 20:13






    4




    4





    Question #2: The proper syntax without the hard cast (avoided by seasoned programmers, nearly always a sign of misunderstanding or masking type issues by beginners), is to use int *p = *pt;

    – WhozCraig
    Jan 2 at 20:14







    Question #2: The proper syntax without the hard cast (avoided by seasoned programmers, nearly always a sign of misunderstanding or masking type issues by beginners), is to use int *p = *pt;

    – WhozCraig
    Jan 2 at 20:14






    1




    1





    That's a great question. Actually pt and p are post-incremented to the first "non-existent" address on the last iteration of the loop, but they're not dereferenced again because the for loop's condition is violated on the 5th pass, when an out-of-bounds p or pt would be dereferenced . So though the last value of pt and p is an invalid one, that value is never actually accessed.

    – Daniel Farrell
    Jan 2 at 20:16





    That's a great question. Actually pt and p are post-incremented to the first "non-existent" address on the last iteration of the loop, but they're not dereferenced again because the for loop's condition is violated on the 5th pass, when an out-of-bounds p or pt would be dereferenced . So though the last value of pt and p is an invalid one, that value is never actually accessed.

    – Daniel Farrell
    Jan 2 at 20:16













    That's a great point @WhozCraig I'll add it to the answer.

    – Daniel Farrell
    Jan 2 at 20:16





    That's a great point @WhozCraig I'll add it to the answer.

    – Daniel Farrell
    Jan 2 at 20:16




    2




    2





    @Dan First, pointers in C point to stuff (bear with me). You dereference a pointer to get to what it points to. The underlying type of the thing being pointed to dictates many things, among them outcome of pointer arithmetic. If you have some int *p, then *p gets you the int being pointed-to, and ++p (or p++ post-facto) advances the pointer to the next int. That said, your function argument is a pointer to an array [4] of int. That's important, because that mean ++p will advance to the next int[4] (not what you want to do). That's probably where the wheels came off.

    – WhozCraig
    Jan 2 at 20:34







    @Dan First, pointers in C point to stuff (bear with me). You dereference a pointer to get to what it points to. The underlying type of the thing being pointed to dictates many things, among them outcome of pointer arithmetic. If you have some int *p, then *p gets you the int being pointed-to, and ++p (or p++ post-facto) advances the pointer to the next int. That said, your function argument is a pointer to an array [4] of int. That's important, because that mean ++p will advance to the next int[4] (not what you want to do). That's probably where the wheels came off.

    – WhozCraig
    Jan 2 at 20:34















    1














    A multy D array is kept in memory as a continuous array so if you have an array [2][2] it will allocate 4 continuous sizeof(int). The reason you need to define array[COL] is to let the compiler know how the pointer arithmetic should be done.



    so- for Q1- you are right, each time you increment you do so for(sizeof(int)*COL). so each time you move by a row.



    Q2- now for each row you want to print one int value at a time, so when you have int* p- this means each increment is done by sizeof(int).



    Q3- the increment is for the pointer- not the value- its easy to see for yourself if you do another print in your main.



    Hope this help, good luck!






    share|improve this answer



















    • 1





      I appreciate the help!!!

      – Dan
      Jan 2 at 20:44
















    1














    A multy D array is kept in memory as a continuous array so if you have an array [2][2] it will allocate 4 continuous sizeof(int). The reason you need to define array[COL] is to let the compiler know how the pointer arithmetic should be done.



    so- for Q1- you are right, each time you increment you do so for(sizeof(int)*COL). so each time you move by a row.



    Q2- now for each row you want to print one int value at a time, so when you have int* p- this means each increment is done by sizeof(int).



    Q3- the increment is for the pointer- not the value- its easy to see for yourself if you do another print in your main.



    Hope this help, good luck!






    share|improve this answer



















    • 1





      I appreciate the help!!!

      – Dan
      Jan 2 at 20:44














    1












    1








    1







    A multy D array is kept in memory as a continuous array so if you have an array [2][2] it will allocate 4 continuous sizeof(int). The reason you need to define array[COL] is to let the compiler know how the pointer arithmetic should be done.



    so- for Q1- you are right, each time you increment you do so for(sizeof(int)*COL). so each time you move by a row.



    Q2- now for each row you want to print one int value at a time, so when you have int* p- this means each increment is done by sizeof(int).



    Q3- the increment is for the pointer- not the value- its easy to see for yourself if you do another print in your main.



    Hope this help, good luck!






    share|improve this answer













    A multy D array is kept in memory as a continuous array so if you have an array [2][2] it will allocate 4 continuous sizeof(int). The reason you need to define array[COL] is to let the compiler know how the pointer arithmetic should be done.



    so- for Q1- you are right, each time you increment you do so for(sizeof(int)*COL). so each time you move by a row.



    Q2- now for each row you want to print one int value at a time, so when you have int* p- this means each increment is done by sizeof(int).



    Q3- the increment is for the pointer- not the value- its easy to see for yourself if you do another print in your main.



    Hope this help, good luck!







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Jan 2 at 20:06









    H.cohenH.cohen

    47019




    47019








    • 1





      I appreciate the help!!!

      – Dan
      Jan 2 at 20:44














    • 1





      I appreciate the help!!!

      – Dan
      Jan 2 at 20:44








    1




    1





    I appreciate the help!!!

    – Dan
    Jan 2 at 20:44





    I appreciate the help!!!

    – Dan
    Jan 2 at 20:44











    0














    The in-memory view of 2D myArr array would be something like this:



            myArr
    ---------------------
    myArr[0] | 12 | 16 | 19 | 20 |
    ---------------------
    myArr[1] | 5 | 99 |102 |200 |
    ---------------------
    myArr[2] | 12 | 20 | 25 |600 |
    ---------------------
    myArr[3] | 65 | 66 |999 |1000|
    ---------------------



    Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])? Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done, increment the pointer."?




    Answer of question 1:



    int (*pt)[4]


    pt is pointer to an array of 4 integer. This statement



    pt = myArr;


    makes the pt pointing to first 1D array of myArr 2D array. It is similar to:



    pt = &myArr[0];


    The impact of both the statement will be like this:



    pt--------|
    |/
    ---------------------
    myArr[0] | 12 | 16 | 19 | 20 |
    ---------------------


    When you increment a pointer, it gets incremented in steps of the object size that the pointer can point to. Here



    printMyArr(pt++);


    first the pt pointer value passed to printMyArr() and then pt will be incremented and since its type is int (*)[4] that means it can point to an object which is an array of 4 integers, so after increment the pt will point to the address (which is address pointing to + size of array of 4 int) i.e. to myArr[1] address.



    Note that this:



    for(counter=0; counter<4; counter++)
    printMyArr(pt++);


    is same as this:



    for(counter=0; counter<4; counter++)
    printMyArr(&myArr[counter]);
    ^^^^^^^^^^^^^^^



    Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?




    Answer of question 2:



    Here



    p = (int *)pt;   // pt is pointer to an array of `4` integer


    if you remove the (int *) cast, you will find that the compiler is giving a warning message on this statement. The reason is p and pt are not the compatible pointer types. The type of p is int * whereas the type of pt is int (*)[4]. This incompatible pointer assignment is working because the address of an array and address of first element of an array is numerically same though their type is different. Instead, you should do



    p = &(*pt)[0];


    From C Standards#6.5.2.1




    The definition of the subscript operator is that E1[E2] is identical to (*((E1)+(E2)))




    by this rule



    &(*pt)[0] --> &(*((*pt)+(0))) --> ((*p)+(0)) --> *p


    The operator & is used to get the address and the operator * is used for dereferencing. These operators cancel the effect of each other when used one after another.



    Hence, this statement



    p = &(*pt)[0];


    is same as this statement



    p = *pt;



    Question 3: Am I correct thinking that I am incrementing each element here?




    Answer of question 3:



    Yes.
    p is a pointer pointing to first element of array of 4 integer and its type is int * i.e. it can point to an object which is an int. When you are doing *p++, this will first dereference p and get the value at the address it is pointing to then the p will be incremented and pointing to next element of array.






    share|improve this answer






























      0














      The in-memory view of 2D myArr array would be something like this:



              myArr
      ---------------------
      myArr[0] | 12 | 16 | 19 | 20 |
      ---------------------
      myArr[1] | 5 | 99 |102 |200 |
      ---------------------
      myArr[2] | 12 | 20 | 25 |600 |
      ---------------------
      myArr[3] | 65 | 66 |999 |1000|
      ---------------------



      Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])? Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done, increment the pointer."?




      Answer of question 1:



      int (*pt)[4]


      pt is pointer to an array of 4 integer. This statement



      pt = myArr;


      makes the pt pointing to first 1D array of myArr 2D array. It is similar to:



      pt = &myArr[0];


      The impact of both the statement will be like this:



      pt--------|
      |/
      ---------------------
      myArr[0] | 12 | 16 | 19 | 20 |
      ---------------------


      When you increment a pointer, it gets incremented in steps of the object size that the pointer can point to. Here



      printMyArr(pt++);


      first the pt pointer value passed to printMyArr() and then pt will be incremented and since its type is int (*)[4] that means it can point to an object which is an array of 4 integers, so after increment the pt will point to the address (which is address pointing to + size of array of 4 int) i.e. to myArr[1] address.



      Note that this:



      for(counter=0; counter<4; counter++)
      printMyArr(pt++);


      is same as this:



      for(counter=0; counter<4; counter++)
      printMyArr(&myArr[counter]);
      ^^^^^^^^^^^^^^^



      Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?




      Answer of question 2:



      Here



      p = (int *)pt;   // pt is pointer to an array of `4` integer


      if you remove the (int *) cast, you will find that the compiler is giving a warning message on this statement. The reason is p and pt are not the compatible pointer types. The type of p is int * whereas the type of pt is int (*)[4]. This incompatible pointer assignment is working because the address of an array and address of first element of an array is numerically same though their type is different. Instead, you should do



      p = &(*pt)[0];


      From C Standards#6.5.2.1




      The definition of the subscript operator is that E1[E2] is identical to (*((E1)+(E2)))




      by this rule



      &(*pt)[0] --> &(*((*pt)+(0))) --> ((*p)+(0)) --> *p


      The operator & is used to get the address and the operator * is used for dereferencing. These operators cancel the effect of each other when used one after another.



      Hence, this statement



      p = &(*pt)[0];


      is same as this statement



      p = *pt;



      Question 3: Am I correct thinking that I am incrementing each element here?




      Answer of question 3:



      Yes.
      p is a pointer pointing to first element of array of 4 integer and its type is int * i.e. it can point to an object which is an int. When you are doing *p++, this will first dereference p and get the value at the address it is pointing to then the p will be incremented and pointing to next element of array.






      share|improve this answer




























        0












        0








        0







        The in-memory view of 2D myArr array would be something like this:



                myArr
        ---------------------
        myArr[0] | 12 | 16 | 19 | 20 |
        ---------------------
        myArr[1] | 5 | 99 |102 |200 |
        ---------------------
        myArr[2] | 12 | 20 | 25 |600 |
        ---------------------
        myArr[3] | 65 | 66 |999 |1000|
        ---------------------



        Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])? Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done, increment the pointer."?




        Answer of question 1:



        int (*pt)[4]


        pt is pointer to an array of 4 integer. This statement



        pt = myArr;


        makes the pt pointing to first 1D array of myArr 2D array. It is similar to:



        pt = &myArr[0];


        The impact of both the statement will be like this:



        pt--------|
        |/
        ---------------------
        myArr[0] | 12 | 16 | 19 | 20 |
        ---------------------


        When you increment a pointer, it gets incremented in steps of the object size that the pointer can point to. Here



        printMyArr(pt++);


        first the pt pointer value passed to printMyArr() and then pt will be incremented and since its type is int (*)[4] that means it can point to an object which is an array of 4 integers, so after increment the pt will point to the address (which is address pointing to + size of array of 4 int) i.e. to myArr[1] address.



        Note that this:



        for(counter=0; counter<4; counter++)
        printMyArr(pt++);


        is same as this:



        for(counter=0; counter<4; counter++)
        printMyArr(&myArr[counter]);
        ^^^^^^^^^^^^^^^



        Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?




        Answer of question 2:



        Here



        p = (int *)pt;   // pt is pointer to an array of `4` integer


        if you remove the (int *) cast, you will find that the compiler is giving a warning message on this statement. The reason is p and pt are not the compatible pointer types. The type of p is int * whereas the type of pt is int (*)[4]. This incompatible pointer assignment is working because the address of an array and address of first element of an array is numerically same though their type is different. Instead, you should do



        p = &(*pt)[0];


        From C Standards#6.5.2.1




        The definition of the subscript operator is that E1[E2] is identical to (*((E1)+(E2)))




        by this rule



        &(*pt)[0] --> &(*((*pt)+(0))) --> ((*p)+(0)) --> *p


        The operator & is used to get the address and the operator * is used for dereferencing. These operators cancel the effect of each other when used one after another.



        Hence, this statement



        p = &(*pt)[0];


        is same as this statement



        p = *pt;



        Question 3: Am I correct thinking that I am incrementing each element here?




        Answer of question 3:



        Yes.
        p is a pointer pointing to first element of array of 4 integer and its type is int * i.e. it can point to an object which is an int. When you are doing *p++, this will first dereference p and get the value at the address it is pointing to then the p will be incremented and pointing to next element of array.






        share|improve this answer















        The in-memory view of 2D myArr array would be something like this:



                myArr
        ---------------------
        myArr[0] | 12 | 16 | 19 | 20 |
        ---------------------
        myArr[1] | 5 | 99 |102 |200 |
        ---------------------
        myArr[2] | 12 | 20 | 25 |600 |
        ---------------------
        myArr[3] | 65 | 66 |999 |1000|
        ---------------------



        Question 1: Here, I've passed the pointer to the function and I keep thinking, "What is this loop iterating over?". Am I correct in thinking that I am incrementing the pointer to each of the first elements in each array (myArr[0][0], myArr[1][0], myArr[2][0], myArr[3][0])? Also, am I correct in assuming that the syntax of this line is in essence saying: "Execute the function passing the current pointer and THEN when it's done, increment the pointer."?




        Answer of question 1:



        int (*pt)[4]


        pt is pointer to an array of 4 integer. This statement



        pt = myArr;


        makes the pt pointing to first 1D array of myArr 2D array. It is similar to:



        pt = &myArr[0];


        The impact of both the statement will be like this:



        pt--------|
        |/
        ---------------------
        myArr[0] | 12 | 16 | 19 | 20 |
        ---------------------


        When you increment a pointer, it gets incremented in steps of the object size that the pointer can point to. Here



        printMyArr(pt++);


        first the pt pointer value passed to printMyArr() and then pt will be incremented and since its type is int (*)[4] that means it can point to an object which is an array of 4 integers, so after increment the pt will point to the address (which is address pointing to + size of array of 4 int) i.e. to myArr[1] address.



        Note that this:



        for(counter=0; counter<4; counter++)
        printMyArr(pt++);


        is same as this:



        for(counter=0; counter<4; counter++)
        printMyArr(&myArr[counter]);
        ^^^^^^^^^^^^^^^



        Question 2: This is what has me the most confused. After quite a bit of digging I found this bit to make it run right and I realize this is how it works, but why?




        Answer of question 2:



        Here



        p = (int *)pt;   // pt is pointer to an array of `4` integer


        if you remove the (int *) cast, you will find that the compiler is giving a warning message on this statement. The reason is p and pt are not the compatible pointer types. The type of p is int * whereas the type of pt is int (*)[4]. This incompatible pointer assignment is working because the address of an array and address of first element of an array is numerically same though their type is different. Instead, you should do



        p = &(*pt)[0];


        From C Standards#6.5.2.1




        The definition of the subscript operator is that E1[E2] is identical to (*((E1)+(E2)))




        by this rule



        &(*pt)[0] --> &(*((*pt)+(0))) --> ((*p)+(0)) --> *p


        The operator & is used to get the address and the operator * is used for dereferencing. These operators cancel the effect of each other when used one after another.



        Hence, this statement



        p = &(*pt)[0];


        is same as this statement



        p = *pt;



        Question 3: Am I correct thinking that I am incrementing each element here?




        Answer of question 3:



        Yes.
        p is a pointer pointing to first element of array of 4 integer and its type is int * i.e. it can point to an object which is an int. When you are doing *p++, this will first dereference p and get the value at the address it is pointing to then the p will be incremented and pointing to next element of array.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Jan 3 at 14:28

























        answered Jan 2 at 22:19









        H.S.H.S.

        5,6291420




        5,6291420






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54012242%2fprecedence-parentheses-pointers-with-iterative-array-functions%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

            Npm cannot find a required file even through it is in the searched directory