11

I was googling and found the following syntax for pointers

 void main() { char a[10]="helloworld"; char *p=a; printf("%c",p[0]); } 

I didnt know that Pointers can be accessed in the array form too. I used to use * for pointer operations I used a[0] for arrays and *p for pointer operations, which is why I didnt know the other 2 things. Now from the above, we can access the second element of array in any one of the following ways

 printf("%C",a[1]); \\ this is the array printf("%c",*(a+1)); \\ this is the array using * printf("%c", p[1]); \\ using the pointer printf("%C",*(p+1)); \\ using the pointer 

Now I wonder: which is the faster operation? I read that operations using pointers are faster, and that this is why C stays at the top for fast execution and that no other language can beat its fastness.

Now the real question: What makes the pointer operations faster?

1) *(p+0) the *(Value at address) that makes the trick or

2) p[0]

since we use

 *(a+1) or *(p+1) both are same a[1] or p[1] both are same 

when a normal array can be used as *(a+1)( which uses * value at address) like a pointer. why do we use pointers for faster operations? When both have the same syntax, when normal array and pointer uses * in those syntaxes why pointers are faster?

But guys please tell me then why we use pointers ? My professor told me pointers are faster because they point to address rather a variable should be searched in the location.

8
  • 7
    Pointers are not faster than arrays, so the question is meaningless. Within the context of your example array is generally faster than pointer, although the difference is disappearingly small. Commented Aug 31, 2011 at 17:38
  • 1
    stackoverflow.com/questions/4939834/… Commented Aug 31, 2011 at 17:38
  • 4
    I think you confuse dereferencing a pointer like *p with addressing an array with a[i]. The latter is slower because it invokes a calculation(namely adding to the base address a the size of the type pointed to times i or a + sizeof(*a) * i. Commented Aug 31, 2011 at 17:39
  • I would imaging that in normal circumstances, with modern compilers the speed difference will be negligible. There might be situations where pointers will be more effective, but they should be less and less frequent. Commented Aug 31, 2011 at 17:46
  • Read section 6 of the comp.lang.c FAQ. Commented Aug 31, 2011 at 17:49

6 Answers 6

13

I wouldn't actually expect *(ptr + offset) to be faster than ptr[offset]. In fact, on my machine, the following functions are compiled into exactly the same assembly code:

int ArrayRef(int* array, int index) { return array[index]; } int PointerRef(int* array, int index) { return *(array + index); } 

which (cleaned up) looks like:

ArrayRef: pushq %rbp movq %rsp, %rbp movq %rdi, -8(%rbp) movl %esi, -12(%rbp) movl -12(%rbp), %eax cltq salq $2, %rax addq -8(%rbp), %rax movl (%rax), %eax leave ret PointerRef: pushq %rbp movq %rsp, %rbp movq %rdi, -8(%rbp) movl %esi, -12(%rbp) movl -12(%rbp), %eax cltq salq $2, %rax addq -8(%rbp), %rax movl (%rax), %eax leave ret 

(gcc 4.5.0, x86_64, no optimisations). Or with -O3

ArrayRef: movslq %esi, %rsi movl (%rdi,%rsi,4), %eax ret PointerRef: movslq %esi, %rsi movl (%rdi,%rsi,4), %eax ret 
Sign up to request clarification or add additional context in comments.

Comments

4

Array access is faster if the array is allocated in the local stack scope or in static memory since it can be directly accessed via an offset of the value in the EBP register or via a direct offset from a fixed address, rather than attempting to access the value of a pointer in a stack variable, and then adding to that variable's value and dereferencing.

For instance, if you write you array like:

int main() { int array[5] = {1, 2, 3, 4, 5}; //... more code return 0; } 

In order to access the value at array[3], the complier will only issue a simple command like (this is for x86):

MOV -8(%ebp), %eax 

This is because if we look at the stack, we would see the following:

EBP + 4 : Return Address EBP : Previous function's stack activation record EBP - 4 : array[4] EBP - 8 : array[3] EBP - 12: array[2] EBP - 16: array[1] EBP - 20: array[0] 

So in order to access the value at array[3], only one instruction is needed. That's very fast.

5 Comments

this is not theory, this is simply true. Problem is that optimizer often generates the better code anyway
when arrays are faster whats the need for pointers? My professor told me that pointers are faster since they directly point to the address but where a variable should be searched in the location for the address
That is not true at all. In machine code, it is generally not faster to access [stack frame pointer register + offset] than to access [fixed address + offset] (e.g. global array) or [pointer + offset] (heap), if the pointer is kept in a register. If the array is accessed via a pointer, it doesn't matter where it is.
Yes, you'll have to get it in the register first. That is something an optimizer takes care of, i.e. you usually only do that once. And [fixed address + offset] doesn't even need the EBP (or whatever) register. If you profile such code, you'll find there is no noticeable difference and nothing that should be prematurely optimized.
Of course there is not going to be a "noticeable" difference ... we're only talking a couple of instructions between the two. That being said, the addition of the extra instructions to get the value out of the pointer variable and into a register will make it "slower", even if it's imperceptible ... Also in unoptimized code, array access will be much faster, as the compiler will not cache the pointer value in a register. Finally, with or without optimizations, you cannot access an automatic variable allocated on the stack without either the EBP or the ESP register.
1

In the examples that you provided, p[1] will not be faster than a[1].

Comments

0

An array name is essentially the pointer to the first element of that array - so, they should be pretty much the same.

Statically created arrays have their own type which incorporates their compile-time defined size which makes them different than pointers technically, but for all intensive purposes the array name and the character pointer in your example can be used identically.

5 Comments

But i read pointer concepts makes c much faster is that wrong?
Arrays are convertible to pointers, but they are not pointers, and they are not always interchangeable with each other (e.g. &a and &p will emit completely different results).
C's ability to directly access memory addresses via pointers, and its inherent design as a low-level language make it faster than other languages which add more complexity to protect you from these things (C#, Java). But with regard to C itself, pointers and arrays shouldn't be treated differently unless you're dealing with some type issues when passing them as arguments. "Nobody" commented on your question and explain how using a subscript operator ([]) can be less efficient than using the de-reference operator (*) and that can be relevant to your confusion - its a good comment.
And make sure you read Eugene's comment above my last one - that makes a good point that I wasn't clear enough on - my bad :)
That may have been true in the days when different addressing modes did matter. These days, there is hardly any difference. It is not something to consider as premature optimization method.
0

Pointers being faster than arrays is coming from the following example.

Say you want to implement the strcpy function, i.e. copy one null-terminated string to another. Let's look at two examples:

First one:

char* strcpy(char* dest, const char* src) { int i = 0; while( src[i] != '\0' ) { dest[i] = src[i]; i++; } dest[i] = '\0'; return dest; } 

Second one:

char* strcpy(char* dest, const char* src) { char *save = dest; while( *src != '\0' ) { *dest++ = *src++; } *dest = '\0'; return save; } 

The second example is implemented more efficiently, cause it does less memory modifications in each iteration, and it uses pointers instead of arrays. But there are two things:

  1. It's not pointers which are fast, it's algorithm using them for optimization.
  2. Optimizer can easily perform this kind of optimization automatically, so you probably end up with the same generated code anyway.

2 Comments

-1: That might have been true in the days of the PDP-11, but not now
@Paul, yes, this is mentioned in the answer, this is oversimplified example and this is explained
0

Array is a pointer, there is no difference between p and a after

char a[10]="helloworld"; char *p=a; 

both a and p are a pointer to char and they are pointing to the same place - beginning of your array in memory.

using "operator []" is equivalent to pointer arithmetic too

a[i] 

will be substituted to

*(a+i) 

it means that pointer to the beginning of the array will be shifted by i*sizeof(char) to the place of i-th element of your array.

The real difference in time appears when you try loop over all elements, for example, copy the string:

char a[10] = "helloworld"; char b[10]; for (int i = 0; i < 10; ++i) b[i] = a[i]; // using array element accessing method 

will produce arithmetic like b+i (aka b shift by i*sizeof(char) ) and a+i (aka a shift by i*sizeof(char) ) for each iteration of loop, and

char a[10] = "helloworld"; char b[10]; char *_a, *_b; for (_a = a, _b = b; *_a != '\0'; ++_a, ++_b) *_a = *_b; // using pointers arithmetic method *b = '\0'; 

is free from this those calculations, you only shift two pointers by size of char each time.

2 Comments

Arrays are most definitely not pointers. Arrays decay or are implicitly converted into pointers when used on the right-hand side of the assignment operator and when passed as a function argument.
ops, you're right, array differs from pointer syntactically and you'll get different sizeof() result, but actually they act in the same way when accessing to element, and you may write char a[10] = "12345"; char* b; b = a; printf ("%c\n", b[2]);

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.