『C语言初阶』第七章 -初识指针

news2024/11/26 18:48:35

前言

时隔多日小羊又来给铁汁们更新C语言之初识指针,指针是C语言中一个关键且强大的概念,理解和掌握指针对于编写高效、灵活的程序至关重要。本文将详细解释C语言中的指针,帮助初学者迈出掌握编程世界的第一步。


在这里插入图片描述

一、指针是什么?

  1. 指针是内存中一个最小单元的编号,也就是地址
  2. 一般我们所说的指针,通常是指指针变量,用来存放内存地址的变量

1.内存

程序在运行时候会在内存中被调用,运行时占用内存的空间。
内存就像一栋楼,里面有很多房间,每一户人家(每一块内存)都有一个门牌号,而这个门牌号就相当于内存编号,我们就可以通过编号找到相对应的内存(值)。
编号也被称为地址,不同内存块所对应的地址也不一样。

2.指针变量

指针变量也是一种变量,只不过是用来存储地址的变量
我们可以通过&(取地址操作符)取出变量的内存起始地址,把该地址存放到一个变量中,这个变量就是指针变量

#include<stdio.h>
int main()
{
	int a = 5;
	int* p = &a;//取出a的地址存放到变量p中
	printf("%p\n", &a);
	printf("%p", p);
	return 0;
}

在这里插入图片描述

总结:指针是一个变量,但它存储的是另一个变量的内存地址,而不是直接存储数据本身。可以将指针看作是数据的"门牌号码",通过它可以找到内存中存储的实际数据。

3.指针大小

在32位电脑上,地址是32个0或者1组成二进制序列,那地址就是32b(位)=4B(字节)的空间来存储,所以一个指针变量的大小就是4个字节。
相应的在64位机器上,64b=8B,一个指针变量大小就是8个字节。

总结:
1. 指针是用来存放地址的,地址是唯一标识一块内存单元的。
2. 指针大小在32位平台上是4个字节,在64位平台是8个字节。


二、指针类型

指针变量是变量,变量有很多类型,那指针变量的类型也是如此。
当我们需要指向不同类型的变量时,就需要创建不同类型的指针变量。

	char* p1 = NULL;//创建一个char类型的指针,并初始化为空指针
	int* p2 = NULL;//创建一个int类型的指针,并初始化为空指针
	short* p3 = NULL;
	long* p4 = NULL;
	float* p5 = NULL;
	double* p6 = NULL;

所以指针的定义方式为:类型 + * = 值。

解读:

  1. char*类型指针是为了存放char类型变量的地址
  2. int*类型指针是为了存放int类型变量的地址
  3. double*类型指针是为了存放double类型变量的地址

注意:
指针大小与指针类型无关,指针大小与计算机(32位或者64位有关)

1.指针类型的作用

从上面代码可知,不同类型指针大小相同,那么指针类型的意义是什么呢?

用法示例

#include <stdio.h>
int main()
{
	int n = 10;
	char* p1 = (char*)&n;//将int类型地址强制转化为char类型
	int* p2 = &n;
 
	printf("%p\n", &n);
	printf("%p\n", p1);
	printf("%p\n", p1 + 1);
	printf("%p\n", p2);
	printf("%p\n", p2 + 1);
	return  0;
}

在这里插入图片描述

我们发现:
当指针为char类型时,指针+1,步长为1
当指针为int
类型时,指针+1,步长为4

总结:不同类型的指针变量决定了指针向前或向后走一步有多大(距离),即步长。

2.指针的解引用

我们知道,指针保存内存的地址,那指针的作用是什么呢?
我们可以通过指针保存的地址,来访问内存中的目标变量,并将其修改,这就需要使用指针的解引用操作

用法示例

#include <stdio.h>
int main()
{
	int n = 0x11223344;
	char* p1 = (char*)&n;
	int* p2 = &n;
	*p1 = 0;   
	*p2 = 0;   
	printf("%#x\n", n);
	printf("%#x\n", p1);
	return 0;
}

