指针初阶

1. 指针

 

地址,空间

大部分数字计算机将内存,分割为一个个空间,每一个空间大小为一个字节

每一个字节,都对应着一个编号进行管理,这些编号也称为地址

什么是指针,指针变量

C语言通常称为低级语言,这里的低级是指C语言与计算机底层有紧密的联系,可以通过指针来访问内存空间

所以,指针可以理解为地址

既然指针就是地址,那么指针变量就是存储地址的变量

口语中的指针,实际上是指针变量

 

指针的申明

int * pa

* 表示pa是一个指针,

int, 表示指针的类型为整形, 存储的是一个整形变量的地址,也叫做指向整形的指针

 

 

取地址& ,间接引用* 操作符

直接看一个例子

#include <stdio.h>
int main()
{
	int a = 1;
	int* pa = &a;
	*pa = 2;
	printf("%d", a);
}

 

执行流程

1,int a = 1

开辟4个字节的空间,然后将1存进去

2,int* pa = &a

&, 取地址操作符

&a表示取出整形变量a的起始地址,存入整形指针pa的存储空间中

 

3, *pa = 2

* ,间接寻址操作符,通过地址访问对应的空间

pa 存储的是a的地址, *pa 实际上访问的是a的空间,然后将存入2

 

2. 指针类型

指针的大小

#include <stdio.h>
int main()
{
	printf("%d\n", sizeof(char*));
	printf("%d\n", sizeof(int*));
	printf("%d\n", sizeof(double*));
    
}

指针是存储地址的变量,地址的大小由机器地址线决定

所以指针的大小都是一样的,和类型无关

那么,指针类型的意义是什么 ?

 

类型的意义

1. 类型决定,*寻址的权限

观察下面两个例子

#include <stdio.h>
int main()
{	
	int a = 0x11223344;
	int* pa = &a;
	*pa = 0;
}

#include <stdio.h>
int main()
{	
	int a = 0x11223344;
	char* pa = (char*)&a;
	*pa = 0;
}

当pa的类型为整形时,*寻址可以一次性访问4个字节

pa类型为字符时, 只能访问一个字节

 

2. 类型决定,指针的步长

#include <stdio.h>
int main()
{	
	int a = 0x11223344;
	int* pa = &a;
	char* pb = (char*)&a;
	printf("%p\n", pa);
	printf("int*: %p\n", pa + 1);
	printf("char*: %p\n", pb + 1);

}

pa, 整形指针, +1跳过了4个字节

pb, 字符指针, +1跳过了1个字节

类型决定指针进行运算时,具体跳过多少个字节

 

3. 指针运算

指针 + 整数

#include <stdio.h>
int main()
{
	int a = 0;
	int* pa = &a;
	char* pb = (char*)&a;
	printf("%p\n", pa);
	printf("%p\n", pa+1);
	printf("%p\n", pb);
	printf("%p\n", pb + 1);
}

从中可以发现,指针+整数,是向高地址移动的,指针的步长由指针的类型决定

 

 

指针 - 整数

#include <stdio.h>
int main()
{
	int a = 0;
	int* pa = &a;
	char* pb = (char*)&a;
	printf("%p\n", pa);
	printf("%p\n", pa - 1);
	printf("%p\n", pb);
	printf("%p\n", pb - 1);
}

 

指针-整数时,指针向低地址移动,移动的步长由类型决定

 

指针 - 指针

#include <stdio.h>
int main()
{
	int arr[10] = {0,1,2,3,4,5,6,7,8,9};
	printf("%d\n", &arr[9] - &arr[0]);
}

指针 - 指针,得到的是两个指针之间的元素个数

 

分析

 

注意: 

C语言规定,指针 - 指针时,必须要确保两个指针指向同一内存块

同时,保证两个指针类型相同

 

指针 - 指针的应用

// 求字符串长度
#include <stdio.h>
 
int len1(char* str)
{
	int count = 0;
	char* ps = str;
	while (*str != '\0')
	{
		str++;
	}
	return str - ps; // 指针 - 指针
}
int main()
{
	char arr[] = "abcdef";
	int res = len1(arr);
	printf("%d\n", res);
	return 0;
}

 

 

指针的关系运算

可以用关系运算符,对两个指针进行比较

比较的结构,取决于两个指针在同一内存块中的地址

#include <stdio.h>
int main()
{
	int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
	printf("%d\n", &arr[9] <= &arr[0]);
	printf("%d\n", &arr[9] >= &arr[0]);
}

 

数组元素9的地址大于或等于元素0 的地址,为1(真)

所以,两个指针之间进行比较,实际上比较的是地址

 

4. 二级指针

什么是二级指针

指针是一个存储地址的变量,既然是一个变量,那么就可以用&取地址操作符,取出一个变量的地址

所以,二级指针就是存储一个一级指针地址的变量,也叫做指向指针的指针

#include <stdio.h>
int main()
{
	int a = 0;
	int* pa = &a;	// 一级指针
	int* *ppa = &pa;	// 二级指针
}

 

 

 

二级指针的声明与赋值

int* *ppa;

ppa前面的*, 表示pppa是一个指针变量,用来存储地址

int*, 表示变量ppa存储的是一个一级整形指针的地址

 

int* *ppa = &pa;

 二级指针和一级指针一样,可以用 =赋值运算符,进行赋值

 

二级指针的使用

#include <stdio.h>
int main()
{
	int a = 0;
	int* pa = &a;	// 一级指针
	int** ppa = &pa;	// 二级指针
	**ppa = 1;
	printf("%d\n", a);
}

 

 * *ppa = 1

*ppa,表示访问ppa的空间, ppa存放的是pa的地址, 所以可以这么理解 **ppa = *(pa)

*pa, 访问的是a的空间,并存入1

 

posted @ 2023-02-16 14:26  许木101  阅读(49)  评论(0)    收藏  举报