Exploration of C pointer statements

Source: Internet
Author: User

Preface
My understanding of the C pointer has been stuck at: the pointer itself is a piece of memory, it stores a piece of memory address, can be referenced, but recently when I was reading the code, the various pointer statements made me very worried. I quickly learned about them and just understood the most basic usage. The summary is as follows.

Basic knowledge
The basic usage of pointers is as described in the preface. Let's look at the following code:
[Cpp]
# Include <stdio. h>
 
Int main ()
{
Int I = 10;
Int * p;
Printf ("p address: % d \ n", & p );
Printf ("content of p when not initialized: % d \ n", p );
// Printf ("memory directed by uninitialized access p: % d \ n", * p); // when this line of code accesses a wild pointer, a segment error is inevitable.
P = & I;
Printf ("-- initialization p completed -- \ n ");
Printf ("the address saved in p: % d \ n", p );
Printf ("p points to the memory content: % d \ n", * p );
Printf ("p size: % d \ n", sizeof (p ));
Printf ("memory size pointed to by p: % d \ n", sizeof (* p ));
Return 0;
}

# Include <stdio. h>

Int main ()
{
Int I = 10;
Int * p;
Printf ("p address: % d \ n", & p );
Printf ("content of p when not initialized: % d \ n", p );
// Printf ("memory directed by uninitialized access p: % d \ n", * p); // when this line of code accesses a wild pointer, a segment error is inevitable.
P = & I;
Printf ("-- initialization p completed -- \ n ");
Printf ("the address saved in p: % d \ n", p );
Printf ("p points to the memory content: % d \ n", * p );
Printf ("p size: % d \ n", sizeof (p ));
Printf ("memory size pointed to by p: % d \ n", sizeof (* p ));
Return 0;
}

The output result is: [plain] view plaincopyprint? P address: 1439276008
Content of p when not initialized: 0
-- P Initialization is complete --
Address saved in p: 1439276020
Memory content pointed to by p: 10
P size: 8
Memory size pointed to by p: 4

P address: 1439276008
Content of p when not initialized: 0
-- P Initialization is complete --
Address saved in p: 1439276020
Memory content pointed to by p: 10
P size: 8
Memory size pointed to by p: 4

This is the basic usage of pointers, which can be described as follows:

 


Pointer and array
First, let's look at the two statements:
[Cpp]
Char (* a) [100];
Char * a [100];

Char (* a) [100];
Char * a [100];
The first is to declare a pointer to an array with 100 char elements (note that it is separate from the char pointer pointing to the first address of the array ); the second is to declare an array with 100 char * elements. The array contains char *.
For understanding, let's look at the following code:
[Cpp]
# Include <stdio. h>
 
Int main ()
{
Int arr [10] [100];
Printf ("sizeof (arr [0]) = % lu \ n", sizeof (arr [0]);
Printf ("sizeof (arr [0] [0]) = % lu \ n", sizeof (arr [0] [0]);
Int * p;
Int (* q) [100];
P = & arr [0] [0];
Q = & arr [0];
Printf ("p = % d \ n", p );
Printf ("q = % d \ n", q );
Printf ("sizeof (* p) = % lu \ n", sizeof (* p )));
Printf ("sizeof (* q) = % lu \ n", sizeof (* q )));
P ++;
Q ++;
Printf ("after add 1, p = % d \ n", p );
Printf ("after add 1, q = % d \ n", q );
Return 0;
}

# Include <stdio. h>

Int main ()
{
Int arr [10] [100];
Printf ("sizeof (arr [0]) = % lu \ n", sizeof (arr [0]);
Printf ("sizeof (arr [0] [0]) = % lu \ n", sizeof (arr [0] [0]);
Int * p;
Int (* q) [100];
P = & arr [0] [0];
Q = & arr [0];
Printf ("p = % d \ n", p );
Printf ("q = % d \ n", q );
Printf ("sizeof (* p) = % lu \ n", sizeof (* p )));
Printf ("sizeof (* q) = % lu \ n", sizeof (* q )));
P ++;
Q ++;
Printf ("after add 1, p = % d \ n", p );
Printf ("after add 1, q = % d \ n", q );
Return 0;
}
After the code is run, the result is as follows:
[Plain]

Sizeof (arr [0]) = 400
Sizeof (arr [0] [0]) = 4
P = 1411443800
Q = 1411443800
Sizeof (* p) = 4
Sizeof (* q) = 400
After add 1, p = 1411443804
After add 1, q = 1411444200

