arrays and pointers arithmetic [duplicate] - c

This question already has answers here:
Is an array name a pointer?
(8 answers)
Closed 8 years ago.
Suppose an array int a[10].
Why we can't do a=a+1 ? but the same is valid with a pointer variable.
int *ptr = a;
ptr = a+1;
How are both scenarios seen practically?

Because array locations are constant.
You can't change the value of a, since that represents the starting address of the array. Moving it doesn't make any sense.
With int *ptr; your variable ptr is just a single pointer and can of course be set to point to anywhere you like.
There's no contradiction here. It's a little like with functions, the name of a function evaluates to its address (called "a function pointer") but you can't assign to that either.

Because Array name is constant pointer pointing to its first element.You cannot change the value of constant variables,i,e what the const keyword is used for.
int a[10]; //here a (array variable is Const i,e you Cannot a=a+1)
int* const p=&a[0]; //here Also Same,Now p is Const i,e you Cannot p=p+1.
But Here:
int* pp=&a[0];//Here pp=pp+1 will work, Because pp is not Const.

You can if the array is a function argument
#include <stdio.h>
int rval(int a[10]) {
a = a + 1;
return a[0];
}
int main(){
int a[10] = {0,1,2,3,4,5,6,7,8,9};
printf ("%d\n", rval(a));
return 0;
}
Program output
1

Related

the code is giving error during compilation, please explain [duplicate]

This question already has answers here:
Is there a reason why an array name is not an lvalue?
(4 answers)
Is an array name a pointer?
(8 answers)
Closed 6 years ago.
#include <stdio.h>
int main(void) {
int values[10];
int a = 10;
values = &a;
printf ("the value is = %i.\n\n", *values);
return 0;
}
This code is written just for experimenting on pointers, I have just started learning it.
My question is that if the name of the array is a pointer then why cant we copy some other variable's address into it.
The error that it gave was "assignment to expression with array type"
please explain it in simple way.
Arrays cannot be assigned to. You can store values into array elements and you can store array addresses into pointers, but arrays themselves cannot appear on the left side of an assignment operator.
You can change values to a pointer:
#include <stdio.h>
int main(void) {
int *values;
int a = 10;
values = &a;
printf ("the value is = %i.\n\n", *values);
return 0;
}
or you can store a into values[0]:
#include <stdio.h>
int main(void) {
int values[10];
int a = 10;
values[0] = a;
printf ("the value is = %i.\n\n", *values);
return 0;
}
think of arrays as parking lots:
You can store a car into a parking spot (array element)
You can write the lot number on a piece of paper (lot pointer, you can retrieve the car by giving that to the operator).
You cannot store a parking lot into another parking lot, they are not moveable.
Array designators are non-modifiable lvalues. You may not use an array designator in the left side of the assignment expression.
Thus the compiler issues an error for this statement
int values[10];
int a = 10;
values = &a;
^^^^^^^^^^

