指针基础知识理解(简单、易懂、超详细!!!!)

目录

一、基础知识补充

(1)计算机的语言表示

(2)计算机基础单位和数据类型

(3)二进制数

二、指针

(1)指针是什么?

(2)指针变量

         (3)指针变量大小和指针类型

① 指针变量大小 

②指针类型

③用指针打印整个数组元素

 (4)指针运算

 ①指针 + - 整数

 ②指针 - 指针

(5)二级指针

(6)指针数组

三、共勉


一、基础知识补充

(1)计算机的语言表示

    在现代的计算机中主要采用的数字集成电路完成,数字电路通过高低电平只能表示0和1,所以就出现了,计算机只会识别0和1。无论是存储还是计算,计算机均采用二进制体系完成。

    例如:十进制 4 ---------- 用二进制表示为 00000100 。

(2)计算机基础单位和数据类型

    1. bit------------ 比特

    2. byte --------- 字节 ------------- 1byte = 8bit

    3. KB ------------ 千字节 ---------- 1KB = 1024byte

    4. MB ----------- 兆 ---------------- 1MB = 1024KB

    5. GB ----------- 吉字节 ---------- 1GB = 1024MB

    6. TB  ----------- 太字节 ---------- 1TB = 1024GB

    7. PB ----------- 拍字节 ----------- 1PB = 1024TB

其中在C语言中的一些特定的数据类型存储也是有一定的范围的:

    1. char -------- 1字节                     2. short --------- 2字节

    3. int -------- 4字节                        4. long ---------- 4字节

    5. long long -------- 8字节             6. float ---------- 4字节


(3)二进制数

    数字在计算机中的二进制表示形式也被称为机器数,其中 二进制数有两个特点:

    1. 二进制数是带符号的,即分正、负数。其中若是正数最高位显示 0 ,若是负数最高位显示 1

    2. 二进制位通常也会受到数据类型的限制,比如 char 型 1 个字节 8 个比特位。

    举例:int 2 ;  ------------------二进制表示:00000000 00000000 00000000 00000010


二、指针

(1)指针是什么?

    在大家初学指针时,或者看书学习指针肯定会觉得指针枯燥乏味,本次我会从另一个我理解的角度去给大家展示,如何去学习指针。

    首先想要了解指针,必须要知道什么时内存,内存:就是存放东西的空间,其中用画图来给大家更加形象的解释内存。

其中左图就是内存这个内存中有9个空间,一个空间代表一个字节。

其中右图就是在这个内存空间中,去创建两个变量  int a 和一个 char ch 根据基础知识,可以知道int 占4个字节 char 占1个字节注意内存中间的每一个小空间(就是1个字节)是有编号的(1,2,3,4,5,6,7,8,9),内存的编号就是地址,地址也叫指针。

总结:1.内存的编号就是地址,地址也叫指针。

           2. 指针是内存中最小单元的编号,也就是地址。

           3. 编号-------->地址---------->指针

(2)指针变量

    指针变量是用来存放内存地址的变量。代码演示: 

#include <stdio.h>
int main()
{
	int a = 10;  //创建一个变量 a = 10
	int* pa = &a;  // 将 a  的首地址传给指针变量 int *pa 
	// 注意:* 为解引用符   用来找到此pa地址里存放的数值   pa 存放 a 的地址
	// 将 * 和 pa 结和在一起就是指针变量  int 为指针变量类型
	// 指针变量只存放 a 的首地址   用变量类型来判断 a 的完整地址
	// 此时 int a 为4个字节   int *pa 会先找到 a 的首地址,根据 int 在向下找3个字节,就是变量 a   
	printf("%d\n", *pa);  // 10
	*pa = 20;
	printf("%d\n", a);    // 20
	return 0;
}

 举例:int a=10;  int *pa = &a;

注意:1.:* 为解引用符   用来找到此pa地址里存放的数值   pa 存放 a 的地址。

           2:将 * 和 pa 结和在一起就是指针变量  int 为指针变量类型。

           3:指针变量只存放 a 的首地址   用变量类型来判断 a 的完整地址。

           4:此时 int a 为4个字节   int *pa 会先找到 a 的首地址,根据 int 在向下找3个字节,就是变量 a   。

           5:pa也有自己的地址,它里面存放的是别人的地址。

(3)指针变量大小和指针类型

    指针的类型具有一定的意义,在int *pa 中不只是为了去申请 4 个字节,而是代着深刻的含义,是不能随便的加入,int , char ,short, 等。  下面将以代码的形式给大家展示,为什要去设定指针的类型。

① 指针变量大小 

1. 在32位机器上 指针变量能够存储4个字节的地址
2. 在64位机器上 指针变量能够存储8个字节的地址

// 在32位的机器上
#include <stdio.h>
int main()
{
	int* pa;
	char* pc;
	float* pf;
	printf("%d\n", sizeof(pa)); // 4个字节
	printf("%d\n", sizeof(pc)); // 4个字节
	printf("%d\n", sizeof(pf)); // 4个字节

	return 0;
}

②指针类型

1. 指针类型:决定了指针进行解引用操作的时候,访问几个字节(权限)
2. char * 的指针引用字节访问1个字节
3. int * 的指针引用字节访问4个字节
4. double * 的指针引用字节访问8个字节

