C语言_指针(初级)_由简到繁_案例讲解

文章目录

  • 初阶
    • 1.指针是什么
    • 2.指针类型
    • 3.野指针
    • 4.指针运算
    • 5.指针和数组
    • 6.二级指针

初阶

1.指针是什么

指针是编程语言中的一个对象。

在计算机储存器中,通过一个变量的地址可以找到所要的变量单元。该变量地址指向变量单元。

因此将地址形象的称为指针,通过指针可以找到其对应的内存单元(指针的解引用)

计算机内存布局

内存

一个字节-------0xFFFFFFFF

一个字节-------0x00000001

一个字节-------0x00000000

32位计算机共有2^32个

地址在计算机中是连续的
每个连续的地址大小位一个字节

指针是个变量,用来储存地址

#include
int main()
{
     
	int a = 10;
	int* p = &a;
	printf("%p",p);
	return 0;
}

//将a的地址给变量p,p为指针变量
p的类型是int*

注意:a占4个字节,在内存中占据4块空间,&a取的是首地址

通过指针找到对应的内存空间。

*p=20;
*表示解引用操作

注意:p是指针变量p=100;p会变成指向内存编号为100的空间

2.指针类型

常见的指针类型有:

int* - char* - float* -double*

1.不同的指针类型在解引用访问的字节数不同。
解引用访问的字节数是对应数据类型大小的字节数

int*在解引用中访问4个字节;

char*在解引用中访问1个字节;

short*解引用访问2个字节;
在这里插入图片描述
在这里插入图片描述
2.不同类型指针+1走的距离不同

#include
int main()
{
     
	int a = 10;
	int* p = &a;
	char* pc = &a;
	printf("%p \n",p);
	printf("%p \n",p+1);
	printf("————————————————\n");
	printf("%p \n", pc);
	printf("%p \n",pc+1);
	return 0;
}

C语言_指针(初级)_由简到繁_案例讲解_第1张图片
整形指针+1走过一个整形的大小,字符指针+1走过一个字符的大小

注意:指针大小与指针类型无关

在32位平台指针是4个字节

在64位平台上指针是8个字节

3.野指针

定义:指针指向位置不明确。

造成野指针的原因:

1.指针未初始化

int* p;//指针未初始化
*p=10;

2.指针所指向的空间被释放

#include

int* test()
{
     
	int a = 10;
	return &a;
}
int main()
{
     
	int* p = test();//a空间出函数被释放
	printf("hehe\n");
	printf("%d ",*p);
	return 0;
}

3.数组越界访问

#include
int main()
{
     
	int arr[10] = {
     0};
	int* p = arr;
	for (int i = 0; i < 11; i++)//数组越界
	{
     
		*(arr + i) = i;
	}
	return 0;
}

注意:

空指针NULL不能进行解引用,在进行指针初始化的时候要注意。

int* p=NULL;
*p=10;

4.指针运算

1.指针±整数

不同类型指针+1走的距离不同,同理加减不再赘述

通过设定不同的指针类型,可以控制解引用访问的大小

int arr[10]={
     0};
int* p=arr;
for(int i=0;i<10;i++)
{
     
    *(p+i)=i;
}

2.指针-指针

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

#include
int main()
{
     
	int arr[10] = {
     0};
	printf("%d ",&arr[9]-&arr[0]);
	return 0;
}

在这里插入图片描述
注意:

#include
int main()
{
     
	int arr[10] = {
      0 };
	int ch[10] = {
      0 };
	printf("%d ",&arr[10]-&ch[0]);
	return 0;
}

结果为随机值,不清楚arr数组与ch数组之间有几个元素个数

所以指针-指针计算的条件为:两个指针指向的是同一块连续的空间

3.指针关系运算

指针大小比较:

#include
int main()
{
     
	int arr[5] = {
      0 };
	for (int* p = &arr[5]; p > &arr[0];)
	{
     
		*(--p) = 0;
	}
	return 0;
}

注意:

标准规定,在c语言中,指针可以比较数组最后元素
之后的元素。但不可以与数组首元素前的元素进行比较

#include
int main()
{
     
	int arr[5] = {
      0 };
	for (int* p=&arr[4];p>=&arr[0];p--)
	{
     
		*p=o;//指针指向了数组首元素之前的元素,可能会报错
	}
	return 0;
}

5.指针和数组

一维数组:数组名是首元素的地址

#include
int main()
{
     
	int arr[5] = {
     0};
	printf("%p\n",&arr[0]);
	printf("%p\n",arr);
	return 0;
}
int arr[5]={
     0};
int* p=&arr[0];
//&arr[i]=p+i

二维数组:数组名是第一行一维数组的地址

注意.第一行的地址与第一个元素的地址大小相同,但有区别

6.二级指针

指针变量也是变量,也有其地址。

二级指针存放一级指针变量的地址

#include
int main()
{
     
	int a = 5;
	int* p = &a;
	int** pp = &p;
	return 0;
}

C语言_指针(初级)_由简到繁_案例讲解_第2张图片

你可能感兴趣的:(C语言)