ポインタ(1)の基本

ポインタ(1)基本

ポインタの概念

  1. メモリの内容へのアクセスを容易にするために、各メモリセルに番号が付けられています。この番号をアドレスおよびポインタと呼びます。
  2. ポインタもデータ型であるため、ポインタにはアドレス(数値)を格納するための独自のメモリがあります。

ポインタの4つの要素

  1. ポインタ自体のタイプはポインタ名を削除し、残っているのはポインタ自体のタイプです
  2. ポインターが指すタイプは、ポインター名と*を削除し、残りはポインターが指すタイプです。
  3. ポインタ自体のメモリは、数値(4バイト)を格納するために使用されます
  4. ポインタが指すメモリには、さまざまなタイプがあります。
    int num = 0;          // 类型: int
    int arr[10] = {
    
    };     // 类型: int [10]
    int* MuShan = {
    
    1,2,3};
    //去掉名字,剩下的就是类型

2つのポインターの定義

1人のオペレーター

*:定義されている場合は、定義がポインタであることを意味します。それ以外の場合は、参照が解決されていることを意味します。

&:アドレス文字を取得します(アドレスを取得するために使用されます)

2つの定義

ポインタの定義を理解する方法はたくさんあります。

  1. 変数名を入力します。
int* p; // 类型: int
        // 变量名: *p
  1. ポインター自体のポインター名。
int* p; // 指针本身的类型: int*
        // 指针名: p
  1. ポインタが指すタイプ*ポインタ名。
int* p; // 指针指向的类型: int
        // 指针名: p

プッシュバック:

  1. ポインタ名を削除します。残っているのはポインタ自体のタイプです
  2. ポインタ名と*を削除します。残りはポインタが指すタイプです。
int****** p1; // p1本身的类型: int****** 
              // p1指向的类型: int*****  (6级指针可以指向5级指针)

スリーポインターメモリ

  1. タイプに関係なく、すべてのポインタはメモリ内の4バイトのメモリを占有します(アドレスは格納されます)(特に64/32ビット環境に関連します)
#include <stdio.h>
int main()
{
    
    
	char*       pch;
	short*      psh;
	int*        pn;
	float*      pf;
	double*     pd;
    
	printf("%d\n", sizeof(pch));  // 4
	printf("%d\n", sizeof(psh));  // 4
	printf("%d\n", sizeof(pn));   // 4
	printf("%d\n", sizeof(pf));   // 4
	printf("%d\n", sizeof(pd));   // 4
    
	return 0;
}
  1. 開始アドレスを指す
int num = 10;
int* p = &num;

[外部リンク画像の転送に失敗しました。ソースサイトにヒル防止リンクメカニズムがある可能性があります。画像を保存して直接アップロードすることをお勧めします(img-52hvEuyS-1613538026451)(C:\ Users \ admin \ Desktop \ Six-Star Education \ Learning \ Pointer \ Pointer(A)] \ Pointer Basics(1)1-1.png)

4つのポインタの初期化と割り当て

1対応する型変数のアドレスを使用します

	int num = 10;
	int* pn = &num;   //初始化

	float f = 3.14f;
	float* pf;
	pf = &f;          //赋值

2同じタイプのポインタを使用する

	int num = 10;
	int* pn = &num;     // 初始值
	int* p1 = pn;       // 初始化
	int* p2;
	p2 = pn;            // 赋值

3アドレスを直接使用する

	int* p = (int*)0x36;

4配列名を使用する

第1レベルのポインターは、1ビット配列の配列名の束を受け入れることができます

	int arr[5] = {
    
     1,2,3,4,5 };
	int* p = arr;

5文字の文字列

#include <stdio.h>
int main()
{
    
    
	// 数组名就是数组的首地址
	char arr[5] = {
    
     'a','b','c' };
	char* p = arr;
	printf("%s\n",p);     //输出:abc
	char str[5] = "abcd";
	p = str;
	printf("%s\n", str);  //输出:abcd
	printf("%s\n", p);    //输出:abcd
	// ==> char*类型的指针可以直接用来打印整个字符串到'\0'停止
	const char* p1;
	p1 = "1234";
	printf("%s\n",p1);    //输出:1234
	const char* p2 = "Mushan";
	printf("%s\n",p2);    //输出:Mushan
	return 0;
}

6空白のままにします

	int* p = NULL;
	int* p1 = (int*)0x0;
/*
   NULL: #define NULL  0
   0地址
   有时候,指针定义好了,但是暂时没有指向
   或者是,指针用完了,没有指向了
   指针不知道指向哪里(会随机指向)
   此时的指针,很危险(野指针)
   所以 这些情况下的指针
   统一安排一个地址给他们指向
   指向0地址
*/

7マルチレベルポインタ

#include<stdio.h>

