6

Please help me understand the programs below.

#include<stdio.h>
int main()
{
    int a[7];
    a[0] = 1976;
    a[1] = 1984;
    printf("memory location of a: %p", a); 
    printf("value at memory location %p is %d", a, *a); 
    printf("value at memory location %p is %d", &a[1], a[1]);
    return 0;
}

&a[1] and &a+1. Are they same or different?

#include <stdio.h> 
int main() 
{
    int v[10];
    int **p; 
    int *a[5];
    v[0] = 1234;
    v[1] = 5678;
    a[0] = v; 
    a[1] = v+1;
    printf("%d\t%d\t%d\t%d\n", *a[0],*a[1],a[0][0],**a);
    printf("%d\n", sizeof(v));
    return 0;
} 

I wanted to know how *a[5] is represented in memory. Is *a a base pointer that points to a[0],a[1],a[2],a[3],a[4]?

#include<stdio.h>

int main()
{
    int v[10];
    int **p;
    int (*a)[10];
    a=&v;
    printf("%d\n",*a);
        return 0;
}

a=v; // gives error why? does v here decay into *v. Then does &v get decayed into (*)[]v? & means const pointer. Here, how is it possible to set a const pointer to a non-const pointer without a typecast?

Where does the array get stored in the memory. Does it get stored onto the data segment of the memory.

#include<stdio.h>

int main()
{
    int carray[5]={1,2,3,4,5};
    printf("%d\n",carray[0]);
    printf("%d\t%d\t%d\n",sizeof(carray),sizeof(&carray),sizeof(&carray[0]));
    return 0;
}

EDITED:

I have gone through some of the articles which stated that the only two possible situations where an array name cannot be decyed into pointer is the sizeof and &. But in the above program sizeof(&carray) gives the size as 4. and &carray decays into (*)[]carray as its an rvalue.

Then the statement that array name cannot get decayed into pointers on two conditions sizeof and & becomes false here.

Jacob Schoen
  • 14,034
  • 15
  • 82
  • 102
Angus
  • 12,133
  • 29
  • 96
  • 151
  • To print a value of type `size_t`, such as the result of `sizeof`, either use `%zu` (if your compiler supports it) or convert the value to some other type and use a format appropriate for that type. `%d` requires an argument of type `int`, and can fail badly if you give it a `size_t` argument. To print a pointer value, you must convert the value to `(void*)` and use `%p`; different pointer types are not generally compatible. Example: `printf("obj has size %lu and address %p\n", sizeof obj, (void*)&obj);` – Keith Thompson Sep 11 '11 at 16:54
  • Read section 6 of the [comp.lang.c FAQ](http://c-faq.com/). Understand that arrays and pointers are two *very* different things; do not listen to anyone who tries to tell you that they're equivalent. – Keith Thompson Sep 11 '11 at 16:57
  • @Keith:Thanks keith.Will read those sections. – Angus Sep 11 '11 at 17:06
  • "But in the above program `sizeof(&carray)` gives the size as 4. and `&carray` decays into `(*)[]carray` as its an rvalue." No, it does not decay. The result of the address-of operator is *always*, well, an address. That is, while `carray` is an array, `&carray` is its address. An address on your machine is, perhaps disappointingly, only 4 bytes long. Consequently, `sizeof(&carray)` yields the address size, 4. No decay is involved. I'm fairly sure that `sizeof(*&carray)` yields 20, showing that the array size was perfectly well preserved through the back and forth. – Peter - Reinstate Monica Oct 09 '15 at 11:47

2 Answers2

5

&a[1] and &a+1. Are they same or different?

Different. &a[1] is the same as (a+1). In general, x[y] is by definition equivalent to *(x+y).

I wanted to know how *a[5] is represented in memory. Does *a is a base pointer that points to a[0],a[1],a[2],a[3],a[4].

In your second example, a is an array of pointers. *a[i] is the value of the object, the address of which is stored as the ith element in your array. *a in this case is the same as a[0], which is the first element in your array (which is a pointer).

a=v //why this gives error

Because a (in your last example) is a pointer to an array. You want to assign to a, then you need to assign the address of the array v (or any other array with correct dimensions);

a = &v;

This is very good that you've commited to understanding things, but nothing will help you better than a good C book.

Hope this helps.

Community
  • 1
  • 1
Armen Tsirunyan
  • 130,161
  • 59
  • 324
  • 434
-3

Stuff you are gonna need to know when dealing with pointers is that:

int *a and int a[]

is a declaration of an Array, the only diffrence is that in a[] youre gonna have to declare its constant size, *a gives you flexability, it can point at an array size 1 to infinity

int *a[] and int **a

is a declaration of an Array of Array,sometimes called Matrix, the only diffrence is that in *a[] youre gonna have to declare how many Arrays a[] gonna contain pointers of, **a gives you flexability, it can point at any Array of arrays that you want it to be assigned to.

IN GENERAL: When adding & to a variable, your adding a * to its Type definition:

int a;

&a -> &(int)=int*

when adding * to a variable, you decrase a * from its Type definition

int *a;

*a -> * (int * )=int

int *a;
&a - the Address given to the pointer a by the system(pointer of pointer = **a)
&a+1 - the Address to the beginning of the array + 1 byte
&a[1] == &(a+1) - the Address to the beginning of the array + 1 size of int

int **a;
*a == a[0] - the Address of the first Array in the array of arrays a
*a[0]==a[0][0] - the first int of first array

int *a, b[5];
*a=*b - ERROR because a points at garbage to begin with
a=b - a points at array b

ask me what else you want to know and ill edit this answer.

Ofek Ron
  • 8,354
  • 13
  • 55
  • 103
  • `int *a` declares a pointer object; it does not declare a pointer object. `int a[]` declares an array object; it does not declare a pointer object. Arrays are not pointers. Pointers are not arrays. – Keith Thompson Sep 11 '11 at 16:50
  • you can declare int a[] and int *b and have a command like b=a and a=b is what i meant, you can go ahead and try it. – Ofek Ron Sep 11 '11 at 19:47
  • 2
    I suggest you try it. If you declare `int a[]` *as a parameter*, then it's really a pointer declaration, not an array declaration. In any other context, `int a[]` or `int a[N]` declares `a` as an array, and an array name cannot appear on the left side of an assignment. – Keith Thompson Sep 12 '11 at 03:07