0

How come that a pointer can freely be used as an array? I thought pointers are more powerful and important in memory manipulation? Can somebody explain to me in which scenario do pointers become more important?

Here is my code:

char * myString ="This is my String";
while(*myString){
  putchar(*myString++);
}
puts("\n");

char * myString1 ="This is my String";
int j=0;
while(myString1[j]!='\0'){
  putchar(myString1[j++]);
}

They print the same results.

mrflash818
  • 930
  • 13
  • 24
Muthoka
  • 35
  • 4
  • 4
    More correctly: array names act as pointers in nearly all expressions in C (this is commonly known as 'arrays decay to pointers'), and the indexing operator is defined in terms of pointer arithmetic. – Michael Burr Jul 19 '15 at 04:15
  • 2
    Neither `myString` or `myString1` is actually an array, they're both pointers. However, the expression `myString1[j]` expands to `*(myString1 + j)`, which is getting the character `j` bytes off from the start of `myString1`. So you can effectively use the array syntax on a pointer and achieve the same result. – ra1nmaster Jul 19 '15 at 04:17
  • 2
    "More important" to whom? According to which criteria of importance? Yours is not an answerable question. – n. m. could be an AI Jul 19 '15 at 04:39
  • How can this possibly be primarily opinion-based? There are such things as the C and C++ standards... StackOverflow is turning to garbage with these nonsensical close votes lately! – autistic Jul 19 '15 at 04:46
  • @MichaelBurr I prefer to use the word "convert", because that's the actual terminology, and *decay* seems to imply some kind of negativity... For example, perhaps to some people an array *decays* when its lifetime ends, and from that point forth it's no longer valid to access the array. – autistic Jul 19 '15 at 04:49
  • 1
    Read section 6 of the [comp.lang.c FAQ](http://www.c-faq.com/). – Keith Thompson Jul 19 '15 at 04:57
  • 2
    @undefinedbehaviour There is some kind of negativity involved because information is lost (the size). – Peter - Reinstate Monica Jul 19 '15 at 05:01
  • 1
    @undefinedbehaviour Where exactly the standards speak about relative importance of arrays and pointers? If you have the quotes please include them in your answer. – n. m. could be an AI Jul 19 '15 at 05:02
  • @PeterSchneider `char foo[32]; strcpy(foo, "bar"); /*` so the size information of `foo` is lost here? Are you sure about that? If we put this afterwards: `*/ printf("sizeof foo: %zu\n", sizeof foo); //` what do you think will be printed? – autistic Jul 19 '15 at 05:05
  • @undefinedbehaviour whether pointers or arrays are more important or more useful, is opinion based – M.M Jul 19 '15 at 05:07
  • 1
    @undefinedbehaviour It is lost in the expression `strcpy(foo, "bar")` , indeed. That the size of the destination is lost when you do string or mem copies is the source of a significant portion of real world software failures, and the reason why `strcpy`'s reputation has suffered in the last few decades. – Peter - Reinstate Monica Jul 19 '15 at 05:09
  • @PeterSchneider Sure. It's lost temporarily, as in a conversion. Not permanently, as in a decay, however... – autistic Jul 19 '15 at 05:14
  • Without pointers to functions, you're going to have a pretty unpleasant time trying to implement callbacks of any significance. Another place they're in common use is for sorting. The basic algorithm remains the same regardless of the data. What does change however, is how you decide if one element should come before another element. If the elements are ints/floats/chars it's easy. You just compare one element to another. If however, they contain structs - you need to know how to compare them. In this case, the sort function is given a pointer to the function that will compare elements. – enhzflep Jul 19 '15 at 06:38
  • One perhaps enlightening consideration is, that arrays in C are quite different from arrays in almost any other language, except assembly... Even in C++ context they're commonly called "C arrays" to distingquish them from `std::array` and `std::vector`, and using C arrays instead of these safer alternatives is generally considered bad in *modern* C++. This is something to keep in mind when switching between C and other programming languages: array means different things. – hyde Jul 19 '15 at 07:31

3 Answers3

6

How come that a pointer can freely be used as an array?

Unless it's the operand of a sizeof or unary & (address-of) operator, an array expression is converted to a pointer expression...

I thought pointers are more powerful and important in memory manipulation? Can somebody explain to me in which scenario do pointers become more important?

Arrays have different use cases than pointers; they're related, but can't be substituted for each other. Neither is more important than the other.

For example, as Mohamed Fouad mentioned in his answer, an array is a contiguous group of elements. We can't store a group of elements with a pointer, unless the pointer points into an array.

As another example where either can be used but pointers are generally more appropriate, consider how fscanf works. When you want to read a sequence of decimal digit characters as an int, you can write something like int destination; fscanf(source_file, "%d\n", &destination);. The & (address-of) operation produces a pointer to destination, and the pointer allows fscanf to write to destination in a way that's visible once fscanf returns.

You could also write this as int destination[1]; fscanf(source_file, "%d\n", destination);, but then later on you'll be referring to destination[0], probably numerous times, rather than destination... You should keep unnecessary clutter in code to a minimum, and thus the former approach (int destination; ...) has become an idiomatic use for scanf (rather than the array-based version) because it's cleaner.

There are more examples where pointers don't even point at objects, and so can't be stored in arrays to begin with. For example, let us consider bsearch. bsearch returns a void *, and uses void * in its arguments, along-side a function pointer. Neither of these are considered to be pointing at a specific type of object, and indeed the former could be made to point at any type object or no object at all. Hence, when bsearch fails to locate an item in your array, it returns NULL (a pointer to nothing), which is a usecase which arrays could not sanely replace.

Functions aren't objects or values, can't be stored within arrays and so arrays have no such related analogy to function pointers.

They print the same results.

Perhaps you meant to write char myString1[] = "This is my String";. That's how we declare arrays. What you wrote, char * myString1 ... denotes a pointer declaration.

The expression myString1 in myString1[j] and myString1[j++] is converted from an array expression to a pointer expression. Does that make sense?

The array[subscript] operator is actually a pointer[subscript] operator. It is the equivalent to *(array + subscript), but recall that the array expression becomes a pointer expression, so it might make more sense to write *(pointer + subscript).

To augment the function pointer mention above, the function(call) operator is actually a pointer(call) operation, which bares striking resemblance to the pointer[subscribt] operation in the way the implicit conversions occur. It's observable nonetheless:

typedef int main_func(void); // declare a new type named main_func to point at
int main(void) {
    int x[1];
    int *y = x;          // notice lack of ampersand, array-to-pointer conversion happens implicitly
    main_func *m = main; // notice lack of ampersand, function-to-pointer conversion happens implicitly
    return (*m)();       // main calls itself via pointer m (don't do this)
}

You might notice the equivalence, now: In your first example, you increment your pointer variable repeatedly, whilst in your second example you increment the subscript repeatedly. Aside from that, the operations are virtually identical.

If you're compiling with any modern-day optimising compiler (use -O3), there shouldn't be any difference between the binaries. Try to avoid premature optimisation; it's often non-constructive. Write clear code, then use your profiler to determine where the most significant bottlenecks are.

autistic
  • 1
  • 3
  • 35
  • 80
1

let's understand what happen when you call a function in c++ and pass a parameter to it it's copy the hole object (or array) to new place in memory and then start to execute the function 1- if the size of this object is huge this will be a big problem (time and memory waste) or 2- if we want to this function to edit the original object not it's copy the pointer is the solution or 3- if we have a system which should be response very fast (like a camera system in modern cars) if we write a code like

object x = new object;

without overload new operator this will be very slow overload new operator will enhance this process because will put our new object in not needed place

array is a contiguous space in memory if we have the starting adddres we can plus the size of object to reach the next object of subtract this what you wrote in your code

pointers are more powerful and important in memory manipulation this is the completely true statement here You will find more answers

Sorry for bad English :D

Community
  • 1
  • 1
Mohamed Fouad
  • 111
  • 1
  • 2
  • 10
1

A pointer in C is simply a location in memory. It points to a single location in memory. Anything can be stored there: an int, a char, a string (char array), or even a more complex object such as a struct.

Pointers are more 'powerful' than an array simply because they can 'point' to anything. This is because they simply point to the memory address where literally anything can be stored.

A pointer's memory address is the beginning of whatever is stored there. So the length of the item is based on how many bytes the item requires. So for an int, the memory address could be 0x0044, and the int would take up sizeof(int) number of bytes. The same would happen if you had a struct stored at that memory address, and it would take up sizeof(nameOfStruct) number of bytes.

Basically, when you are using a pointer to initialize a character array, or a string, you are allocating enough bytes at a memory address to store the length of your string.

What this means is you declare a pointer to a character. myString and myString1 are both pointers to a char. Then, when you assign a string of text to your pointers, you are asking the program to find enough memory to store that string. The program will store "This is my String" in memory contiguously, and will assign the memory address to the first character to our pointer myString. So now myString 'points' to the beginning of our string in memory.

What you end up doing when you are running the following code

char * myString1 ="This is my String";
int j=0;
while(myString1[j]!='\0'){
  putchar(myString1[j++]);
}

is you are going through the string looking for the null terminator, or the end of the string. Basically, every time j advances by one, your moving one character forward in memory, and printing out what is there, until you reach the null terminator, or the end of the string. Of course with c, if you went past the end of the string, the program wouldn't care, and would just continue to output whatever garbage is next along the line in memory. This is because when you are advancing j, you are just advancing to the next memory address and printing out whatever is there.

element11
  • 4,218
  • 2
  • 16
  • 22