i have tried a c program on array and pointers
#include<stdio.h>
int main()
{
int a[10], i;
for(i=0; i<10; i++)
{
a[i]=0;
}
fun(a,i);
}
fun(int *p, int i)
{
for (i=0; i<10; i++)
{
printf("%d\n", &*(p+i));
}
}
output is:
2752228
2752232
2752236
2752240
2752244
2752248
2752252
2752256
2752260
2752264
it prints addresses instead of array elements
* and & together here nullify each other's effect. &*(p+i) is equivalent to (p+i). (p+i) gives the address of the ith element of the array. To access the element's value you need to remove & from that expression, which will be *(p+i) and is equivalent to p[i].
Note: Instead of using a loop to initialize all elements of an array you can use initializer list as follows
int a[10] = {0};
Also you have to pass size of the array to the function. Your function should use that size to know the length of the array passed.
fun(int *p, int size){
for (int i=0; i < size; i++){
printf("%d\n", p[i]);
}
}
Do not forget to add a function prototype before main
void fun(int *p, int size);
and call it
fun(a, sizeof(a)/sizeof(a[0]));
&*x side by side applied results in x and here that x is p+i. p is the pointer to the first element of the array and added i to it, the value is incremented by sizeof *p here sizeof int which is 4 bytes in your case. More clearly you printed &p[i] in each iteration and that too with wrong format specifier. Use %p format specifier for printing address.
If you want to print the array - remove the address of operator & and instead use the value that you want to print *(p+i) or p[i].
You have passed i though not clear why. You have used hard-coded value for array length. Know that if your intention was to pass the size of the array you could pass sizeof arr/sizeof arr[0] - this term is nothing but the size of the array.
Related
I practiced today some C code, especially array with return function and pointers.
And I found some code which were really confusing and want to know why it is.
So I have first a function which print all elements out of the array.
void function(int *arr)
{
...
printf("%d, arr[i]);
}
Now in main I have a 2D array and a 1D array.
int array2D[2][2] = {{1,2}, {3,4}};
int array1D[3] = {1,2,3};
function(*array2D); // Why do I need here the derefernce pointer
function(array1D); // why I don't need here the deference pointer
And in another case:
void disp( int *num)
{
printf("%d ", *num);
}
int main()
{
int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
for (int i=0; i<10; i++)
{
/* Passing addresses of array elements*/
disp(&arr[i]); // why i need here & and above in the function not
}
}
This is really confusing me right now. Can someone explain me this?
The first line
function(*array2D);
is equivalent to
function(array2D[0]);
So you are passing the first array [1,2]. In C an array decays into a pointer
when it is passed to a function.
However, your function function1 should also get the number of
elements of the array.
void function(int *arr, size_t len)
{
size_t i;
for(i = 0; i < len; ++i)
printf("%d\n", arr[i]);
}
Then you can call it2
int array2D[2][2] = { { 1,2} ,{3,4}};
int array1D[3] = {1,2,3};
function(*array2D, sizeof *array2D / sizeof **array2D);
function(array1D, sizeof array1D / sizeof *array1D);
disp (&arr[i]); // why i need here & and above in the function not
Because arr[i] would give you the value stored at the position i, disp
expects a pointer, so you use the &-operator which returns the address of the
array at the position i, which is also equivalent to arr + i.
1Don't call your functions function. Technically that is valid name, but it
would be better if you give your function more explicit names so that just by
reading the name, you know what the functions does.
2Note that sizeof array / sizeof *array only works with arrays. If you have a
function and you expect an array, you will get only a pointer to the array.
In this case you also would need to pass the length of the array.
We're used to the fact that int mike[10] decays to int *, which points to the first thing in the array. So it seems like int sam[5][10] might also decay to int * pointing to the first element of the array. But int sam[5][10] is not a "two-dimensional array of int" that decays to an int pointer, it's an array of five arrays of ten integers. The first thing in sam is the first of the five arrays, so sam decays to a pointer to an array of ten integers, which type is written int (*)[10], though it rarely is written.
So your array2D decays to a different type than integer pointer, which is why your call function(array2D); creates a type mismatch. But your call function(*array2D); does work because (as noted above) *array2D is the same as array2D[0], which is an array of integers, and does decay to int *.
For your second case, arr is an array, but arr[i] is an int, since it is just one position in the array. The ampersand operator makes a pointer of what it operates, so &arr[i] is a pointer, and the call works.
#include<stdio.h>
#include<stdlib.h>
int main()
{
int i, j;
int(*p)[3];
p = (int(*)[3])malloc(3*sizeof(*p));
for(i=0; i<3; i++)
{
for(j=0; j<3; j++)
printf("%d", p[i][j]);
}
return 0;
}
p is a pointer to an array of 3 integer then why it is behaving as a 2D array
It is a completely superfluous cast that only adds clutter. Or in case of C++ it is needed, but you should never be using malloc in C++...
p is an array pointer to an array of type int [3]. *p is an array and therefore 3*sizeof(*p) gives the size of 3 such arrays, 3*3*sizeof(int). So the code allocates an array of arrays - a 2D array.
p is set to point at the first element of that array. p[i] is pointer arithmetic on an array pointer and gives you array number i. Therefore a pointer to a 1D array can be used to access a 2D array.
A better way to write the malloc call would be this:
p = malloc( sizeof(int[3][3]) );
You example never initializes the arrays, so printing their contents would give garbage and possibly undefined behavior. Corrected code:
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
int(*p)[3];
p = malloc( sizeof(int[3][3]) );
for(size_t i=0; i<3; i++)
{
for(size_t j=0; j<3; j++)
{
p[i][j] = (int)j;
printf("%d ", p[i][j]);
}
printf("\n");
}
free(p);
return 0;
}
Related topic: Correctly allocating multi-dimensional arrays.
malloc is a command to allocate a block of memory according to the size of data you needed (in byte).
in this case you are trying to allocate a block of memory for an array of integer with size of 3.
meanwhile sizeof() is a method to get actual byte size of memory would be used for a data type which is an integer in this case. and because you are needing an array with size of 3, that's why the 3 multiplier comes for
and than you would like to type cast as an pointer into an array of integer with size of 3 to be used later
I want to pass an array as a parameter to another function:
int i;
int main()
{
int a[5] = {1, 2, 3, 4, 5};
printf("Main:\n");
for(i=0; i<sizeof(a)/sizeof(int); i++)
{
printf("%i\n", a[i]);
}
func(a);
return;
}
void func(int a[])
{
printf("Func:\n");
for(i=0; i<sizeof(a)/sizeof(int); i++)
{
printf("%i\n", a[i]);
}
}
The loop in the main function prints all 5 values:
Main:
1
2
3
4
5
But the loop in the function func only prints 2 values:
Func:
1
2
Why this strange behaviour?
I want to pass an array as a parameter to another function:
This is a common pitfall. Arrays do not bring along their length, as they do in other languages. A C "array" is just a bunch of contiguous values, so sizeof will not (necessarily) return the length of the array.
What actually happens is that the function gets passed a pointer to the area of memory where the array is stored (and therefore, to the first element of the array), but no information about that area's size. To "pass an array with size", you must do something to provide the extra information:
explicitly pass also its length as an extra parameter. Safer: you can pass uninitialized arrays.
use a special "terminating" value on the array. More compact: you pass only one parameter, the pointer to the array.
(suggested implicitly by #CisNOTthatGOODbutISOisTHATBAD's comment): pass a pointer to a struct holding a pointer to the memory and a size_t length in elements (or in bytes). This has the advantage of allowing to store yet more metadata about the array.
For arrays of integral type, you could even store the length in the first (zeroth) element of the array. This can sometimes be useful when porting from languages that have 'measured' arrays and indexes starting from 1. In all other cases, go for method #1. Faster, safer, and in my opinion clearer.
Strings are arrays of characters that employ a variation of method #2: they are terminated by a special value (zero).
Using method #1, your function would become:
void func(size_t n, int a[])
{
printf("Func:\n");
for (i=0; i < n; i++)
{
printf("%i\n", a[i]);
}
}
(it is equivalent to void func(size_t n, int *a) ).
Declaring a function with a parameter of array type is equivalent to declaring it with a parameter of pointer type, i.e. your function is equivalent to:
void func(int *a)
As such, the computation of sizeof(a) inside func computes the size of an int *, not the size of the original array (5 * sizeof(int)).
Since the size of an int * on your platform is apparently twice the size of an int, you see two values printed inside the function in contrast to the five printed outside it (where sizeof(a) correctly computes the size of the array).
This is all related to the fact that when you pass an array to a function, what you're actually doing is passing a pointer to its first element.
Note in passing that this is a FAQ of the comp.lang.c newsgroup:
http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr#aryparmsize
I would change the code to this:
int i;
const int N = 5;
int main()
{
int a[N] = {1, 2, 3, 4, 5};
printf("Main:\n");
for(i=0; i<N; i++)
{
printf("%i\n", a[i]);
}
func(a);
return;
}
void func(int a[])
{
printf("Func:\n");
for(i=0; i<N; i++)
{
printf("%i\n", a[i]);
}
}
Parameter N is constant and define size of array.
I think it is better way, then 2 parameters in function.
Suppose I have a function, int function(int N, int c[N]){...}, taking as parameters an integer and an array. Suppose now I have a double array **c of size 'N times 2' and suppose, I want to apply the function function to one column of the double arrow, c[i][0], i varying from to N-1. How am I supposed to use this function. Does it looks like something like function(N,*c[0]) ?
Does anyone can help ?
An array in C always decays to a pointer to its first element when passed into a function. This is good to know in some situations.
As an example, you could write
int list[10];
func (int *x) {
int i;
for (i = 0; i < 10; i++) {
printf("%d", x[i]);
}
}
x[i] is really just syntactic sugar. In C, when you use bracket notation to access an element of an array, it gets converted to *(x + i), where x is the name of the array.
This works because of pointer arithmetic. If x is the name for an array of 10 integers, then the value of x in an expression is the address of the first integer of the array.
x + i will always point to the i-th element after x (C takes into account the size of the element type stored in the array, and increments the pointer accordingly).
Thus, when passing 2d arrays, the array decays to a pointer to its first element - which is an array.
A function signature taking a 2d array can be written as
func(int x[][columns] {
...
}
// but could also be written as
func(int (*x)[columns]) {
...
}
which indicates that x is a pointer to an array of integers.
Sometimes you need to write a function to accept a 2 dimensional array where the width is not known until run time. In this case, you can pass a pointer to the [0][0] element and also pass the two dimensions, and then use pointer arithmetic to get the right element. For example,
print_2d_array (int *x, height, width) {
int i, j;
for (i = 0; i < height; i++) {
for (j = 0; j < width; j++) {
printf("%d", x[i * width + j]);
}
}
}
int list[10][10];
print_2d_array (&list[0][0], 10, 10);
would work for a dynamically allocated 2d array.
In c langauge, for single dimentional array you no need to mention the size of the array in the function arguments while passing an array to that function.
If it is a single dimentional array
...
int a[10];
func(10, a);
...
void func(int size, int x[]) //no need to mention like int x[10]
{
//here x is not an array. Its equivalent to int *
printf("%d", sizeof(x)); // this will print 4 or 8 not 40
}
If it is 2D array
...
int a[10][5];
func (10, a);
...
void (int rows, int x[][5]) //here int x[][] is invalid
{
}
I am new to C programming and this is my problem:
I want to store the first value of each array in a new array, then the second value of each array in a new array and so on.
I could declare the array of pointers but I don't know how I use it!
Please I need Help.
int main()
{
int t1[4]={0,1,2,3};
int t2[4]={4,5,6,7};
int t3[4]={8,9,10,11};
int t4[4]={12,13,14,15};
int *tab[4]={t1,t2,t3,t4};
int i,j,k,l;
for (i=0; i<4;i++)
{
printf("%d\t", *tab[i]);
}
return 0;
}
When I do this, I store just the first value of each array.
Your terminology is a little bit all over the place. I think the easiest way to answer your question is to go through your code line by line.
int main()
{
int t1[4]={0,1,2,3}; //Declares a 4 integer array "0,1,2,3"
int t2[4]={4,5,6,7}; //Declares a 4 integer array "4,5,6,7"
int t3[4]={8,9,10,11}; //Declares a 4 integer array "8,9,10,11"
int t4[4]={12,13,14,15}; //Declares a 4 integer array "12,13,14,15"
int *tab[4]={t1,t2,t3,t4};//Declares a 4 pointer of integers array "address of the first element of t1, address of the first element of t2, ..."
int i,j,k,l; //Declares 4 integer variables: i,j,k,l
for (i=0; i<4;i++)
{
printf("%d\t", *tab[i]); //print out the integer that is pointed to by the i-th pointer in the tab array (i.e. t1[0], t2[0], t3[0], t4[0])
}
return 0;
}
Everything you are doing seems ok until your loop. You are showing only the first integer of every array because you are not going through them. To iterate over them, your code should look like this:
for (i=0; i<4;i++)
{
for (j=0; j<4; j++)
{
printf("%d\t", *(tab[j] + i));
}
}
The above code uses two loop counters, one (the i) to go through the positions in the array (first value in the array, second value in the array, etc.); the other to go through the different arrays (the j). It does this by retrieving the pointer stored in tab[j] and creating a new pointer that has the right offset to show the value for the ith column. This is called pointer arithmetic (there is additional information about pointer arithmetic here)
Most people find the syntax *(tab[j] + i) to be clunky, but it is more descriptive of what is actually happening. In C, you can rewrite it as tab[j][i], which is much more usual.
You have stored the data as you intended, you just need to access it properly
for (i=0; i<4;i++)
{
for (j = 0; j < 4; j++) {
int* temp = tab[i];
printf("%d\t", temp[j]); // or try the next line...
printf("%d\t", *(temp + j)); // prints same value as above line
printf("%d\t", tab[i][j]; // the same value printed again
}
}
All of the above print the same value, it is just different ways of accessing that value using pointer arithmetic. Each element of tab is a int* the value of each is the address of your other defined int[] arrays at the start
Edit: In response to the comment of Jerome, you can achieve that by declaring 4 arrays
int tab1[4]={*t1,*t2,*t3,*t4};
int tab2[4]={*(t1+1),*(t2+1),*(t3+1),*(t4+1)};
int tab3[4]={*(t1+2),*(t2+2),*(t3+2),*(t4+2)};
int tab4[4]={*(t1+3),*(t2+3),*(t3+3),*(t4+3)};
Now tab1 contains the first elements of each array, tab2 the second elements, and so on.
Then you can use
int *tttt[4]={tab1,tab2,tab3,tab4};
for (i=0; i<4;i++) {
for (j = 0; j < 4; j++) {
printf("%d\t", tttt[i][j]);
}
}
to print what you wanted. If you declared another pointer array like you did at the start
int* tab[4] = {t1,t2,t3,t4};
then essentially in matrix terms, tttt is the transpose of tab
You store everything but you just don't show it. Try
for (i=0; i<4;i++)
{
for (j=0; j<4; j++)
printf("%d\t", *(tab[i]+j));
}
int* (*a[5])[5][5][5] declares an array of 5 pointers to a 3d array of pointers to ints
int* (*(*a[5])[5])[5][5][5] declares an array of 5 pointers to an array of 5 pointers to a 3d array of pointers to ints.
#include <stdio.h>
int main()
{
int t1[4]={0,1,2,3};
int t2[4]={4,5,6,7};
int t3[4]={8,9,10,11};
int t4[4]={12,13,14,15};
int (*tab[4])[4]={&t1,&t2,&t3,&t4};
int i,j,k,l;
for (i=0; i<4;i++)
{
printf("%d\t", (*tab[i])[1]);
}
return 0;
}
There's a difference between t2 and &t2. Though they have the same value their types are different. int [4] vs int (*)[4]. The compiler will throw a warning (clang) or error (gcc).
int a[4] is conceptually at compiler level a pointer to an array of 4 as well as being the array itself (&a == a).
int (*a)[4] is conceptually at compiler level a pointer to a pointer to an array of 4 as well as being a pointer to the array itself (a == *a) because it's pointing to an array type where the above is true.
At runtime, if an int * and int (*a)[4] point to the same address, they are physically identical – it's just an address, the same address. The type only matters in how the compiler interprets and produces arithmetic operations with that address and the assembly it actually outputs based on the type. You can cast the address to any type you want in order to achieve the desired code output to manipulate data at the address it holds. An int a[4] type however is physically the array itself but you use it as if there is a pointer a to it in memory which is given the same address as the array itself. A pointer to int a[4] means 'a pointer to the address range a that is treated by the compiler as an array with int element width, where the compiler treats the start of the array as if it were a pointer to the array', and any operations on that type will be consistent in a derefernce chain i.e. you must at compiler level use (*a)[0] to access the first element if the type is a pointer to an array, but if you cast the same address to int * then you need to use a[0] to access the member.