带你重新了解指针

1.指针的概念

在计算机内存中,每一块内存都有自己的地址,这里的地址在c语言中就叫指针,详细来说指针就是一个用于存储“另外一个变量地址”的变量。

2.学习指针前需要认识的&*

2.1取地址操作符&

	int a = 0;
	printf("%p\n", &a);

这里&a会取出a所占四个字节中地址较小的字节的地址

2.2解引用操作符*

int a=0;
int *p=&a;//取出a的地址并保存在指针变量p中

我们&a得到的地址是一个数值,比如0X006FFD70,这种变量一般存放在指针变量中,也就是*p,这种变量就是用来存放地址的,存放在指针变量中的值都会被理解为地址。

当然*还有一个重要的用途就是解引用,通过解引用可以找到指针指向的对象。

int a=10;
int *p=&a;
*p=0;

这里第三行*p=0就使用了解引用,意思是通过p存放的地址找到p指向的对象并将值改为0,最结果是a=0。

3.指针类型的意义

众所周知变量类型有很多种,每种类型所占的字节也略有差异。 

	printf("%zd\n", sizeof(int));//4
	printf("%zd\n", sizeof(char));//1
	printf("%zd\n", sizeof(double));//8
	printf("%zd\n", sizeof(float));//4

但是如果是指针变量的情况下会惊奇的发现,如果是x86环境下所有类型都是4个字节,x64环境下都是8个字节。这里的原因是

在x86环境下,指针变量的大小通常为4个字节,这是因为x86架构的内存寻址是基于32位的,即32位地址空间。每个指针变量存储一个内存地址,这个地址是由32位二进制数表示的,因此占据4个字节的存储空间。

而在x64环境下,指针变量的大小通常为8个字节,这是因为x64架构的内存寻址是基于64位的,即64位地址空间。每个指针变量存储一个内存地址,这个地址是由64位二进制数表示的,因此占据8个字节的存储空间。

指针变量的大小与计算机架构的内存寻址位数有关,不同的架构有不同的位数要求,因此指针的大小也会相应地变化。

	printf("%zd\n", sizeof(int*));
	printf("%zd\n", sizeof(char*));
	printf("%zd\n", sizeof(double*));
	printf("%zd\n", sizeof(float*));

上面说明了所有指针类型的大小都是一样的,那为什么我们还有各种各样的指针类型呢,因为指针类型决定了,对指针解引用时候有多大权限,一次可以访问多少个字节。例如:char*一次只能访问一个字节,int*一次可以访问四个字节

4.指针加减整数的变化

	int n = 10;
	int* p1 = &n;
	char* p2 = (char*)&n;
	printf("%p\n", &n);
	printf("%p\n", p1);
	printf("%p\n", p1+1);
	printf("%p\n", p2);
	printf("%p\n", p2+1);

运行结果如下,可以发现char*+1跳过了一个字节,而int*跳过四个字节,指针类型决定了指针的步长有多少。

带你重新了解指针_第1张图片

再举一个例子 

	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = &arr[0];
	for (int i = 0; i < 10; i++) {
		printf("%d ", *(p + i));
	}

 这里程序的最终结果就是把数组中所有的数据都打印出来,得出结论就是p指向了数组首元素的地址,而指针是int类型所以每次指针加1就会向后走4个字节,也就是数组的下个元素的地址,再解引用就是相当于arr[i]的作用。

5.指针-指针

	int the_strlen(char* s)
	{
		char* p = s;
		while (*p) {//不是\0就一直找
			p++;
		}
		return p - s;
	}

	int main() {
		printf("%d ", the_strlen("abcdefg"));
	}

上段代码模仿了strlen函数,利用形参接受字符串首元素地址,再通过字符串结尾一定会有\0的特点设计的一个函数,主要原理是通过循环使得指针地址的一直加,再解引用一直判断元素内容最终得出的结果。

好了以上就是指针学习的第一部分,下面内容敬请期待,如果有错误请大佬批评指正。

你可能感兴趣的:(c#,改行学it,c语言)