int main() {
    
    
	int num = 10;
	printf(" num = %d\n", num);        //   num = 10;
	printf("&num = %X\n", &num);       //  &num = 10FFA78
    
	int* p = &num;
	printf("*p = %d\n", *p);           //  *p = 10 (num值)
	printf(" p = %X\n", p);            //   p = 10FFA78 (num的地址)
	printf("&p = %X\n", &p);           //  &p = 10FFA6C

	int** pp = &p; // 一个二级指针
	printf("**pp = %d\n", **pp);       // **pp = 10 (num值)
	printf(" *pp = %X\n", *pp);        //  *pp = 10FFA78 (num的地址)
	printf(" pp = %X\n", pp);          //   pp = 10FFA6C (p的地址)
	printf(" &pp = %X\n", &pp);        //  &pp = 10FFA60 

	int*** ppp = &pp; // 一个三级指针
	printf("***ppp = %d\n", ***ppp);   // ***ppp = 10 (num值)
	printf(" **ppp = %X\n", **ppp);    //  **ppp = 10FFA78 (num地址)
	printf(" *ppp = %X\n", *ppp);      //   *ppp = 10FFA6C (p的地址)
	printf("  ppp = %X\n", ppp);       //    ppp = 10FFA60 (pp的地址)
	printf(" &ppp = %X\n", &ppp);      //   &ppp = 10FFA54

	return 0;
}

5つのポインターの加算と減算

コア:ポインタ自体の値(ポインティング)は変更されていません

ポインタオフセット

  1. ポインタは整数を加算または減算できます

  2. ポインタが整数で加算または減算された後、実際にはオフセットされます

  3. オフセットの範囲は、プラスまたはマイナスの単位の整数です。

    単位:ポインタが指すタイプのメモリ内のバイト数

    オフセット:ポインタは変更されませんが、コンテンツはオフセットに従って取得できます

#include <stdio.h>
int main()
{
    
    
	int num = 10;
    
	int* p = &num;
	printf("%X\n", p);          // EFFB5C
	printf("%X\n", p + 1);      // EFFB60
    
	return 0;
}

6つのポインターの増減

自己インクリメントと自己デクリメントは、ポインタポイントを変更します

++:ポインタが1単位後方に移動することを示します

–:ポインタが1単位前方に移動することを示します

単位:ポインタが指すタイプが占めるメモリ内のバイト数

#include <stdio.h>
int main()
{
    
    
	int num = 10;
	int* p = &num;
	printf("%X\n", p);          // EFFB5C
	printf("%X\n", p + 1);      // EFFB60

	printf("%d\n",*p);          // 10
	printf("%X\n", p += 1);     // EFFB60
	printf("%d\n",*p);          // -858993460(无意义)
	return 0;
}

ポインタを介して配列をトラバースする7つ

1次元配列をトラバースします

#include <stdio.h>
int main()
{
    
    
	int arr[10] = {
    
     0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	for (size_t i = 0; i < 10; i++)
	{
    
    
		printf("%2d", arr[i]);
	}
	printf("\n");
	int* p = arr;
	// p和arr,除了arr是一个常量之外,其他几乎是一样的
	for (size_t i = 0; i < 10; i++)
	{
    
    
		printf("%2d", p[i]);
	}

	printf("\n");
	printf("%d\n", p[0]);        // 0
	printf("%d\n", *(p + 0));    // 0
	printf("%d\n", p[1]);        // 1(先偏移 后取值)
	printf("%d\n", *(p + 1));    // 1
	// p[n] <==> *(p+n)
	return 0;
}
// p[n]:叫做下标形式
// *(p+n):叫做指针偏移的形式

2次元配列をトラバースします

  1. 二次元配列も配列です

  2. 2次元配列は、要素が1次元配列である1次元配列と見なすことができます。

  3. 配列のメモリは連続しています

#include<stdio.h>

int main()
{
    
    
	int arr[3][4] = {
    
    
        {
    
    1,2,3,4},
		{
    
    5,6,7,8},
		{
    
    9,10,11,12}
	};

	for (size_t i = 0; i < 3; i++)
	{
    
    
		for (size_t j = 0; j < 4; j++)
		{
    
    
			printf("%3d", arr[i][j]);
		}
		printf("\n");
	}

	int* p0 = arr[0];
	int* p1 = arr[1];
	int* p2 = arr[2];
	printf("\n");
	// 1:
	for (size_t i = 0; i < 4; i++)
	{
    
    
		printf("%3d", p0[i]);           // 1  2  3  4
	}
	printf("\n");
	for (int i = -4; i <= 7; i++)
	{
    
    
		printf("%3d", p1[i]);           // 1  2  3  4  5  6  7  8  9 10 11 12
	}
	printf("\n");
	for (int i = 0; i < 12; i++)
	{
    
    
		printf("%3d", arr[0][i]);       // 1  2  3  4  5  6  7  8  9 10 11 12
	}
	printf("\n");
	// 下标: 保证数组不越界即可
    
	// 2:
	int* p = &arr[0][0];
	for (int i = 0; i < 12; i++)
	{
    
    
		printf("%3d", arr[0][i]);       // 1  2  3  4  5  6  7  8  9 10 11 12       
	}
	printf("\n");
	for (int i = 0; i < 12; i++)
	{
    
    
		printf("%3d", *p);              // 1  2  3  4  5  6  7  8  9 10 11 12
		p++;
	}
	printf("\n");
	return 0;
}

おすすめ

転載: blog.csdn.net/zhuiyizhifengfu/article/details/113833241