Sizeof (arr [0]) = 400
Sizeof (arr [0] [0]) = 4
P = 1411443800
Q = 1411443800
Sizeof (* p) = 4
Sizeof (* q) = 400
After add 1, p = 1411443804
After add 1, q = 1411444200
Because the memory is linear, the so-called two-dimensional array in C is just an array. The arr array has 10 elements, each of which is an array with a length of 100, in the programmer's mind, arr is a two-dimensional array with 10 rows and 100 columns.
In the code, p is a pointer to the int type, and q is a pointer to the "int array with 100 int. So the initialization methods of p and q are different, but at the beginning they all point to the first address of the array of arr (which is equal at the beginning ), however, after the auto-increment operation is executed separately, because of their different types, the step size varies according to the meaning of the auto-increment operation of the pointer, and p moves sizeof (int) and q moves the sizeof (int [100]) byte, so their values are also different, which can be used to describe:


In addition, you should note the declaration of the Two-dimensional character array:
[Cpp]
Include <stdio. h>
 
Int main ()
{
Char * str [2] = {"liushuai", "kobe "};
Printf ("% s \ n", str [0], str [1]);
Return 0;
}

# Include <stdio. h>

Int main ()
{
Char * str [2] = {"liushuai", "kobe "};
Printf ("% s \ n", str [0], str [1]);
Return 0;
}
The output result is clear:
[Plain]
Liushuai kobe

Liushuai kobe

The preceding statement is a valid two-dimensional array of characters. str is an array with two elements. The type of each element is a char.
Returns the pointer function and function pointer.
Let's look at the following two statements:
[Cpp]
Int * foo (int I );

Int * foo (int I );
This should be easy to understand. It is similar to the declaration of char * a [100] in an array with pointers. This is a function declaration and a function named foo is declared, this function accepts a parameter of the int type and returns a pointer to the int type.
Let's look at the following statement:
[Cpp]

Void (* bar )();

Void (* bar )();
Similar to the declaration of arrays, this statement declares a pointer bar pointing to a function, which requires the return value to void and does not accept any parameters. This is a simple function pointer declaration.
Since a function can return a pointer, can a function return a pointer to the function? The answer is yes. You can see how flexible the pointer is. The contact may be a bit uncomfortable. Let's look at an example:
[Cpp]
Int (* foo (int) (double *, char );

Int (* foo (int) (double *, char );
Like the above explanation, we know that this statement declares a function foo, which accepts an int type parameter and returns a pointer to the function, the function to be pointed to has the following format: accept a double type pointer and a char type variable as the parameter, and return a value of the int type.
We can use typedef in C to simplify this statement:
[Cpp]
Typedef int (* ptf) (double *, char );
Ptf foo (int );

Typedef int (* ptf) (double *, char );
Ptf foo (int );

Note: typedef and # define are different. typedef creates an alias ptf for the "such" pointer, rather than simply replacing the macro.
Well, let's proceed with a more abnormal one. If the parameters and return values of a function are both function pointers, the declaration will be more complicated, for example:
[Cpp] view plaincopyprint? Void (* signal (int sig, void (* func) (int siga );

Void (* signal (int sig, void (* func) (int siga );
In fact, it is not difficult to analyze slowly. We can use typedef to simplify the process:
[Cpp]
Typedef void (* p_sig) (int );
P_sig signal (int sig, p_sig func );

Typedef void (* p_sig) (int );
P_sig signal (int sig, p_sig func );
The func parameter of the signal function is a function pointer that returns a function pointer, and the two pointers must point to the function in the same form (accept an int-type parameter, returns a null value ).
Call a function using a function pointer
An example is provided to illustrate the problem:
[Cpp]
# Include <stdio. h>
 
Void printMyName ();
 
Int main ()
{
Void (* f )();
F = printMyName;
F ();
F = & printMyName;
F ();
Return 0;
}
 
Void printMyName ()
{
Printf ("liushuaikobe \ n ");
}

# Include <stdio. h>

Void printMyName ();

Int main ()
{
Void (* f )();
F = printMyName;
F ();
F = & printMyName;
F ();
Return 0;
}

Void printMyName ()
{
Printf ("liushuaikobe \ n ");
}
Is it easy. Note that it is legal to use "& function name" and "function name" to initialize a function pointer, because the numbers in C will be converted to pointers to this function.
Pointers are a product of wisdom. Through function pointers, you can easily implement some advanced features such as polymorphism in object-oriented languages (such as Java interfaces and C ++ virtual functions ), it's really amazing.
For the great gods, these things may all be Pediatrics, but I have never used C very much. I am also very happy to understand these things.
Finally, I will give you a sentence:
Don't forget why you set out too far.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.