Learning notes of C programming language -- pointer and array

Keywords: C C++

Pointers and arrays

A pointer is a variable that holds the address of a variable.
Pointers are often the only way to express a computer,
Using pointers usually produces more efficient and compact code.

ANSI C uses the type void * (pointer to void) instead of char * as the type of general-purpose pointer.

Pointer and address

Generally, one byte of the machine can store a char type data, two adjacent byte storage units can store a short type data, and four adjacent byte storage units can store a long type data.
A pointer is a set of storage units (usually 2 or 4 bytes) that can store an address.

Pointers and function parameters

C language passes parameters to the called function by value transfer. Therefore, the called function cannot directly modify the value of variables in the calling function.

Pointer function enables the called function to access and modify the value of the object in the calling function.

Pointers and arrays

int a[10];
int *pa;

pa = &a[0];
// Equivalent to
pa = a;

a[i]
// Equivalent to
*(a+i)

&a[i]
// Equivalent to
a+i

The pointer is a variable, so the statements pa = a and pa + + are legal in C language.
But the array name is not a variable, so statements like a=pa and a + + are illegal.

In function definition, formal parameters
	char s[]
Equivalent to
	char*s

Address arithmetic operation

<stddef.h>Defined ptrdiff_t,Ensure a large enough signed number to store the difference between two pointers
 Pointer+/- Integer: it means that the pointer executes the current position forward/Moves the address after a specified number of objects of the same type backward
 Pointer 1 - Pointer 2: refers to the number of objects of the same type that differ between pointer 1 and pointer 2
 Pointer comparison is limited to the comparison between pointers in the same array
 The comparison or arithmetic operation between pointers to different array elements is not defined
 The pointer can be compared with 0, 0 can be assigned to the pointer, and other integer constants are not	that 's ok.
Commonly used in programs NULL Instead of 0, defined in<stddef.h>

Valid pointer operation:
Assignment between pointers of the same type[One of the two is void*,The other party	No pointing type requirements]
Addition or subtraction between pointer and integer
 Subtraction or comparison between two pointers to elements in the same array
 Assign pointer to 0 or compare pointer to 0

Character pointers and functions

char amessage[] = "now is the time"; /* an array */
char *pmessage = "now is the time"; /* a pointer */

amessage is a one-dimensional array only enough to store initialization characters and empty characters' \ 0 '.
A single character in the array can be modified, but the amessage always points to the same storage location.
On the other hand, pmessage is a pointer whose initial value points to a string constant, which can then be modified to point to other addresses, but if you try to modify the content of the string, the result is meaningless.

Pointer array and pointer to pointer

Because pointers themselves are variables, they can also be stored in arrays like other variables.

If the text lines to be sorted are stored end-to-end in a long character array, each text line can be accessed by a pointer to its first character.
These pointers themselves can be stored in an array. In this way, the pointer to two text lines can be passed to the function strcmp to compare the two text lines.
When two text lines with reversed order are exchanged, in fact, the pointers corresponding to the two text lines in the pointer array are exchanged, not the two text lines themselves.

3 steps of sorting process:

Read all input lines
 Sort text
 Print text lines in order

The input function must collect and save the characters in each line of text and build an array of pointers to these text.
Its colleagues must also count the beginning of the input line, because this information is used in sorting and printing.
Since the input function can only handle a limited number of input lines, when the number of input lines exceeds the maximum number of lines, the function returns a number used to represent the beginning of an illegal line, such as - 1

The output function only needs to print these text lines in order in the pointer array.

Multidimensional array

2D array:

