我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C语言指针原来也可以这样了解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C语言指针原来也可以这样了解

什么是指针

指针是应该对象,可以直接指向电脑存储器中的某个地方,这个地方就是内存单元,指针指向的是一个对象的地址。地址的指向就是内存单元,一个内存单元是一个字节,在32位平台上面,一个指针是4个字节。因为32位的平台有32根地址线,每根地址线是 1 bit,所以32位平台的指针大小是 4 个字节。同理,64位平台的指针大小就是 8 个字节。

指针的应用

指针用于指向某个对象的地址,也可以通过指针解引用来修改对象。


int main()
{
	int a = 10;
	int* p = &a;			
	printf("%d\n", *p);		//10
	return 0;
}

&a 就是把 a 的地址取出来。int* 说明 p 是指针变量,指向的对象是整型。所以 *p 指向的就是 a 的地址,打印出来也是10。因为 *p和 a 指向的是同一块内存,所以对 *p修改也就是对 a 的值进行修改。


int main()
{
	int a = 10;
	int* p = &a;
	*p = 20;
	printf("%d\n", a);		//20
	return 0;
}

这里就是通过 *p 对 a 的值进行修改。

指针 ± 整数

指针 + 指针

指针指向的是一个对象。比如指针 + 1,就是指向后一个元素,拿数组举例。


int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%d\n", *arr);
	printf("%d\n", *(arr + 1));
	printf("%d\n", *(arr + 2));
	return 0;
}

在这里插入图片描述

从图片可知,指针每次 + 1,都会指向数组的下一个元素。如果是对数组取地址再 + 1的话,就会跳过整个数组,指向整个数组后面的地址。所以使用指针加减和取地址加减的时候,一定要注意。

指针 - 指针

指针 - 指针算的是两个指针之间的元素个数。


int my_strlen(char* s)
{
	char* p = s;
	while (*p != '\0')
		p++;
	return p - s;
}
int main()
{
	char arr[10] = "abcdef";
	int ret = my_strlen(arr);
	printf("%d\n", ret);			//6
	return 0;
}

算的结果是 6,因为指针相减,得到了差的元素个数。

野指针

野指针就是指针执行的位置使随机的,是没有被分配的内存空间。

野指针成因

野指针是由于指针未初始化,指针越界访问造成的。野指针也是经常导致程序崩溃的原因。

指针未初始化


int main()
{
	int* p;
	*p = 20;
	return 0;
}

这里的指针就没有初始化,没有初始化指向的内容,就是野指针,而且这里连编译也完成不了。

指针越界访问

指针越界访问是一件非常可怕的事情,会导致程序崩溃,程序死循环。


int main()
{
	int i = 0;
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	for (i = 0; i <= 12; i++)
	{
		arr[i] = 0;
		printf("haha\n");
	}
	return 0;
}

上面这个代码就死循环了,因为指针越界访问,造成了死循环.这里是一个压栈的情况造成的。用下面这张图来解释:

在这里插入图片描述

上面这张图就描述了这个死循环的过程。

指针和数组

数组名其实表示的就是首元素的地址,传参的时候传数组名就等于是传了数组的首元素地址。因为数组在内存当中是连续存储的,所以只要把首元素地址传过去就可以了。


int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%p\n", &arr[0]);
	printf("%p\n", arr);
	return 0;
}

在这里插入图片描述

通过图片就可以看出。

指针 ± 和数组的关系

当指针 ± 的时候,解引用指向数组的元素也在发生改变,+1,表示向后移动一个元素。


int main()
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,0 };
	int* p = arr; //用指针来存放数组首元素的地址
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("&arr[%d] = %p   <====> p+%d = %p\n", i, &arr[i], i, p + i);
	}
	return 0;
}

使用数组的时候,也可以换做指针来使用,看起来会整洁一些。

二级指针

因为指针变量也是变量,是变量就会有地址,那么指针变量的地址就可以用二级指针来描述。就是把一个变量的地址放在指针里面,然后再把指针的地址放在二级指针里面。所以就可以通过对二级指针解引用拿到一级指针的地址,对二级指针两次解引用,就拿到变量的地址了。


int main()
{
	int a = 10;
	int* p = &a;
	int** pp = &p;
	printf("%p\n", a);
	printf("%p\n", *p);
	printf("%p\n", **pp);
	return 0;
}

在这里插入图片描述

既然能拿到地址,那么对pp解引用之后修改,也就修改了a的值。


int main()
{
	int a = 10;
	int* p = &a;
	int** pp = &p;
	**pp = 20;
	printf("%d\n", a);
	return 0;
}

在这里插入图片描述

所以在使用二级指针的时候,也可以直接对变量进行修改。

总结

本篇文章就到这里了,希望能给你带来帮助,也希望能够您能够关注编程网的更多内容!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C语言指针原来也可以这样了解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录