C语言-指针初阶(6)

目录

思维导图:

1. 指针是什么?

2. 指针和指针类型 

2.1 指针+-整数

2.2 指针的解引用

3. 野指针

3.1 野指针成因

3.2 如何规避野指针

4. 指针运算

4.1 指针+-整数

4.2 指针-指针

4.3 指针的关系运算

5. 指针和数组

6. 二级指针

7. 指针数组

写在最后:


思维导图:

1. 指针是什么?

想了解指针,必须先了解内存是什么?

内存是计算机上的一种存储空间,程序运行时会载入内存,存储数据时也会申请内存。

而一个内存单元的大小是一个字节,每个内存单元都有自己的编号,而内存单元的编号被称为地址

在C语言中,地址也被称为指针。

总结:内存单元的编号 = 地址 = 指针

有关指针:

关于指针的大小:

2. 指针和指针类型 

2.1 指针+-整数

指针类型的意义:

例:

2.2 指针的解引用

指针类型决定了,指针进行解引用操作的时候,一次性访问几个字节,访问权限的大小

如果是char*的指针,解引用访问1个字节

如果是int*的指针,解引用访问4个字节

 所以,指针的访问是可以灵活运用的:

例:


#include <stdio.h>

int main()
{
	int a = 0x11223344;
	int* pa = &a;	
	*pa = 0;//一次性将四个字节初始化成零
	
	char* pc = &a;
	*pc = 0;//一次只将一个字节初始化成零

	return 0;
}

3. 野指针

野指针就是指针指向的位置是不可知的。

3.1 野指针成因

1. 指针未初始化

例:

int main()
{
	int* p;//未初始化
	*p = 20;
	return 0;
}

2. 指针越界访问

例:

#include <stdio.h>

int main()
{
	int arr[5] = { 1,2,3,4,5 };
	int* p = arr;
	int i = 0;
	for (i = 0; i <= 5; i++)
	{
		printf("%d ", arr[i]);//越界访问
	}
	return 0;
}

输出结果:

输出:1 2 3 4 5 -858993460(随机值)

3.2 如何规避野指针

1. 指针初始化

2. 小心指针越界

3. 指针指向空间释放,及时置NULL

4. 避免返回局部变量的地址

5. 指针使用之前检查有效性

例:

#include <stdio.h>
int main()
{
	int a = 10;
	int* pa = &a;//指针的初始化

	int* p = NULL;//NULL - 空指针,专门用来初始化指针
	if (p != NULL)//使用前检查指针的有效性
	{
		;
	}
	return 0;
}

4. 指针运算

4.1 指针+-整数

例:

int main()
{
	int arr[n];
	int* p;
	for (p = &arr[0]; p < &arr[n];)
	{
		*p++ = 0;//先赋值再++,将数值arr中的值都初始化成0
	}            //每一次++都想后移一个整形
	return 0;
}

4.2 指针-指针

例:

#include <stdio.h>

int main()
{
	int arr[10] = { 0 };
	printf("%d\n", &arr[9] - &arr[0]);//指针相减的值是两个指针之间的元素个数

	return 0;
}

注:两个数组的指针之间是不能相加减的

应用:

模拟实现strlen函数:

#include <stdio.h>

my_strlen(char* arr)
{
	char* str = arr;
	while (* arr != '\0')
	{
		arr++;
	}
	return arr - str;//数组长度
}

int main()
{
	char arr[] = "abcdef";
	int len = my_strlen(arr);

	printf("%d\n", len);
	return 0;
}

输出结果:

输出:6

4.3 指针的关系运算

例:

#include <stdio.h>

#define n 5

int main()
{
	int arr[n];
	int* p;
	for (p = &arr[0]; p < &arr[n];)//这个其实就是指针之间的关系运算//p < &arr[n]
	{
		*p++ = 0;//先赋值再++,将数值arr中的值都初始化成0
	}            //每一次++都想后移一个整形
	return 0;
}

5. 指针和数组

用指针打印数组:

例:

#include <stdio.h>
int main()
{
	int arr[10] = {0};
	int* p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;

	//给数组赋值
	for (i = 0; i < sz; i++)
	{
		*(p + i) = i + 1;//通过指针访问数组的每一个元素
	}

	//打印数组
	for (i = 0; i < sz; i++)
	{
		//printf("%d ", arr[i]);
		printf("%d ", *(arr + i));//这两种打印方式是一模一样的
	}
	return 0;
}

输出结果:

输出:1 2 3 4 5 6 7 8 9 10

6. 二级指针

例:

#include <stdio.h>

int main()
{
	int a = 0;
	int* pa = &a;//pa是一级指针变量
	int** ppa = &pa;//ppa是二级指针变量
	**ppa = 50;
	printf("%d\n", **ppa);
	printf("%d\n", a);
	return 0;
}

输出结果:

输出:
50
50

当然如果你想创建三级指针变量,规则也是一样的。

7. 指针数组

指针数组是什么?

指针数组是数组(数组是主语),就比如:好孩子是孩子(孩子是主语)(主语在后面)

例:

#include <stdio.h>

int main()
{	//我们可以使用一维数组,模拟一个二维数组
	int a[] = { 1,2,3,4 };
	int b[] = { 2,3,4,5 };
	int c[] = { 3,4,5,6 };
	int* arr[3] = { a,b,c };
	int i = 0;
	int j = 0;
	for (i = 0; i < 3; i++)
	{	//通过i访问arr
		for (j = 0; j < 4; j++)
		{	//通过j访问a b c
			printf("%d ", arr[i][j]);
		}
		printf("\n");
	}
	return 0;
}

输出结果:

输出:
1 2 3 4
2 3 4 5
3 4 5 6

写在最后:

以上就是本篇文章的内容了,感谢你的阅读。

如果喜欢本文的话,欢迎点赞和评论,写下你的见解。

如果想和我一起学习编程,不妨点个关注,我们一起学习,一同成长。

之后我还会输出更多高质量内容,欢迎收看。

  • 32
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 44
    评论
评论 44
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

戊子仲秋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值