I recently read "UNIX system programming", and I feel that I can use the C language to get into the classroom.
In general, we will understand the relationship between pointers and arrays. For example, * p is a one-dimensional array, and ** p is a two-dimensional array. In general, it is also rare to see the two-dimensional pointer, but the higher-dimensional ones are afraid that they will be dizzy after a while. There is an example about the parameter list in UNIX system programming. I feel that pointer usage has reached a superb position. So I will post it for your reference.
Multi-level pointer to pointer
In the main function of the C language entry, there is a ** argv parameter that specifies the command line parameter, which is generally written as follows:
C code
- int main(int argc, char **argv){
- /*
- * code here.
- */
- }
-
- int main(int argc, char **argv){
- /*
- * code here.
- */
- }
This ** argv is a pointer to a pointer used to save the command line parameters. For example, enter a command:
Prog-c-v 200
** The contents in argv are prog,-c,-v, 200. because prog,-c, and so on have different lengths, a pointer is required to reference them, and several parameters behind prog are also not fixed. Therefore, a pointer is required to reference them, so it's the two-dimensional pointer here. It may seem clearer to draw a table:
In another case, the shell program does not know how many lines of commands you will lose, so it needs another pointer to reference how many command inputs you will have. This is what we want to watch today (*** ptr.
Multi-level pointer pointing to "Pointer"
The example in the book is as follows:
C code
- int makeargv(const char *s, const char *delimiters, char ***argvp);
- int makeargv(const char *s, const char *delimiters, char ***argvp);
The function accepts three parameters. The first is the string to be analyzed, the second is the delimiter sequence, and the third is the pointer to the generated "Pointer" (that is, a two-dimensional array. The implementation is relatively simple, mainly based on the usage of pointers:
C code
- /*
- * Author: juntao. qiu
- */
- Int makeargv (const char * s, const char * delimiters, char *** argvp ){
- Int error;
- Int I;
- Int numtokens;
- Const char * snew;
- Char * t;
- If ((S= NULL) | (Delimiters= NULL) | (Argvp= NULL )){
- Error=EINVAL;
- Return-1;
- }
- *Argvp=NULL;
- SSnew= S + strspns (s, delimiters );
- If ((T=Malloc(Strlen (snew) + 1) = NULL)
- Return-1;
- Strcpy (t, snew );
- Numtokens=0;
- If (strtok (t, delimiters )! = NULL)
- For (Numtokens=1; Strtok (NULL, delimiters )! = NULL; numtokens ++ );
- If ((*Argvp=Malloc(Numtokens + 1) * sizeof (char *) = NULL ){
- Error=Errno;
- Free (t );
- Errno=Error;
- Return-1;
- }
- If (Numtokens= 0 ){
- Free (t );
- } Else {
- Strcpy (t, snew );
- **Argvp=Strtok(T, delimiters); // note the pointer operation here.
- For (I=1; I< Numtokens; I ++)
- * (* Argvp) + I) = strtok (NULL, delimiters); // note the pointer operation here.
- }
- * (* Argvp) + numtokens) = NULL;
- Return numtokens;
- }
-
- /*
- * Author: juntao. qiu
- */
- Int makeargv (const char * s, const char * delimiters, char *** argvp ){
- Int error;
- Int I;
- Int numtokens;
- Const char * snew;
- Char * t;
-
- If ((S= NULL) | (Delimiters= NULL) | (Argvp= NULL )){
- Error=EINVAL;
- Return-1;
- }
-
- *Argvp=NULL;
- SSnew= S + strspns (s, delimiters );
- If ((T=Malloc(Strlen (snew) + 1) = NULL)
- Return-1;
-
- Strcpy (t, snew );
- Numtokens=0;
-
- If (strtok (t, delimiters )! = NULL)
- For (Numtokens=1; Strtok (NULL, delimiters )! = NULL; numtokens ++ );
-
- If ((*Argvp=Malloc(Numtokens + 1) * sizeof (char *) = NULL ){
- Error=Errno;
- Free (t );
- Errno=Error;
- Return-1;
- }
-
- If (Numtokens= 0 ){
- Free (t );
- } Else {
- Strcpy (t, snew );
- **Argvp=Strtok(T, delimiters); // note the pointer operation here.
- For (I=1; I< Numtokens; I ++)
- * (* Argvp) + I) = strtok (NULL, delimiters); // note the pointer operation here.
- }
- * (* Argvp) + numtokens) = NULL;
-
- Return numtokens;
- }
The main body of the program is relatively simple, that is, the program is divided according to the incoming s, according to the delimiter delimiters. After the split, the program is placed in a two-dimensional array, and the first dimension indicates the last array, the second dimension represents the value of each element in the first array.
Test
Okay, let's test its running status:
C code
- int main(int argc, char **argv){
- char delim[] = " \t";
- int i;
- char **argvp;
- int numtokens;
- char *test = "mine -c 10 2.0";
-
- if((numtokens = makeargv(test, delim, &argvp)) == -1){
- fprintf(stderr, "failed to parse the string you given:%s\n", test);
- return 1;
- }
- printf("argument contains :\n");
- for(i = 0;i < numtokens;i++)
- printf("%d:%s\n", i, argvp[i]);
- return 0;
- }
-
- int main(int argc, char **argv){
- char delim[] = " \t";
- int i;
- char **argvp;
- int numtokens;
- char *test = "mine -c 10 2.0";
-
- if((numtokens = makeargv(test, delim, &argvp)) == -1){
- fprintf(stderr, "failed to parse the string you given:%s\n", test);
- return 1;
- }
- printf("argument contains :\n");
- for(i = 0;i < numtokens;i++)
- printf("%d:%s\n", i, argvp[i]);
- return 0;
- }
The running result is as follows:
- C:\development\cpl\usp>ls
- Makefile a.exe makeargv.c nbproject
-
- C:\development\cpl\usp>a
- argument contains :
- 0:mine
- 1:-c
- 2:10
- 3:2.0
I personally feel that I can use the multi-level pointer to this level of proficiency to be able to master C. The code in "UNIX system programming" is very elegant. I have been a sophomore and I am still reading it after graduation. I will try my best to post my experiences for your reference.
- Comprehensive analysis of the concept of C pointer
- Tell the story of C and pointer
- Effective collection of C ++ reference counting smart pointers
- Relationship between arrays and pointer types in C ++
- Use C language to edit the drawing program