当前位置:网站首页>C language array and pointer

C language array and pointer

2022-06-12 13:24:00 shlyyy

One 、 One dimensional array

The array name is number 0 Pointer constants for elements .

The result of the subscript operation gets a reference to its element .

Subscript operation requires an operand of integer type , The other operand is the address .

int main(int argc, char* argv[])
{
    

    int ary[5] = {
     1, 2 };

    // &2[ary] = &ary[2];
    printf("%p\r\n", &ary[2]); // 0019FED0
    printf("%p\r\n", &2[ary]); // 0019FED0

    system("pause");
    return 0;
}

Addressing mode of one-dimensional array :
type ary[M] = …; ary[n] address is:
(int)ary + sizeof(type) * n

int main(int argc, char* argv[])
{
    
    int ary[2] = {
     0 };

    // 0x400000 Situated MZ identification 
    printf("%p\r\n", (void*)ary[(0x400000 - (int)ary) / sizeof(int)]); // 00905A4D

    printf("%s\r\n", (char*)&ary[(0x400000 - (int)ary) / sizeof(int)]); // MZ?

    system("pause");
    return 0;
}

Two 、 Two dimensional array

Two dimensional arrays are special one-dimensional arrays , Array elements are arrays of one-dimensional arrays

int ary[2][3] = {
    
    {
    1,2,3},   // ary[0]
    {
    4,5,6}    // ary[1]
};

// ary There are two elements , Each element is int[3] type 
int[3] ary[2] = {
    
    {
    1,2,3},
    {
    4,5,6}
};

//  Two subscript operations , The first subscript operation yields ary[1], For a one-dimensional array 3 Elements 
//  The second subscript operation starts from ary[1] Take the th... From the one-dimensional array of 2 Elements get data 
ary[1][2];

Two dimensional array addressing mode

type ary[N][M] = ...;
int x,y = ...;

ary[x][y] address is:
(int)ary + sizeof(type[M])*x + sizeof(type)*y
==> (int)ary + sizeof(type)*M*x + sizeof(type)*y
==> (int)ary + sizeof(type)*(M*x + y)
ary[0][M*x + y] <==> ary[x][y]

3、 ... and 、 The pointer

The pointer = Address + Mode of interpretation

Pointer arithmetic

1. Pointer plus integer gets pointer constant of the same type

2. Subscript the pointer , Get variable references to pointer types

3. Pointers of the same type can be subtracted , The result is an integer constant

type *p = ...;
int n = ...;

// 1. Pointer plus integer gets pointer constant of the same type 
p + n = (int)p + n*sizeof(type);

// 2. Subscript the pointer , Get variable references to pointer types 
p[n] = *(type*)((int)p + n*sizeof(type));
type *p1 = ...;
type *p2 = ...;

// 3. Pointers of the same type can be subtracted , The result is an integer constant 
p1 - p2 = ((int)p1 - (int)p2) / sizeof(type);

*p++ And *++p

* With the priority of ++ Same priority for , The priority is 2, And they are all combined from right to left .

*p++: First, execute p++, But post ++ After the whole statement is executed p Again ++. And then execute *p Value . Last p+=1. Equate to *p;p+=1;

void mystrcpy(char* szDst, char* szSrc)
{
    
    while(*szDst++ = *szSrc++);
}

*++p: From right to left ,++p Execute first , After execution p Updated to p+1, And then take the value . Equate to :p+=1;*p;

Four 、 Pointer array and two-dimensional pointer

Pointer array :
advantage : It integrates the advantages of variable length storage and fixed length storage . It has the advantage of variable length storage and variable data size , It also has the advantage of random access of fixed length storage . When sorting, you only need to exchange the pointers in the array , There is no copy of the element . The problem of finding and sorting variable length storage has been solved .
shortcoming : When the data volume is large , Insertion and deletion are expensive .

int main(int argc, char* argv[], char* envp[])
{
    
    //  Command line to argc Parameters as end flags 
	for (int i = 0; i < argc; i++)
	{
    
		puts(argv[i]);
	}

    //  Environment variables are represented by NULL As a closing sign 
	while (*envp != NULL)
	{
    
		puts(*envp);
		envp++;
	}
	system("pause");
	return 0;
}

there argv As an array name , The array name is number 0 Elements (char * type ) Pointer constants for , That is to say char** type . So receive argv You need to define a two-dimensional pointer .

int main(int argc, char* argv[])
{
    
    char** p = argv;
    
	system("pause");
	return 0;
}

A two-dimensional pointer as a pointer , It can also be used as a formal parameter , Make indirect access to the two-dimensional pointer in the function , To modify the arguments ( One dimensional pointer & operation ), So as to achieve the purpose of modifying one-dimensional pointer .

int g_nTest = 0x123;
//  Pass out the pointer through the parameter , To pass in a second level pointer 

//  Pass on pn The address of is kept in ppn Parameter variables 
void SetPoint(int** ppn)
{
    
    //  Indirect access occurs   take pn The content of the address is modified 
    *ppn = &g_nTest;
}

int main(int argc, char* argv[])
{
    
    int n = 0x888;
    int* pn = &n;
    
    //  modify pn The direction of   Set up pn Save the address of the global variable 
    SetPoint(&pn);
    
    system("pause");
	return 0;
}