static char daytab[2][13] = 
{
	{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
	{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

Two dimensional arrays are passed as parameters

f(int daytab[2][13]) { ... }
// equivalence
f(int daytab[][13]) { ... }
// equivalence
f(int (*daytab)[13]) { ... }

Generally speaking, except that the first dimension (subscript) of the number can not specify the size, all other dimensions must specify the size explicitly.

Initialization of pointer array

/* month_name Function: returns the name of the nth month */
char *month_name(int n)
{
	static char *name[] = 
	{
	"Illegal month",
	"January", 
	"February", 
	"March",
	"April", 
	"May", 
	"June",
	"July", 
	"August", 
	"September",
	"October", 
	"November", 
	"December"
	};
	return (n < 1 || n > 12) ? name[0]:name[n];
}
name The initialization of the array is realized through a string list, and each string in the list is assigned to the element at the corresponding position of the array.
The firstiAll characters of a string are stored in a location in memory
 The pointer to it is stored in name[i]
Unspecified array name When compiling, the compiler counts the number of initial values and fills the exact number into the array length

Pointers and multidimensional arrays

Declaration and graphical description of pointer array:

Declaration and graphical description of two-dimensional array:

Command line parameters

ANSI requirement argv[argc]The value needs to be NULL
 Commands that support parameter options. Option commands are generally allowed to appear in any order or combination
#include <stdio.h>
#include <string.h>
#define MAXLINE 1000
int getline(char *line, int max);
/* find: print lines that match pattern from 1st arg */
main(int argc, char *argv[])
{
	char line[MAXLINE];
	long lineno = 0;
	int c, except = 0, number = 0, found = 0;
	// Traversal parameters, processing options
	// When char* argv [] is used as an array parameter,
	// It needs to be converted to char** argv
	// argv is a variable that points to the first element of the array. Each element of the array is of type char *
	// ++Argv will change argv. Argv is the changed value in the next access

	// Requires that options be placed before matching content parameters
	while (--argc > 0 && (*++argv)[0] == '-')
	{
		// argv[i] returns a reference to the I element of the array index,
		// ++argv[i] will change the value of argv[i] element by reference. The next access to argv[i] will access the changed value
		while (c = *++argv[0])
		{
			switch (c) 
			{
				case 'x':
					except = 1;
					break;
				case 'n':
					number = 1;
					break;
				default:
					printf("find: illegal option %c\n", c);
					argc = 0;
					found = -1;
					break;
			}
		}
	}
		
	// argc indicates that the first parameter is processed, and the number of parameters remaining after the option parameter is processed
	if (argc != 1)
	{
		printf("Usage: find -x -n pattern\n");
	}
	else
		while (getline(line, MAXLINE) > 0) 
		{
			lineno++;
			// Expectations for argv
			// 1. argv is not the first parameter
			// 2. argv points to an option parameter that has not been processed
			// argv now points to the matching content parameter
			if ((strstr(line, *argv) != NULL) != except) 
			{
				if (number)
					printf("%ld:", lineno);
				printf("%s", line);
				found++;
			}
		}
		
		return found;
}

Pointer to function

The function itself is not a variable,
However, it is possible to define a pointer to a function, which is a variable.
#include <stdio.h>
#include <string.h>
#define MAXLINES 5000 /* max #lines to be sorted */
char *lineptr[MAXLINES]; /* pointers to text lines */
int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort(void *lineptr[], int left, int right,
int (*comp)(void *, void *));
int numcmp(char *, char *);
/* sort input lines */
main(int argc, char *argv[])
{
	int nlines; /* number of input lines read */
	int numeric = 0; /* 1 if numeric sort */
	if (argc > 1 && strcmp(argv[1], "-n") == 0)
		numeric = 1;
	if ((nlines = readlines(lineptr, MAXLINES)) >= 0) 
	{
		qsort(
			(void**) lineptr, 
			0, 
			nlines-1,
			// numcmp, strcmp function address
			// When assigning a pointer to a function name or array name, you do not need to prefix it&
			(int (*)(void*,void*))(numeric ? numcmp : strcmp));
		writelines(lineptr, nlines);
		return 0;
	} 
	else 
	{
		printf("input too big to sort\n");
		return 1;
	}
}

/* qsort Function: sort v[left]...v[right] in ascending order */
void qsort(
	void *v[], 
	int left, 
	int right,
	int (*comp)(void *, void *))
{
	int i, last;
	void swap(void *v[], int, int);
	if (left >= right) /* do nothing if array contains */
		return; /* fewer than two elements */
	swap(v, left, (left + right)/2);
	last = left;
	for (i = left+1; i <= right; i++)
	{
		if ((*comp)(v[i], v[left]) < 0)
		{
			swap(v, ++last, i);
		}
	}
	
	swap(v, left, last);
	qsort(v, left, last-1, comp);
	qsort(v, last+1, right, comp);
}


#include <stdlib.h>
// Note that this function prototype can match the type of function pointer pointed to by int (*)(void*,void *)
int numcmp(char *s1, char* s2)
{
	...
}
int (*comp)(void *, void *)
It shows comp Is a pointer to a function that has two void*Type, whose return value type is int. 

if ((*comp)(v[i], v[left]) < 0)
comp The use of is consistent with its declaration, comp Is a pointer to a function,
 *comp Represents a function. Call this function:
	(*comp)(v[i], v[left])
Parentheses are necessary to ensure the correct combination of all parts.

	int *comp(void *, void *)  /*  Wrong writing */
Then show comp Is a function that returns a pointer to int Pointer to type.

Complex declaration

A good way to create complex declarations is to use typedef to synthesize them in simple steps

char **argv
	argv: pointer to char
int (*daytab)[13]
	daytab: pointer to array[13] of int
int *daytab[13]
	daytab: array[13] of pointer to int
void *comp()
	comp: function returning pointer to void
void (*comp)()
	comp: pointer to function returning void
char (*(*x())[])()
	x: function returning pointer to array[] of
	pointer to function returning char
char (*(*x[3])())[5]
	x: array[3] of pointer to function returning
	pointer to array[5] of char

dcl: optional *'s direct-dcl
direct-dcl: name
	(dcl)
	direct-dcl()
	direct-dcl[optional size]


	// x is a function
	// The argument to the function is null
	// The return value of the function is a pointer to an array
	// Each element of the array is a function pointer, the return value of the function is char, and the parameter is null.
	char (*(*x())[])()
Declarator dcl Yes, there may be more than one in front*of direct-dcl
direct-dcl however name,Enclosed by a pair of parentheses dcl,Followed by a pair of parentheses direct-dcl,Followed by square brackets indicating the optional length direct-dcl.
(*pfa[])() 
pfa It's a name,It's a direct-dcl
pfa[]Also a direct-dcl
*pfa[]Identified as a dcl
 So,(*pfa[])It's a direct-dcl
(*pfa[])()Identified as a direct-dcl,Also a dcl

Learning References:

<C Programming language, 2nd Edition, new edition

https://blog.csdn.net/x13262608581/article/details/108592819

Posted by kcorless on Sun, 24 Oct 2021 23:20:56 -0700