在这里插入图片描述

分析:
因为p2是int类型指针变量,所以能访问四个字节的空间,*p2=0,将n的值修改为0;
但是p1是char类型指针变量,所以只能访问一个字节的空间,那为何又是修改地址中的44而不是11呢,后面文章会详解大小端的知识。

总结:

  1. 指针的类型决定指针加减整数时所跳过的步长
  2. 指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)

三、野指针

概念:野指针就是指针的位置是不可知的(随机的、不正确的、没有正确限制的)指针。
野指针很危险,它访问的空间不可知,从而导致出现的可能情况有:

  1. 指针未初始化
  2. 指针越界或者非法访问
  3. 指针指向的空间被释放了(例:局部变量)

用法示例

#include <stdio.h>
int main()
{
	//1>:
	int* p1;
	*p1 = 5;
	//此时p1就是一个野指针。

	//2>:
	int arr[10] = { 0 };
	int i = 0;
	int* p2 = arr;//p指向数组的首地址
	for (i = 0; i < 11; i++)
	{
		*(p2++)=i;
	}
	//当p2指向的空间超过数组的最后一个元素时,指针就非法访问,即越界访问了未知空间。
	//此时p2是野指针。

	//3>:
	int j = 0;
	for (j = 0; j < 5; j++)
	{
		int a = 5;
		a += 1;
	}
	int* p3 = &a;//当循环结束之后,局部变量a向内存申请的空间就被释放了。
	//此时p3指针指向的空间就是已经被释放掉的空间。p3就是野指针。

	return 0;
}

如何规避野指针

  • 指针初始化
  • 小心指针越界
  • 指针指向空间释放及时置NULL
  • 避免返回局部变量的地址
  • 指针使用之前检查有效性

四、指针的运算

1.指针加减整数

用法示例

例:打印一维数组