count array length in c by pointer, the answer is wrong [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 6 years ago.
#include <stdio.h>
int a[3] = {1,2,3};
void cal(int* item){
printf("Length(inside) is %lu\n", sizeof(item)/sizeof(item[0]));
}
int main(){
printf("Length(outside) is %lu\n", sizeof(a)/sizeof(int));
cal(a);
}
The code above comes out with the result that
Length(outside) is 3
Length(inside) is 2
However, it is wrong, because both of them should be 3, what's wrong with my code?
First of all, you should be using %zu fomat specifier to print the result.
Secondly, when passed to a function as argument, array name decays to the pointer to the first element, so the sizeof(item) will not work as expected.
Basically what you're doing is sizeof (int *)/ sizeof (int) and in your environment, it is likely that a pointer occupies 8 bytes and an int takes 4, so you get this result.
This is because the array decays into a pointer when it is passed to a function.
So essentially what you are doing is
sizeof(int*)/sizeof(int);
What you can think is the difference between
int a[5];
sizeof(a)/sizeof(a[0]); //this works
and
int a[5];
int* p = a;
sizeof(p)/sizeof(p[0]);

What is the difference between pointer to array and pointer to pointer?

I'm new in programming and learning about pointers in array. I'm a bit confused right now. Have a look at the program below:
#include <stdio.h>
int fun();
int main()
{
int num[3][3]={23,32,478,55,0,56,25,13, 80};
printf("%d\n",*(*(num+0)+1));
fun(num);
printf("%d\n", *(*(num+0)+1));
*(*(num+0)+0)=23;
printf("%d\n",*(*(num+0)));
return 0;
}
int fun(*p) // Compilation error
{
*(p+0)=0;
return 0;
}
This was the program written in my teacher's notes. Here in the main() function, in the printf() function dereference operator is being used two times because num is pointer to array so first time dereference operator will give pointer to int and then second one will give the value at which the pointer is pointing to.
My question is that when I'm passing the array name as argument to the function fun() then why *p is used; why not **p as num is a pointer to array?
Second thing why *(p+0) is used to change the value of zeroth element of the array; why not *(*(p+0)+0)=0 as in the main() function *(*(num+0)+0) is used to change the value of zeroth element?
The whole thing is very confusing for me but I have to understand it anyway. I have searched about this and found that there is a difference between pointer to array and pointer to pointer but I couldn't understand much.
The trick is the array-pointer-decay: When you mention the name of an array, it will decay into a pointer to its first element in almost all contexts. That is num is simply an array of three arrays of three integers (type = int [3][3]).
Lets analyse the expression *(*(num + 1) + 2).
When you mention num in the expression *(num + 1), it decays into a pointer to its first element which is an array of three integers (type = int (*)[3]). On this pointer pointer arithmetic is performed, and the size of whatever the pointer points to is added to the value of the pointer. In this case it is the size of an array of three integers (that's 12 bytes on many machines). After dereferencing the pointer, you are left with a type of int [3].
However, this dereferencing only concerns the type, because right after the dereferencing operation, we see expression *(/*expression of type int[3]*/ + 2), so the inner expression decays back into a pointer to the first array element. This pointer contains the same address as the pointer that results from num + 1, but it has a different type: int*. Consequently, the pointer arithmetic on this pointer advances the pointer by two integers (8 bytes). So the expression *(*(num + 1) + 2) yields the integer element at an offset of 12 + 8 = 20 bytes, which is the sixth integer in the array.
Regarding your question about the call of fun(), that call is actually broken, and only works because your teacher did not include the arguments in the forward declaration of fun(). The code
int fun(int* arg);
int main() {
int num[3][3] = ...;
...
fun(num);
}
would have generated a compile time error due to the wrong pointer type. The code of your teacher "works", because the pointer to the first array in num is the same as the pointer to the first element of the first array in num, i. e. his code is equivalent to
int fun(int* arg);
int main() {
int num[3][3] = ...;
...
//both calls are equivalent
fun(num[0]);
fun(&num[0][0]);
}
which would compile without error.
This example shows a matrix, pointers to the first integers of arrays, and pointer to pointer
#include<stdio.h>
int fun(int (*p)[3]); /* p is pointer to array of 3 ints */
int main()
{
/* matrix */
int num[3][3]={{23,32,478},{55,0,56},{25,13, 80}};
/* three pointers to first integer of array */
int *pnum[3] = {num[0], num[1], num[2]};
/* pointer to pointer */
int **ppnum = pnum;
printf("%d\n", *(*(num+1)+2));
fun(num);
printf("%d\n", *(*(num+1)+2));
pnum[1][2] = 2;
printf("%d\n", *(*(num+1)+2));
ppnum[1][2] = 3;
printf("%d\n", *(*(num+1)+2));
return 0;
}
int fun(int (*p)[3])
{
p[1][2]=1;
return 0;
}
You do not actually need any pointers to print anything here.
Your int num[3][3] is actually an array of three elements, each of which is an array of three integers. Thus num[0][0] = 23, num[1][1] = 0, and so on. Thus you can say printf("%d", num[0][0]) to print the first element of the array.
Pointer to variable:
Pointer is variable which stores the address( of a variable). Every one know that.
Pointer to Array:
An array is a variable which has the starting point(address) of group of same objects.
And the pointer is a variable which stores the starting point(address) of an Array.
For example:
int iArray[3];
iArray is a variable which has an address value of three integers and the memory is allocated statically. And the below syntax is provided in a typical programming languages.
// iArray[0] = *(iArray+0);
// iArray[1] = *(iArray+1);
// iArray[2] = *(iArray+2);
In the above the iArray is a variable through which we can access the three integer variables, using any of the syntax mentioned above.
*(iArray+0); // Here iArray+0 is the address of the first object. and * is to dereference
*(iArray+1); // Here iArray+1 is the address of the second object. and * is to dereference
So simple, what is there to confuse.
The below lines are for your understanding
int iArray1[3];
int iArray2[3][3];
int *ipArray = 0;
ipArray = iArray1; // correct
ipArray = iArray2[0]; // correct
ipArray = iArray2[2]; // correct
int **ippArray = iArray2; // wrong
As per the above last line, compiler will not take it as a valid assignment. So **p is not used.
Pointer arthmatic cannot be applied on double arrays because of the way memory is allocated.

passing pointer as size of an array in C

I want to pass a pointer as a size element of an array
example:
void hello(int array1[how can i refer pointer "ptr" here][2])
{
// i want to access the array used in the main() here
printf("hi");
}
int main()
{
int c=5;
int *ptr=&c;
a[*ptr][2];
a[0][1]=0;
a[0][2]=4;
}
I apologize for not being clear with my question here , i want to access the array used in the main() function in my hello() function.
You will have to use the value pointed to by the pointer:
a[*ptr][2];
ptr is the address pointed to by the pointer not the value stored there. You use the dereference operator * to get the value.
Of course, ptr is not of type int, it's of type int * (integer pointer). An array subscript must be of type int.
Maybe what you want is a[*ptr][2].
You need to deference the pointer by using *ptr so
int c = 5;
int *ptr = &c;
a[*ptr][2];
otherwise you are not using the value of ptr you are using its address in memory which returns an error.
Use the dereference operator *:
a[*ptr][2];
The expression *ptr tells the compiler to use the value pointed to by ptr.
As for your updated question, that's not possible. But it's not needed either, as it's passed as a pointer anyway.
When declaring a function, this:
void foo(int a[5][5])
is the same as this:
void foo(int a[][2])
And also the same as this:
void foo(int (*a)[2])
It has pretty much been answered already, you can't call an adress in the array a[0x3950f2][2]
Always use the pointer* to get the position in the array a[*ptr][2] to get the expected value - in this case: a[*ptr][2] == a[5][2]. You may read this.
Edit to your updated question: You can't to this. You can use the pointer when you call the function or when using the variable in the function.
Your second edit:
void hello(int **array1)
{
// i want to access the array used in the main() here
printf ("hi");
a[0][0] = 24;
}
int main()
{
int c = 5;
int *ptr = &c;
int **a;
a[*ptr][2];
a[0][1] = 0;
a[0][2] = 4;
hello (a);
return 0;
}

But the sizeof() operator doesn't work on pointer but works on the array name. Why is it so? [duplicate]

This question already has answers here:
Stack pointer difference for char pointer and array
(1 answer)
C pointers and arrays/ 'sizeof' operator [duplicate]
(2 answers)
Closed 9 years ago.
Hi i was doing this exercise and wanted to get the size of array after i pass the pointer to the array to the function:
But the sizeof() operator doesn't work on pointer but works on the array name. Why is it so?
Is this any way i could get the size of the array on the findPut function?
#include <stdio.h>
//global vars
int i,j;
//functions prototypes
void findPut(int *, int);
int main(void){
int ins=4;
int arr[10]={1,2,3,5,6,7,8};
printf("%d\n",sizeof(arr)); //gives 40
int *ap=arr;
printf("%d\n",sizeof(*ap)); //gives 4 instead of 40 why?? if ap and arr the same thing
findPut(ap, ins);
return 0;
}
//functions
void findPut(int *p, int n){
//vars
//getting size of array
int size= sizeof(*p);
//sizeof(int);
printf("%d\n",size); //gives 4 but expected 40????
}
When you dereference *p you get an int, so it returns 4 (which is the size of int on your platform).
Because, sizeof(*ap) means sizeof(arr[0]); since array is of type int, sizeof(int), since in your system configuration, int is of size 4 you got the result as 4.
You can try it your self by printing the value of *p, you will get the value of arr[0].
Let int *p be a pointer and int arr[10]
Please note that:
Arrays and Pointers are not equivalent.
sizeof operator is a compile time operator.
sizeof(arr), evaluates to 10*sizeof(int), that is 10*4=40 in your case.
When you dereference p (getting the value that p points to), it doesn't give you whole array, but one unit of
your array that is an int so, *p means arr[0]. sizeof(arr[0]) is
4 (in your case) that's obvious.
When you use sizeof(p), it will give you the size of the pointer in your machine.
In my machine it is 8.
main function's return type should be int always. It has to retport operating system the exit status of the program. If you use void it might return random garbage.
The example demonstrate the issue:
#include<stdio.h>
#include<stdlib.h>
int main(){
int *p=NULL;
int arr[10]={10,1,2,3,5,6,7,8,9,10};
p=arr;
printf("values: arr[0]=%d *p= %d\n\n",arr[0],*p);
printf("sizes : sizeof(arr[0])=%lu, sizeof(*p)= %lu sizeof(int)=%lu\n\n",sizeof(arr[0]),sizeof(*p),sizeof(int));
printf("Sizeof pointer p: %lu \n\n",sizeof(p));
printf("Sizeof arr: %lu \n\n",sizeof(arr));
printf("Pointing p to the first byte of 100 byte sequence\n\n");
p=malloc(100);
printf("Though p is pointing 100 byte block, sizeof(p)=%lu",sizeof(p));
return 0;
}
Essentially, sizeof evaluates the sizeof type but not the sizeof type it points to.
Thank you, i do appreciate your knowledge but is there any way i could
find the size of array inside another function( not the one where i
define the array).
You can't in my IMHO! You have to pass the size along with the array.
Example:
int main(){
int arr[10]={10,1,2,3,4,5};
printf("Length of array: %lu",findLength(arr,sizeof(arr)));
return 0;
}
size_t findLength(int *p,int size){
return size/sizeof(*p);
}
You have an int array and an int pointer:
int arr[10] = {1,2,3,5,6,7,8};
int* ap;
ap = arr;
In C, the expression arr is equivalent to &arr[0]. It stands to reason, then, that *ap is equivalent to arr[0], which is an int, which for your binary has a size of 4.
You also need to understand that arrays and pointers aren't the same thing. You may have been confused by the fact that arrays and pointers are often used interchangeably in the sense that a pointer can store the address of the beginning of an array (its first element, in other words) and navigate the consecutive addresses as if it had the actual array passed to it.

Resources