#include <stdio.h>
int main()
{
	// 2个16进制位,可以换算8个二进制位
  //十六进制数的进率是16,二进制数的进率是2,且16=2^4,说明二进制数连续进位4次,等效于16进制数进1位。
 //这么说可能不好理解,那么举个例子吧,比如15+1=16,用二进制表示就是1111+1=10000,用十六进制表示就是F+1=10。
// 这也就说明了一位十六进制数对应四位二进制数了(F对应1111)。
	int a = 0x11223344;
	int *pa=&a;
	*pa = 0;
	//1. 指针类型:决定了指针进行解引用操作的时候,访问几个字节(权限)
	// char * 的指针引用字节访问1个字节
	// int * 的指针引用字节访问4个字节
	// double * 的指针引用字节访问8个字节
	return 0;
}

根据上面的代码我们进行调试看结果:

     我们发现在 int 类型中的 int a = 0x11223344 刚好占用了四个字节,在将 0 赋值给 a 时4个字节由44 33 22 11变成了 00 00 00 00   此时 Int 类型给那好满足条件。

#include <stdio.h>
int main()
{
	int a = 0x11223344;
	//int *pa=&a;
	//*pa = 0;
	char* pc = &a;  
	*pc = 0;
	//1. 指针类型:决定了指针进行解引用操作的时候,访问几个字节(权限)
	// char * 的指针引用字节访问1个字节
	// int * 的指针引用字节访问4个字节
	// double * 的指针引用字节访问8个字节
	return 0;
}

     此时再次进行调试,发现出现了错误,如图所示:

     发现在 char 类型中,只改变了一个字节,此时发生了错误。但是此错误,也让我们知道指针类型是有意义的指针类型:决定了指针进行解引用操作的时候,访问几个字节(权限)。

③用指针打印整个数组元素

#include <stdio.h>
int main()
{
	int a[10] = { 0 };  //内存中创建了10个整型

	int* pa = a;  //数组名就是首元素的地址
	for (int i = 0; i < 10; i++)
	{
		*pa = i + 1;   // 数值+1
		 pa++;         //地址+1
		 //*(pa+i)=i+1
		 // pa表示pa中存放的地址  *pa表示:指向存放地址的内容,也就是解用
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", a[i]);
	}
	return 0;
}
#include <stdio.h>
int main()
{
	int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
	//printf("%d\n", a);
	//printf("%d\n", &a[0]);   //首地址
	int* p = a;
	int sz = sizeof(a) / sizeof(a[0]);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", *p);// 1 2 3 4 5 6 7 8 9 10
		p++;
	}
	return 0;
}

 (4)指针运算

 ①指针 + - 整数

#include <stdio.h>
int main()
{
	int a[5] = { 0 };
	int* pa = a;
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", *(pa + i));  // 0 0 0 0 0
	}
	return 0;
}

②指针 - 指针

#include <stdio.h>
int main()
{
	int a[10] = { 0 };
	printf("%d\n", &a[9] - &a[0]);  // 9
	printf("%d\n", &a[0] - &a[9]);  // -9
	// 两个指针相减的前提是:指针指向同一块连续的空间
	return 0;
}

   两个指针相减的前提是:指针指向同一块连续的空间

   计数器(指针-指针)

#include <stdio.h>
#include <string.h>
//计数器的方法
// 指针-指针
int my_strlen(char *str)
{
	char* start = str;   // 将初始指针保存
	while (*str != '\0')
	{
		str++;
	}
	return str - start;  // 末尾指针-初始指针
}
int main()
{
	char a[] = "abcdef";
	int len = my_strlen(a);
	printf("%d\n", len);   // 6
	return 0;
}

(5)二级指针

    指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里? 这就是 二级指针 。

#include <stdio.h>
int main()
{
	int a = 10;
	int* p = &a;    //p就是指针变量 ,一级指针变量
	int** pp = &p;  // pp就是二级指针,把一级指针变量的地址取出来,放在pp里面去,pp用两解操作符
	return 0;
}

注意:1.这里因为a的类型为 int 所以对于P来说 * 应该指向int  也就有了 int *p
           2.同样 p 的类型为(int *)所以对于 pp来说 *应该指向(int *),也就有了 int* *p 

二级指针的使用

#include <stdio.h>
int main()
{
	int a = 10;
	int* p = &a;
	int** pp = &p;
	*p = 20;
	printf("%d ", a); //20
	*(* pp) = 30;
	printf("%d ", a);  //30
	return 0;
}

(6)指针数组

    指针数组是 : 数组,是存放指针的数组

int main()
{
	// 整型数组存放整型的数组
	int a[10];
	// 字符型数组存放字符的数组
	char b[10];
	// 指针数组存放指针的数组
	int* arr[5]; //存放整型指针的数组
}

    应用

#include <stdio.h>
int main()
{
	int a = 10;
	int b = 20;
	int c = 30;
	int d = 40;
	int f = 50;
	int* arr3[5] = { &a,&b,&c,&d,&f };
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", (*arr3[i])); // 10 20 30 40 50
	}
	return 0;
}

    通常用于二维数组

#include <stdio.h>
int main()
{
	// 用一维数组模拟二维数组
	int arr1[] = { 1,2,3,4,5 };
	int arr2[] = { 2,3,4,5,6 };
	int arr3[] = { 3,4,5,6,7 };
	int arr4[] = { 4,5,6,7,8 };
	int *arr[4]={arr1, arr2, arr3, arr4}; //指针数组
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 5; j++)
		{
			//printf("%d ", arr[i][j]);
			printf("%d ", *(*(arr + i) + j));  // 不可看作二级指针
		}
		printf("\n");
	}
	return 0;
}

三、共勉

    这就是我对指针的初级理解,如果又不懂,或者问题的小伙伴,可以在评论区说出来,我们一起讨论,一起加油哦!!!

猜你喜欢

转载自blog.csdn.net/weixin_45031801/article/details/127017272
今日推荐