#include<stdio.h>
int main()
{
	int arr[5] = { 1,2,3,4,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i = 0;
	int* p = arr;
	for (i = 0; i < 5; i++)
		printf("%d ", *p + i);
	return 0;
}

2.指针-指针

指针减指针可以用来计算字符数组的长度或字符串的长度

用法示例

#include <stdio.h>
int my_strlen(char* s)
{
	char* p = s;
	while (*p != '\0')
		p++;
	return p - s;
}
int main()
{
	char str[] = "hello world";
	int len = my_strlen(str);
	printf("%d", len);
	return 0;
}

3.指针的关系运算

标准规定:
允许指向数组元素的指针与指针数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。


五、二级指针

指针变量也是变量,变量有地址,那么指针变量的地址存放在哪里?
这时候就来了解二级指针!

#include <stdio.h>
int main()
{
	int a = 10;
	int* p1 = &a;
	int** p2 = &p1;//p2就是二级指针,指向p1
	**p2 = 6;
	printf("%d", a);
	return 0;
}

在这里插入图片描述
a的地址存放在p1中,p1的地址存放在p2中
p1是一级指针,而p2是二级指针
**p2=6通过第一次解引用找到p1,再第二次解引用找到a,将其修改为6

以此还有三级指针和其他多级指针,常见的就是一级和二级指针


指针的注意事项

  • 指针操作前应该初始化,避免出现未定义行为。
  • 指针可以进行比较操作,但仅在指向同一数组中的元素时才有意义。
  • 避免野指针(指向未知内存区域的指针)的使用,这可能导致程序崩溃。

结论:

初学者理解指针是学习C语言的重要一步,它使得程序可以更加灵活和高效地操作内存。通过掌握指针的基本概念、操作和用途,可以构建出更加复杂和强大的C语言程序。逐步练习并在实际项目中应用指针,将有助于加深对指针的理解和熟练掌握。


在这里插入图片描述
小羊希望本文对初学者理解C语言中的指针概念提供了一些帮助。在进一步学习过程中,还请查阅相关文档和示例以加深理解,咱们下期再见~~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/858916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

无涯教程-Perl - int函数

描述 此函数返回EXPR的整数元素,如果省略则返回$_。 int函数不进行舍入。如果需要将值四舍五入为整数,则应使用sprintf。 语法 以下是此函数的简单语法- int EXPRint返回值 此函数返回EXPR的整数部分。 例 以下是显示其基本用法的示例代码- #!/usr/bin/perl$int_valint…

PromQL实现Actuator获取的JVM指标的Full GC次数监控

Spring Boot 版本需要2.0.0或更高版本。 添加Micrometer Prometheus registry依赖: <dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId> </dependency>在application.properties中开…

哪个牌子的运动耳机好、最好的运动耳机推荐

在当今快节奏的生活中&#xff0c;运动已经成为许多人追求健康与活力的重要组成部分。而在运动过程中&#xff0c;一款出色的运动耳机不仅能为我们提供激励和动力&#xff0c;还能让我们沉浸在音乐的世界中&#xff0c;享受极致的运动体验。然而&#xff0c;市场上琳琅满目的运…

[LeetCode - Python] 278.第一个错误的版本(Easy)

题目&#xff1a; 278.第一个错误的版本&#xff08;Easy&#xff09; 代码&#xff1a; # 常用的 左闭右开&#xff0c;二分法&#xff0c;要当心判断条件 到底是True还是False # The isBadVersion API is already defined for you. # def isBadVersion(version: int) -&g…

【Spring security 解决跨域】

security 跨域 概述方案方案一方案二方案三方案四 主页传送门&#xff1a;&#x1f4c0; 传送 概述 Spring Security是一个功能强大且高度可定制的&#xff0c;主要负责为Java程序提供声明式的身份验证和访问控制的安全框架。其前身是Acegi Security,后来被收纳为Spring的一个…

hcip的BGP实验

题目 拓扑图 思路&#xff1a; 1、给各个设备配置IP地址及环回接口 2、配置R2、R3、R4&#xff0c;三个设备的OSPF环境 3、将R1、R2、R3、R4、R5建立BGP对等体关系 4、建临时&#xff0c;将源地址也修改为环回接口 5、宣告时&#xff0c;将BGP路由传递给本地的邻居时修改下…

mysql一些统计实用函数

文章目录 一对多&#xff0c;多的一端只查询最新数据YEAR 年份函数MONTH 月份函数QUARTER 季度函数往前递推十年往后递推十年查询去年12月份统计身份证户籍所在地人数 一对多&#xff0c;多的一端只查询最新数据 ROW_NUMBER() over(PARTITION BY evt_id ORDER BY evt_node_rec…

挖洞小技巧

挖洞小技巧 1. Google语法1.1. 基础语法1.2. 操作符 2. 寻找漏洞2.1. SQL注入2.1.1. 不带公司2.1.2. 带公司2.1.3. 如何测试 2.2. 后台管理漏洞2.2.1. 查询单个网站2.2.2. 常见后台管理路径 2.3. 支付漏洞2.4. 文件上传漏洞2.5. 查找文件类型2.6. 敏感信息泄露 3. 刷分 1. Goog…

分享讨论学习IT上培训班有用吗?个人感悟

不知不觉一入行2年有余&#xff0c;回顾自己转行的学习历程&#xff0c;历历在目。我对培训机构好感度为0&#xff01; IT分行业发展未来&#xff0c;前景还是很好的&#xff0c;但是入门方向很重要&#xff0c;要选择什么方向去学学完才有钱景&#xff0c;需要自己 &#xff0…

直接在html中引入Vue.js的cdn来实现Vue3的组合式API

Vue3的组合式API是使用setup函数来编写组件逻辑的。setup函数是Vue3中用于替代Vue2的选项API&#xff08;如data、methods等&#xff09;的一种方式。在setup函数中&#xff0c;你可以访问到一些特殊的响应式对象&#xff0c;并且可以返回一些可以在模板中使用的数据、方法等。…

[计算机入门] 使用输入法

2.12 使用输入法 输入法是一种计算机软件&#xff0c;它允许用户通过键盘在计算机上输入文字和符号。输入法主要用于处理中文、日语、韩语等语言中较为复杂的字形和字音&#xff0c;使用户能够快速、方便地输入这些文字。 在使用输入法时&#xff0c;用户可根据输入法提供的提…

百数私有云模式

百数私有云模式是百数低代码平台中带有独立服务器的模式 简介&#xff1a;百数的私有化部署是搭建在真正的“私有云”上&#xff0c;拥有独立的服务器&#xff0c;ip&#xff0c;存储&#xff0c;可用企业自己的域名&#xff0c;使用企业自己的Logo&#xff0c;通过企业自身设…

Linux--计算CPU算力

#include <iostream> #include <unistd.h> #include <signal.h>using namespace std;int count 0;void catchSig(int signum) {//cout<< "进程捕捉到了一个信号&#xff0c;正在处理中&#xff1a; "<< signum << " pid: …

【JavaScript】match用法 | 正则匹配

match正则匹配 var e "www.apple.com:baidu.com" var match e.match(/com/g) console.log("match: "match);> "match: com,com"match返回值问题 match的返回值是一个数组 数组的第0个元素是与整个正则表达式匹配的结果 数组的第1个元素是…

展会直击丨虹科实车上展,展会首日汽车行业解决方案备受青睐!

虹科特装展 8月9日&#xff0c;上海汽车测试展和IME在上海世博展览馆拉开序幕&#xff0c;虹科携众多汽车相关解决方案在【3002】展位与各位见面。 开展首日 虹科展位现场实况一览 ↓↓↓↓↓↓ 虹科展位前人头攒动&#xff0c;实车展示自动驾驶等汽车相关解决方案引来各位客…

如何让PPT看起来规整统一

一、字体 常见问题&#xff1a;字体风格太多、文字可读性差、页面风格不匹配 1.使用文字的几个原则 &#xff08;1&#xff09;一份PPT最多使用两种中文字体 比如首页大标题宋体、正文黑体、其他页标题黑体加粗。通过粗细、字号、不同颜色背景等区分不同层级。注意 使用粗体…

opencv基础57-模板匹配cv2.matchTemplate()->(目标检测、图像识别、特征提取)

OpenCV 提供了模板匹配&#xff08;Template Matching&#xff09;的功能&#xff0c;它允许你在图像中寻找特定模板&#xff08;小图像&#xff09;在目标图像中的匹配位置。模板匹配在计算机视觉中用于目标检测、图像识别、特征提取等领域。 以下是 OpenCV 中使用模板匹配的基…

怎么学习机械学习相关的技术? - 易智编译EaseEditing

学习DOM&#xff08;文档对象模型&#xff09;相关技术是成为前端开发者的关键一步&#xff0c;因为DOM是用于操作和控制网页内容的基础。以下是学习DOM相关技术的步骤和方法&#xff1a; 了解基础知识&#xff1a; 首先&#xff0c;了解什么是DOM&#xff0c;它如何表示HTML…

Python小白入门:文件、异常处理和json格式存储数据

这里写自定义目录标题 所用资料 一、从文件中读取数据1.1 读取整个文件1.2 文件路径1.3 逐行读取1.4 创建一个包含文件各行内容的列表1.5 使用文件的内容1.6 包含一百万位的大型文件1.7 圆周率值中包含你的生日吗练习题 二、写入文件2.1 写入空文件2.2 写入多行2.3 附加到文件练…

Mask RCNN网络结构以及整体流程的详细解读

文章目录 1、概述2、Backbone3、RPN网络3.1、anchor的生成3.2、anchor的标注/分配3.3、分类预测和bbox回归3.4、NMS生成最终的anchor 4、ROI Head4.1、ROI Align4.2、cls head和bbox head4.3、mask head 1、概述 Mask RCNN是在Faster RCNN的基础上增加了mask head用于实例分割…