Declaring type of pointers?
Type-safety. If you don't know what p
is supposed to point to, then there'd be nothing to prevent category errors like
*p = "Nonsense";
int i = *p;
Static type checking is a very powerful tool for preventing all kinds of errors like that.
C and C++ also support pointer arithmetic, which only works if the size of the target type is known.
address occupies same amount of memory whatever my be the type
That's true for today's popular platforms. But there have been platforms for which that wasn't the case. For example, a pointer to a multi-byte word could be smaller than a pointer to a single byte, since it doesn't need to represent the byte's offset within the word.
Why is the data type needed in pointer declarations?
The data type is needed when dereferencing the pointer so it knows how much data it should read. For example dereferencing a char
pointer should read the next byte from the address it is pointing to while an int
pointer should read 2 bytes.
Why to specify a pointer type?
Type of a pointer is needed in following situations
- Dereferencing the pointer
- Pointer arithmetic
Here is the example of dereferencing the pointer.
{
char *ptr; //pointer of type char
short j=256;
ptr=&j; // Obviously You have to ignore the warnings
printf("%d",*ptr)
}
Now because ptr
is of type char so it will only read one byte. But the binary value of 256 is 0000000100000000
but because ptr
is of type char
so it will read only first byte hence the output will be 0
.
Note: if we assign j=127 then output will be 127 because 127 will be hold by first byte.
Now, the example of pointer arithmetic
:
{
int *ptr;
int var=0;
ptr=&var;
var++;
ptr++;// pointer arithmetic
}
Are statements var++
and ptr++
are same thing? No, var++
means var=var+1
and ptr++
means ptr=ptr+4
. Because the compiler "knows" this is a pointer and that it points to an int
, it adds 4
to ptr
instead of 1, so the pointer "points to" the next integer.
Beginners question - Why does C use * to declare a pointer and not &?
Using *
to declare pointers is mostly a matter of convention, but there is a reason of consistency: the *
in the declaration int *p
means int
is the type of *p
.
It might seem more consistent to write int &p = &n
as p
is initialized to the address of n
but this convention would not hold for double pointers: int **pp
defines pp
as a pointer to a pointer to an int
, yet pp
cannot be initialized with &(&n)
.
Note that int& p = n;
is a valid definition in C++ for a reference to an int
, which is a pointer in disguise. Modifying p
would then modify n
. References are implemented as pointers without the indirection notation.
Pointer declaration in C, whats the difference?
Grammatically, the type uint8_t
is a declaration-specifier; whereas the pointer *
is a declarator. According to C's grammar declarators bind to the declared name rather than the declaration-specifier. Consequently your first line is parsed like:
uint8_t (*start_ptr), end_ptr;
i.e. only the first name becomes a pointer.
This is one reason some tend to put the space before the pointer *
rather than after. The correct way to declare those in one line would be:
uint8_t *start_ptr, *end_ptr; // both are pointers to uint8_t.
Is it possible to create pointers in C without a specific datatype
There is a generic pointer type in C for exactly this reason: void *
.
You can convert any data pointer type implicitly to and from void *
:
char foo[] = "bar";
void *ptr = foo;
// ...
char *str = ptr;
But be aware that you still have to know the correct type. Accessing an object through a pointer of the wrong type would be undefined behavior.
There are two things you can't do with void *
:
You can't do pointer arithmetics on it (this includes indexing).
void
is an incomplete type, so it doesn't have a known size. Some compilers allow arithmetics onvoid *
by assuming the size of achar
, but this is an extension and not portable.You can't dereference a
void *
.void
is "nothing", so it wouldn't be meaningful.
Declaring a pointer to a structure
The difference is that this statement creates two variables:
struct point var, *varptr;
It has the same effect as using 2 statements:
struct point var; // type struct point
struct point *varptr; // type pointer to struct point
And this statement creates 1 variable:
struct point *var; // type pointer to struct point
Can we just use the second one without assigning any variable's address to it?
Yes you can use the second one but you would want to initialize it to something (usually another variable's address) before derefrencing the pointer.
Declaring pointers; asterisk on the left or right of the space between the type and name?
It's a matter of preference, and somewhat of a holy war, just like brace style.
The "C++" style
someType* somePtr;
is emphasizing the type of the pointer variable. It is saying, essentially, "the type of somePtr
is pointer-to-someType
".
The "C" style
someType *somePtr;
is emphasizing the type of the pointed-to data. It is saying, essentially, "the type of data pointed to by somePtr
is someType
".
They both mean the same thing, but it depends on if a given programmer's mental model when creating a pointer is "focused", so to speak, on the pointed-to data or the pointer variable.
Putting it in the middle (as someType * somePtr
) is trying to avoid committing to either one.
Correct way of declaring pointer variables in C/C++
Bjarne Stroustrup said:
The choice between "int* p;" and "int *p;" is not about right and wrong, but about style and emphasis. C emphasized expressions; declarations were often considered little more than a necessary evil. C++, on the other hand, has a heavy emphasis on types.
A "typical C programmer" writes "int *p;" and explains it "*p is what is the int" emphasizing syntax, and may point to the C (and C++) declaration grammar to argue for the correctness of the style. Indeed, the * binds to the name p in the grammar.
A "typical C++ programmer" writes "int* p;" and explains it "p is a pointer to an int" emphasizing type. Indeed the type of p is int*. I clearly prefer that emphasis and see it as important for using the more advanced parts of C++ well.
Source: http://www.stroustrup.com/bs_faq2.html#whitespace
I'd recommend the latter style because in the situation where you are declaring multiple pointers in a single line (your 4th example), having the asterisk with the variable will be what you're used to.
Related Topics
Replace Multiple Spaces with One Space in a String
How to Create a C++ Boost Undirected Graph and Traverse It in Depth First Search (Dfs) Order
Erase/Remove Contents from the Map (Or Any Other Stl Container) While Iterating It
Lnk2019: Unresolved External Symbol _Main Referenced in Function _Tmaincrtstartup
What Could C/C++ "Lose" If They Defined a Standard Abi
C++ Template Metaprogramming - How to Output the Generated Code
When Should Functions Be Member Functions
Make a File Pointer Read/Write to an In-Memory Location
Multi-Dimensional Array Initialization
How to Use a Custom Type as Key for a Map in C++
Explicit Return Type of Lambda
Visual Studio 2010 & 2008 Can't Handle Source Files with Identical Names in Different Folders
Is There a Compact Equivalent to Python Range() in C++/Stl
Why Was Std::Pow(Double, Int) Removed from C++11
C++ Ifstream Error Using String as Opening File Path
Utilizing C++ in iOS and MAC Os X Applications
Performance Wise, How Fast Are Bitwise Operators VS. Normal Modulus