zhm
zhm

Reputation: 107

Is the use of (arr+2)[0] right?

I am a student who will be a freshman in an university after this summer vacation.I want to learn about computer programing in advance but I run into some problems. Why when I run the program in devc++,the result is -1 and 44? When I read the book called Pointers On C,In the chapter on functions,the book says that the name of array is a pointer,and in C language arr[m]=*(arr+m),and arr[0] is composed by a pointer and a [number],so can I come to a conclusion that (arr+2),which is a pointer,and[0],can compose (arr+2)[0] equaling to *(arr+2+0)?

int main(void)
{
    int arr[10];
    for(int i=0;i<10;i++)
    {
        arr[i]=i+1;
    }
    int b=*(arr+1);
    int c=(arr+2)[0];//Is this true?
    printf("%d\n",b);
    printf("%d",c);
    return 0;
}

Upvotes: 1

Views: 220

Answers (4)

Persixty
Persixty

Reputation: 8589

Is the use of (arr+2)[0] right?

Linguistically yes. But very questionable practice.

The beautiful invention of C is pointer arithmetic and that is exemplified by the definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))).

So by definition (arr+2)[0] is the same as (*((arr+2)+(0))) and simplifies to *(arr+2) and arr[2] simplifies to the same thing.

Array subscripting in C is syntactic sugar on pointer arithmetic. The term 'syntatic sugar' is sometimes overused. But in this case it really is just syntactic sugar.

The example demonstrates a critically important fact about how C manages arrays. Pointer arithmetic works in units of the type (measured in bytes they occupy) and array subscripting the same. So adding to a pointer (arr+2) and subscripting into an array (arr[2]) have a fundamental relationship.

When you understand that and realise the that array subscripts start at 0 because of that because they're offsets you get "C" as a language.

Please never write code like that. Writing code like 7[A] gets funny looks.

Upvotes: 1

Adam
Adam

Reputation: 1386

#include <stdio.h> // printf


int main(void)
{
    int arr[10];
    
    
    printf("fill and print the array\n");
    for(int i=0;i<10;i++)
    {
        arr[i]=i+1;
        printf("%d -th element of the array = arr[%d] = %d\n",i+1, i, arr[i]);
    }
    
    
    printf("pointer arithmetic in c \n");
    int b=*(arr+1); // arr[m]=*(arr+m)
    int c=(arr+2)[0];//(arr+2)[0]  = *(arr+2+0)
    
    
    int n = 0;
    printf("%d -th element of the array = arr[%d] = %d\n",n+1, n , *(arr + n));
    printf("%d -th element of the array = %d\n",2,b);
    printf("%d -th element of the array = %d\n",3,c);
    
    return 0;
}

compile

gcc t.c -Wall -Wextra

run

./a.out

result:

fill and print the array
1 -th element of the array = arr[0] = 1
2 -th element of the array = arr[1] = 2
3 -th element of the array = arr[2] = 3
4 -th element of the array = arr[3] = 4
5 -th element of the array = arr[4] = 5
6 -th element of the array = arr[5] = 6
7 -th element of the array = arr[6] = 7
8 -th element of the array = arr[7] = 8
9 -th element of the array = arr[8] = 9
10 -th element of the array = arr[9] = 10

pointer arithmetic in c 
1 -th element of the array = arr[0] = 1
2 -th element of the array = 2
3 -th element of the array = 3

HTH

Upvotes: 0

Andrew
Andrew

Reputation: 2312

C allows you to do all sorts of clever things with arrays and pointers.

This is either a good thing (if you like writing clever code) or very frustrating (if later you have to maintain some of that clever code)

All of the following are equivalent:

  • (arr+2)[0]
  • arr[2]
  • 2[arr]
  • *( ( arr + 2 ) + 0 )
  • *( arr + 2 )

While they are equivalent, that doesn't necessarily mean you should use them interchangeably - my general recommendation is to use array notation when accessing an array, and pointer arithmetic when indexing into any other structures. Decaying an array into a pointer is prone to errors!

In noting that you have defined your data structure as an array int arr[10]; my advice would be to access it as arr[2] - then everyone is clear what you are trying to do, both now and in teh future.

As an aside (and see profile for affiliation) MISRA C dedicates a whole chapter (8.11) to pointer type conversion, and another (8.18) to the pitfalls of arrays and pointers - a fair bit of guidance and a total of 17 Rules between them...

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 311038

There is a typo in your code

for(int i=0;i<10;i++)
{
    arr[0]=i+1;
}

It seems you mean

for(int i=0;i<10;i++)
{
    arr[i]=i+1;
}

From the C Standard (6.5.2.1 Array subscripting)

2 A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). Because of the conversion rules that apply to the binary + operator, if E1 is an array object (equivalently, a pointer to the initial element of an array object) and E2 is an integer, E1[E2] designates the E2-th element of E1 (counting from zero).

So the expression

(arr+2)[0]

evaluates like

*( ( arr + 2 ) + 0 )

That is the same as

*( arr + 2 )

and in turn is the same as

arr[2]

You even may write

2[arr]

Pay attention to that the expression

 (arr+2)[0]

will be more clear if to introduce an intermediate pointer like

int *p = arr + 2;

and then to use the expression

p[0]

Upvotes: 1

Related Questions