开发者

Why do we have pointers other than void

I know that we have different pointers like int, float, an开发者_StackOverflow中文版d char. A void pointer is the only pointer which can hold all others.

Do the other pointers exist only for the flexibility to do pointer arithmetic?

Is there any other reason that pointers other than void are present in C language?


Type safety. Defining the type of pointers helps the compiler find errors where you are trying to use data of the wrong type through a pointer. That's the reason C has types in the first place.


The compiler needs to know the types pointed at otherwise all sorts of code won't work. Consider the following:

*a = *b + *c;    // Should this add char? int? float?
s_ptr->x = 0;    // How does the compiler know anything about the structure s_ptr points to?
a[5] = 0;        // How far is a[5] from a[0]?

Not having types for pointers would be like not having types for anything. The compiler would be completely lost. In short, C and C++ are both strongly typed and this carries over to pointers for fairly obvious reasons.


int o = 12;
void *i = &o;

How would you access the int that i points to if there were only void pointers and no int*. You might know that on your platform an int is 4 bytes so you could memcpy 4 bytes from the start of whatever the void* points to into a temporary int and then use that. But that's not very convenient.

Or given a

struct Pair {
   char *first;
   char *second;
};

how useful would a void pointer to struct Pair be ? You'd likely want to access its first member and that's a lot of work if you couldn't have a pointer to a struct Pair.


Actually, it is the "pointer to void" which is to be explained.

In programming languages in general and in C in particular, we like types. Types are the basic safety net which checks whether we are doing something stupid, where "stupid" means "interpreting a bunch of bits for something they are not". It is possible to program without types, some languages are fully devoid of any kind of type (e.g. assembly or Forth), but this is not for the faint of heart and, generally speaking, programmer productivity seems to be greatly enhanced by use of types.

Therefore, when we have a pointer we want the computer to know what it may found at the end of the pointer. We want a "pointer to int" so that the computer checks that when we look at the bits which are at the end of the pointer, we look at them as an "int" and not as something else.

The "pointer to void" is the type-less pointer, which we use when the type system of C fails to capture what we are doing. It is a symptom of C not being able to follow the complexity of the code we are producing (or maybe the programmer was not good enough to express what he does within the constraints of the C type system). Hence, while "void *" is convenient in some situations, one should see it as the exception, and strive to avoid it.


The type of a pointer in C tells the compiler what is the size of the memory block to be read in case you attempt to dereference it. In other words, when dereferencing an int pointer the compiler knows that 4 bytes have to be read after the address. That is why dereferencing a void pointer without casting it to a typed pointer is forbidden - in this case the compiler doesn't know how many bytes to read after the address.


Dead simple:

void* p;
*p; // compile error!

Or to put it in words; a void pointer can not be dereferenced.

Perhaps you should rename the question why do we have pointers, or rather don't and just search for that question on SO.


When You use pointer to float or int (for example) compiler knows how many bytes it should take from memory (sizeof(int) for int* for example).

With void You would have to tell each time to compiler how many bytes it have to take (by writing (int*)some_void_ptr for example.

But this is great simplification.


Is there any other reason that pointers other than void are present in C language?

They are an awesome way to handle memory chunks freely. : )


When you iterate through the memory block pointed to by a pointer, it's necessary to know the size of the data type the memory contains. Say you have two pointers, a charcharptr and an intintptr, both pointing at memory at byte X. charptr+1 will point to the byte X+1, while intptr+1 will point to byte X+4.

A quick and dirty piece of badly written code to illustrate that:

#include <stdio.h>

int main()
{
    char * cptr = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    short * sptr = (short*)cptr;
    int * iptr = (int*)cptr;
    long long * lptr = (long long*)cptr;

    printf ("CHAR: %d, +1: %d\n",cptr,cptr+1);
    printf ("SHORT: %d, +1: %d\n",sptr,sptr+1);
    printf ("INT: %d, +1: %d\n",iptr,iptr+1);
    printf ("LONG LONG: %d, +1: %d\n",lptr,lptr+1);
}

This should:

  • generate warnings about casting pointers of different sizes (type safety),
  • output identical numbers in the first column (all pointers point to the same address in memory), but different numbers in the 2nd column (which is base address + size of the pointer's type: 1, 2, 4 and 8 bytes).


Two Words: Type Safety

There's a little tidbit on type safety (or lack thereof) in C on Wikipedia that might shed some light for you.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