5、 ... and 、 Array pointer

Consider a situation , For a one-dimensional array , If you define a pointer to receive an array name , That's all right. , Because of the same type, you can put ary Directly assign to p.

int ary[4] = {
    10,20,30,40};

int * p = ary;

But if the definition is as follows , Compilation will warn .

// warning C4047: “ initialization ”:“int *” And “int (*)[4]” Different levels of indirection 
int * p = &ary;

From the warning contents , Address the array name (&ary) The type of result is int (*)[4] type . Why this type ?

First ary It is also a defined variable , Only its type is int[4] type (int An array of types , Inside 4 Elements ), from & It can be known by operation , Do... On variables & Operation to obtain a pointer to a variable of the same type , So for variables ary The type obtained by taking the address is int[4] *

So it should be defined as follows

int[4] *p = &ary;

But this kind of writing is not supported in grammar , The correct wording should be as follows

int (*p)[4] = &ary;

The parentheses here are different from pointer arrays int *p[4], because * Priority is lower than [], So the array pointer is written in parentheses .

summary : Get array pointer type by logarithm group address .

int main(int argc, char* argv[], char* envp[])
{
    
    int ary[4] = {
    10,20,30,40};

    printf("%p\r\n", ary);
    printf("%p\r\n", &ary);   //  The array takes the address to get the array pointer  int[4]*
    printf("%p\r\n", ary + 1);
    printf("%p\r\n", &ary + 1);   // &ary by int[4]* type . by int[4] Pointer to type , We can know from the pointer operation mode ,&ary+1 The address for  (int)&ary + sizeof(int[4])*1 = (int)&ary+16

    system("pause");
    return 0;
}

/* // output 0019FECC 0019FECC 0019FED0 0019FEDC 0x0019FECC 0a 00 00 00 14 00 00 00 1e 00 00 00 28 00 00 00 ............(... 0x0019FEDC cc cc cc cc 56 98 37 56 04 ff 19 00 63 74 45 00 ????V?7V....ctE. 0x0019FEEC 01 00 00 00 00 6c 92 00 08 93 92 00 01 00 00 00 .....l?..??..... */

Consider another situation , Can you define a variable to receive the array name of a two-dimensional array ?

int nAry[2][4] = {
    
	{
    10,20,30,40},
	{
    60,70,80,90
};

The type of this array is int[4] type ,nAry There are two elements , Each element is a int[4] That is to say int An array of types .

The array name is number 0 Pointer constants for elements , Array name nAry Of the 0 Elements nAry[0] by int[4] type , therefore nAry yes int[4]* type .

So you can define variables like this

int[4] *p = nAry;

Also, the syntax does not support , The correct way to write it should be

int (*p)[4] = nAry;
int main(int argc, char* argv[])
{
    
    int nAry[2][4] = {
    
        {
    10,20,30,40},
        {
    60,70,80,90}
    };

    int(*p)[4] = nAry;
    
    system("pause");
    return 0;
}

A profound

int main(int argc, char* argv[])
{
    
    int nAry[2][4] = {
    
        {
    10,20,30,40},
        {
    60,70,80,90}
    };

    int(*p)[4] = nAry;

	/* 0x0019FEBC 0a 00 00 00 14 00 00 00 1e 00 00 00 28 00 00 00 ............(... 0x0019FECC 3c 00 00 00 46 00 00 00 50 00 00 00 5a 00 00 00 <...F...P...Z... 0x0019FEDC cc cc cc cc 85 c9 90 ad 04 ff 19 00 c3 75 45 00 ????????....?uE. 0x0019FEEC 01 00 00 00 00 6c 8a 00 08 93 8a 00 01 00 00 00 .....l?..??..... */

    printf("%p\r\n", p);
    printf("%p\r\n", *p);
    printf("%p\r\n", (void*)**p);
    

    printf("%p\r\n", (void*)sizeof(p));
    printf("%p\r\n", (void*)sizeof(*p));
    printf("%p\r\n", (void*)sizeof(**p));
    

    printf("%p\r\n", p + 1);
    printf("%p\r\n", *p + 1);
    printf("%p\r\n", (void*)(**p + 1));


    printf("%p\r\n", p[1] + 1);

    printf("%p\r\n", (void*)*((p + 1)[1]));
    printf("%p\r\n", (void*)(*(p + 1))[1]);

    //  Subscript operation has priority over * Operation has high priority 
    printf("%p\r\n", (void*)(*p[1] + 1));
    printf("%p\r\n", (void*)(p[1] + 1)[1]);

    system("pause");
    return 0;
}

/* 0019FEBC 0019FEBC 0000000A 00000004 00000010 00000004 0019FECC 0019FEC0 0000000B 0019FED0 CCCCCCCC 00000046 0000003D 00000050 */

summary

Serial number The rules
0 The array name is the number... Of the array 0 Pointer constants for elements
1 Array subscript operation to get the reference of its element
2 Variable of a certain type & Operation to get pointers of the same type
3 A pointer of a certain type plus an integer gets a pointer constant of the same type
4 A pointer of a certain type is indexed to obtain a variable reference of the same type
5 Pointer of a type * Operation to get a reference to a variable of a certain type
原网站

版权声明
本文为[shlyyy]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203010516523910.html