IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 一文搞懂C语言如何用指针来代替变量和数组进行数据的存储 -> 正文阅读

[C++知识库]一文搞懂C语言如何用指针来代替变量和数组进行数据的存储

??众所周知,指针的用法最常见的无外乎两种,一种是用指针来指向变量的内存地址,通过操控指针进而可以间接的操控变量。另外一种是把指针当成变量来使用,像变量一样可以存储数据。数组也是类似的道理,因为数组实际上也是变量。本文仅讨论第二种情况,即用指针来代替变量和数组进行数据的存储。

??用指针来存储数据主要有三种方法,即:

  1. 定义指针之后直接使用
  2. 定义指针之后,分配内存再使用

预科知识

??我们知道,c语言在定义变量的同时,会为变量分配一个对应类型的内存空间,方便后续用该内存空间来存储数据。如果没有初始化的话,这个内存空间里面的值是随机的,不确定的。如果加了static关键字,并且没有初始化的话,这个值就是0。

int a; //会为a分配一个int类型的内存空间,大小为4字节,该内存空间的值是随机的

static int b;  //会为b分配一个int类型的内存空间,大小为4字节,并且该内存空间里面的值是0

int c = 3;  //会为c分配一个int类型的内存空间,大小为4字节,并且该内存空间里面的值是3

??而在定义指针变量的时候,也会为指针变量分配一个对应类型的内存,里面存储的数据的情况也和上面类似,但是不同的是,指针存储的是内存首地址,而变量存储的是基本初等类型。

??定义了一个指针变量,如果没有初始化的话,它指向一个随机的未知的空间,也称为野指针。所以为了系统的内存安全性,一般在定义的时候将指针初始化为NULL,表示该指针不指向任何空间。

??因为指针存储的是地址,所以指针占的空间和语言无关,和系统有关。32位系统的话,占4个字节,16位系统的话,占2个字节。

int *a; //未初始化,指针指向一个未知的地址空间

int *b = NULL;  //指针不指向任何地址空间

int c;  
int *d = &c;  //指针指向变量c的地址

一、定义指针之后直接使用

??既然未初始化的指针指向的地址是随机的,那么就可以用这个地址来存储数据。

1.当成变量使用

??我们这里以结构体为例。我们可以看到,未初始化的指针也可以像变量一样用来存储数据。只不过受限于编译器的缘故,有的电脑可能能正常输出结果,而有的会异常终止。

??这种用野指针的行为,我不提倡大家使用!!

struct Student{  //定义一个学生结构体 
	int age; // 年龄
	int number; // 学号 
};

struct Student stu; //定义一个结构体变量 

struct Student *stuu;  //定义一个未初始化的结构体指针 

int main()
{
	//为结构体变量赋值 
	stu.age = 12;
	stu.number = 12345;
	
	//为结构体指针赋值 
	stuu->age = 13;
	stuu->number = 11111;
	
	printf("%d\n",stu.age);
	printf("%d\n",stu.number);
	
	printf("%d\n",stuu->age);
	printf("%d\n",stuu->number);
	
	return 0;
}

2.当成数组使用

??当成数组使用的时候也和上面类似,有的电脑可能能正常输出结果,而有的会异常终止。

??这种用野指针的行为,我不提倡大家使用!!

int main()
{
	int *a; //定义一个未初始化的指针 
	a[0] = 11;
	a[1] = 22;
	a[2] = 33;
	a[3] = 44;
	a[4] = 55;
	
	int b[5] = {1, 2, 3, 4, 5}; //定义一个数组 
	
	for(int i = 0;i < 5; i++)
	{
		printf("%d ",a[i]);
		printf("%d ",b[i]);
	}
	
	return 0;
	
}

二、定义指针之后,分配内存再使用

??我们定义了未初始化的指针之后,可以用malloc函数,为这个指针分配空间。即,指针就会指向该空间的首地址。如果这个空间大小刚好是n个int类型的大小的话,这个指针就相当于一个大小为n的int数组,可以用来存储数据。

??这种方式,就不是野指针的用法了,提倡大家用这种方法。但是所存储的数据大小最好不要超过分配的空间的大小,不然就和野指针一样,可能会发生内存安全问题,导致异常终止。

1、当成变量使用

??和上面的代码类似,只不过多了一步,就是为指针分配了空间。

struct Student{  //定义一个学生结构体 
	int age; // 年龄
	int number; // 学号 
};

struct Student stu; //定义一个结构体变量 

struct Student *stuu = (struct Student *)malloc(sizeof(struct Student));  //定义一个分配了空间的结构体指针 

int main()
{
	//为结构体变量赋值 
	stu.age = 12;
	stu.number = 12345;
	
	//为结构体指针赋值 
	stuu->age = 13;
	stuu->number = 11111;
	
	printf("%d\n",stu.age);
	printf("%d\n",stu.number);
	
	printf("%d\n",stuu->age);
	printf("%d\n",stuu->number);
	
	return 0;
}

??可以看到能正常输出,不会异常终止程序。
在这里插入图片描述

2.当成数组使用

??和上面的代码类似,只不过多了一步,就是为指针分配了空间。

int main()
{
	int *a = (int *)malloc(sizeof(int) * 5); //定义一个分配了5个int大小内存空间的指针 
	a[0] = 11;
	a[1] = 22;
	a[2] = 33;
	a[3] = 44;
	a[4] = 55;
	
	int b[5] = {1, 2, 3, 4, 5}; //定义一个数组 
	
	for(int i = 0;i < 5; i++)
	{
		printf("%d ",a[i]);
	}
	
	printf("\n");
	
	for(int i = 0;i < 5; i++)
	{
		printf("%d ",b[i]);
	}
	
	return 0;
	
}

??看一下运行结果。
在这里插入图片描述

三、总结

??1、指针可以作为数组用,数组号表示指针基地址偏移。

??2、第一次看到这种用法的时候,我觉得很诧异(居然可以这样子。。。。)。但是后来想想,这种用法也合情合理,毕竟数组名本身也是数组的首地址,数组是有类型的,数组元素的类型都是相同的,这样数组下标可以根据类型来决定偏移多少空间,找到对应下标元素的地址,从而找到对应的元素。回过头来看指针当成数组使用,指针也是有类型的,int* 、 char*、 unsigned char* 、struct st* 等等。这样的话,把指针当成数组使用,利用下标来寻找偏移地址,也可以根据类型知道每次偏移多少空间。

??3、如果只定义指针,没有初始化系统是不会给它分配内存的,初始化后,只是指向某个内存而已,没有初始化的指针是指向一个未知的内存地址,这样的指针是很危险的。一般我们定义一个指针变量就会给它初始化为空,以免造成的危险无法补救。分配内存之后它再也不指向a变量的内存地址,而是指向一个新的内存地址。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-10-17 12:13:43  更:2022-10-17 12:15:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 10:36:50-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码