So I know that pointers are variables that store the address(s) of some other variables. But the thing that I am confused with is this:
I know that using the name of the array in most of the contexts would decay it to the base address of the element. But I get confused here:
When we declare an array say int arr[5]
, and then say scanf("%d",arr 1)
, here arr
is an address right? We did not explicitly store it in any variable i.e, a pointer. So how does arr 1
arithmetic work similar to pointer arithmetic? Also this: *(arr 1)
would give us the value in the address arr 1
. I do realize that we can dereference an address, but here I kind of find it difficult to work with it because I kind of lose the "hey this pointer points to this address.." here. And my final question would be, is this the exact way that we can differentiate an address from a random value in a computer? Like arr 1
leads to the address of the next integer in this case, and not normal 1
(pointer arithmetic basically).
I hope that my question does not have any ambiguity.
CodePudding user response:
Let's suppose we have:
int n = 1;
int arr[100];
arr n
: yes this is an address.arr n
: yes, we do doing pointer arithmetic here.arr n
is the same thing as&arr[n]
.*(arr n)
is the same thing asarr[n]
.
Example of pointer arithmetic:
Let's suppose the size of an int
is 4 bytes and arr
is the address 0x10000
:
arr n
is0x10000
n * 4
- sor for example
arr 2
is the address0x10008
Your last question is somewhat unclear but if you understood the above it should be clear.
CodePudding user response:
Your problem starts with this misunderstanding:
So I know that pointers are variables that store the address(s) of some other variables.
"Pointer" is a type category. There are values of pointer types, which are also referred to as "addresses", and there also variables declared to hold such values. This is entirely analogous to there being values of type int
and variables declared to hold int
values. Also, just as we might refer to either an int
value or an int
variable as "an int", people can and do refer to both pointer values and pointer variables as "pointers".
Additionally, it is a bit imprecise and a bit misleading to say that pointer values are the addresses of variables. They are the addresses of objects, and although in-scope variables do represent objects, not all objects correspond to variables.
When we declare an array say int
arr[5]
, and then sayscanf("%d",arr 1)
, here arr is an address right?
When the scanf
call is evaluated, the array value of arr
is automatically converted to a pointer value, the address of the first array element.
We did not explicitly store it in any variable i.e, a pointer.
You do not need to store a pointer value in a variable in order to use it in an expression. In fact, just the opposite: if you want to use the value of a pointer variable in an arithmetic expression, you must first read the value from it -- a process called "lvalue conversion". The same applies to variables of all types and expressions involving most operators. Most operations are defined in terms of values, and variables are just one way to convey those.
So how does
arr 1
arithmetic work similar to pointer arithmetic?
There is no "similar to" here. It is pointer arithmetic. arr
is automatically converted to a pointer value. That value is a suitable operand for the addition operator, provided that the other operand is of integer type. This is a pointer arithmetic expression.
Also this:
*(arr 1)
would give us the value in the addressarr 1
.
Yes, though it would be more idiomatic to say the value at address arr 1
.
I do realize that we can dereference an address, but here I kind of find it difficult to work with it because I kind of lose the "hey this pointer points to this address.."
Well, most people would write *(arr 1)
as arr[1]
, which is 100% equivalent, but easier to read and usually clearer. Other than that, I'm not sure what you're asking, if anything.
is this the exact way that we can differentiate an address from a random value in a computer? Like
arr 1
leads to the address of the next integer in this case, and not normal1
(pointer arithmetic basically).
How a C program interprets a given sequence of bytes is determined by the data type it attributes to the sequence. That is exactly the function of data typing. There is no difference discernable in the underlying physical memory, it is all a manner of the program's interpretation. x 1
is pointer arithmetic if x
has pointer type, including as the result of automatic conversion from an array. It is integer addition if x
has type int
, long
, etc.. It is floating-point addition if x
has type double
, float
, or long double
.