野指针、空指针、指针和数组、指针运算、多级指针-掌握C语言中的指针-系列七

目录

一、C语言中的指针(初识)

二、指针和内存单元

三、指针定义和使用

三、野指针

四、空指针

五、万能指针/泛型指针(void *)

六、指针和数组的区别

七、指针的加减运算

八、指针实现 strlen 函数

九、指针比较运算

十、指针数组

十一、多级指针

十二、写在最后


一、C语言中的指针(初识)

二、指针和内存单元

  • 指针: 地址。
  • 内存单元: 计算机中内存最小的存储单位。——内存单元。大小一个字节。 每一个内存单元都有一个唯一的编号(数)。称这个内存单元的编号为 “地址”。
  • 指针变量:存地址的变量。

三、指针定义和使用

  • 指针的大小与类型 无关。 只与当前使用的平台架构有关。32位:4字节。64位:8字节。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

int main0101(void)
{
	int a = 10;

	int *p = &a;

	//*p = 2000;
	a = 350;

	//printf("a = %d\n", a);
	printf("*p = %d\n", *p);
	
	printf("sizeof(int *) = %u\n", sizeof(int *));
	printf("sizeof(short *) = %u\n", sizeof(short *));
	printf("sizeof(char *) = %u\n", sizeof(char *));
	printf("sizeof(long *) = %u\n", sizeof(long *));
	printf("sizeof(double *) = %u\n", sizeof(double *));

	printf("sizeof(void *) = %u\n", sizeof(void *));



	system("pause");
	return EXIT_SUCCESS;
}

三、野指针

1. 没有一个有效的地址空间的指针

int *p;

*p = 1000;

2.  p变量有一个值,但该值不是可访问的内存区域

int *p = 10;

*p = 2000;

四、空指针

	int *p = NULL;     #define NULL ((void *)0)

	*p 时 p所对应的存储空间一定是一个 无效的访问区域。

五、万能指针/泛型指针(void *)

  • 可以接收任意一种变量地址。但是,在使用【必须】借助“强转”具体化数据类型。
char ch = 'R';

void *p;  // 万能指针、泛型指针
		
p = &ch;

printf("%c\n", *(char *)p);

六、指针和数组的区别

	数组名:  
		【数组名是地址常量】 --- 不可以被赋值。	 ++ / -- / += / -= / %= / /=  (带有副作用的运算符)

		指针是变量。可以用数组名给指针赋值。 ++ -- 

	取数组元素:

		int arr[] = {1,3, 5, 7, 8};

		int *p = arr;  

		arr[i] == *(arr+0) == p[0] == *(p+0)

	指针和数组区别:

		1. 指针是变量。数组名为常量。

		2. sizeof(指针) ===》 4字节 / 8字节

		   sizeof(数组) ===》 数组的实际字节数。

	指针++ 操作数组:

		int arr[] = { 1, 2, 4, 5, 6, 7, 8, 9, 0 };
		int *p = arr;		

		for (size_t i = 0; i < n; i++)
		{
			printf("%d ", *p);
			p++;  // p = p+1;   一次加过一个int大小。 一个元素。
		}

		p的值会随着循环不断变化。打印结束后,p指向一块无效地址空间(野指针)。

七、指针的加减运算

	数据类型对指针的作用:
		
		1)间接引用:

			决定了从指针存储的地址开始,向后读取的字节数。  (与指针本身存储空间无关。)

		2)加减运算:

			决定了指针进行 +1/-1 操作向后加过的 字节数。

	指针 * / % : error!!!

	指针 +- 整数:

		1) 普通指针变量+-整数

			char *p; 打印 p 、 p+1  偏过 1 字节。

			short*p; 打印 p 、 p+1  偏过 2 字节。

			int  *p; 打印 p 、 p+1  偏过 4 字节。		
	
		2)在数组中+- 整数

			short arr[] = {1, 3, 5, 8};

			int *p = arr;

			p+3;			// 向右(后)偏过 3 个元素

			p-2;			// 向前(左)偏过 2 个元素

		3)&数组名 + 1

			加过一个 数组的大小(数组元素个数 x sizeof(数组元素类型))

	指针 +- 指针:

		指针 + 指针: error!!!

		指针 - 指针:

			1) 普通变量来说, 语法允许。无实际意义。【了解】

			2) 数组来说:偏移过的元素个数。

八、指针实现 strlen 函数

	char str[] = "hello";

	char *p = str;

	while (*p != '\0')
	{
		p++;
	}

	p-str; 即为 数组有效元素的个数。

九、指针比较运算

	1) 普通变量来说, 语法允许。无实际意义。

	2) 数组来说:	地址之间可以进行比较大小。

			可以得到,元素存储的先后顺序。

	3) int *p;

	    p = NULL;		// 这两行等价于: int *p = NULL;

	    if (p != NULL)

		printf(" p is not NULL");

	    else 
		printf(" p is NULL");

十、指针数组

	一个存储地址的数组。数组内部所有元素都是地址。

	1) 
		int a = 10;
		int b = 20;
		int c = 30;

		int *arr[] = {&a, &b, &c}; // 数组元素为 整型变量 地址
	2) 

		int a[] = { 10 };
		int b[] = { 20 };
		int c[] = { 30 };

		int *arr[] = { a, b, c }; // 数组元素为 数组 地址。	

	指针数组本质,是一个二级指针。

	二维数组, 也是一个二级指针。

十一、多级指针

	int a = 0;

	int *p = &a;  				一级指针是 变量的地址。

	int **pp = &p;				二级指针是 一级指针的地址。

	int ***ppp = &pp;			三级指针是 二级指针的地址。	

	int ****pppp = &ppp;			四级指针是 三级指针的地址。
	......


	多级指针,不能  跳跃定义!

	
	对应关系:

	ppp == &pp;			三级指针

	*ppp == pp == &p; 			二级指针

	**ppp == *pp == p == &a				一级指针

	***ppp == **pp == *p == a				普通整型变量

	*p : 将p变量的内容取出,当成地址看待,找到该地址对应的内存空间。

		如果做左值: 存数据到空间中。

		如果做右值: 取出空间中的内容。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值