C语言——指针初阶(一)

news2024/11/29 8:03:54

目录

一.什么是指针???

        指针是什么?

        指针变量:

        总结:

        总结:

二.指针和指针类型

指针+-整数:

        总结:

指针的解引用

总结:

三.野指针

如何规避野指针

往期回顾:


一.什么是指针???

        指针是什么?

        指针理解的2个要点:

       1. 指针是内存中一个最小单元的编号,也就是地址

       2. 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量

        总结:指针就是地址,口语中说的指针通常指的是指针变量。

        指针变量:

        我们可以通过&(取地址操作符)取出变量的内存其实地址,把地址可以存放到一个变量中,这个变量就是指针变量。

        比如:

#include <stdio.h>
int main()
{
 int a = 10;//在内存中开辟一块空间
 int *p = &a;//这里我们对变量a,取出它的地址,可以使用&操作符。
    //a变量占用4个字节的空间,这里是将a的4个字节的第一个字节的地址存放在p变量
中,p就是一个之指针变量。
 return 0;
}

p就是一个指针变量,而*p叫做指针变量的解引用,指向p指针所指的对象

        总结:

        经过仔细的计算和权衡我们发现一个字节给一个对应的地址是比较合适的。 对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电 平(低电压)就是(1或者0);

        那么32根地址线产生的地址就会是:

00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000001 ...

11111111 11111111 11111111 11111111  

        这里就有2的32次方个地址。 每个地址标识一个字节,那我们就可以给 (2^32Byte == 2^32/1024KB == 2^32/1024/1024MB==2^32/1024/1024/1024GB == 4GB)4G的空闲进行编址。 

        这里我们就明白: 在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以 一个指针变量的大小就应该是4个字节。 那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地 址。

        总结:

        指针是用来存放地址的,地址是唯一标示一块地址空间的。 指针的大小在32位平台是4个字节,在64位平台是8个字节。

二.指针和指针类型

        当有这样的代码:

int num = 10;
p = &num;

        要将&num(num的地址)保存到p中,我们知道p就是一个指针变量,那它的类型是怎样的呢? 我们给指针变量相应的类型。

char  *pc = NULL; int   *pi = NULL; short *ps = NULL; long  *pl = NULL; float *pf = NULL; double *pd = NULL;

        这里可以看到,指针的定义方式是: type + * 。

        其实: char* 类型的指针是为了存放 char 类型变量的地址。 short* 类型的指针是为了存放 short 类型变量的地址。 int* 类型的指针是为了存放 int 类型变量的地址。

        那指针类型的意义是什么?

        我们接着讨论:

指针+-整数:

        如下代码:

#include <stdio.h>
//演示实例
int main()
{
 int n = 10;
 char *pc = (char*)&n;
 int *pi = &n;
 
 printf("%p\n", &n);
 printf("%p\n", pc);
 printf("%p\n", pc+1);
 printf("%p\n", pi);
 printf("%p\n", pi+1);
 return  0;
}

根据运行结果我们发现:当指针变量的类型是char型的时候,指针+1,指针向后移动一位,当是int型的时候,指针+1,指针向后移动4位。

        总结:

        指针的类型决定了指针向前或者向后走一步有多大(距离)。

指针的解引用

//演示实例
#include <stdio.h>
int main()
{
 int n = 0x11223344;
 char *pc = (char *)&n;
 int *pi = &n;
 *pc = 0;   //重点在调试的过程中观察内存的变化。
 *pi = 0;   //重点在调试的过程中观察内存的变化。
 return 0;
}

通过调试中窗口-内存-找到n的地址,接着进行调试

当代码运行到1399行的时候,n的地址第一位变成00;

当代码运行到1400行的时候,n的地址前四位全变成00;

总结:

        指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。简单来说,指针变量体现了访问指针内存的一种视角,想怎样访问内存应该找相应的指针变量。

        比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节。

三.野指针

        野指针成因:

①指针未初始化

#include <stdio.h>
int main()
{ 
 int *p;//局部变量指针未初始化,默认为随机值
    *p = 20;
 return 0;
}

②指针越界访问

int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;
	int i = 0;
	for (i = 0; i <= 10; i++)
	{
		printf("%d", *p);//当i=10的时候再运行出现越界访问
		p++;
	}
	return 0;
}

如何规避野指针

1. 指针初始化

2. 小心指针越界

3. 指针指向空间释放即使置NULL(空指针——专门用来初始化指针的)

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

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

#include <stdio.h>
int main()
{
    int *p = NULL;
    //....
    int a = 10;
    p = &a;
    if(p != NULL)
   {
        *p = 20;
   }
    return 0;
}

往期回顾:

C语言函数递归经典题型——汉诺塔问题-CSDN博客

C语言——数组基本知识(二)-CSDN博客

C语言——数组基本知识(一)-CSDN博客

C语言——数组逐元素操作练习-CSDN博客

C语言编程练习:验证哥德巴赫猜想 进制转换 rand函数-CSDN博客

C语言——函数基本知识(三)-CSDN博客

C语言——函数基本知识(二)-CSDN博客

C语言 ——函数基本知识(一)-CSDN博客

C语言——二分法查找讲解-CSDN博客

C语言算法经典基础题型——求一个数的回文数(两种方法)_编程计算一个数的回数-CSDN博客

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

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

相关文章

游戏引擎学习第22天

移除 DllMain() 并成功重新编译 以下是对内容的详细复述与总结&#xff1a; 问题和解决方案&#xff1a; 在编译过程中遇到了一些问题&#xff0c;特别是如何告知编译器不要退出程序&#xff0c;而是继续处理。问题的根源在于编译过程中传递给链接器的参数设置不正确。原本尝试…

Paper -- 建筑物高度估计 -- 使用街景图像、深度学习、轮廓处理和地理空间数据的建筑高度估计

基本信息 论文题目: Building Height Estimation using Street-View Images, Deep-Learning, Contour Processing, and Geospatial Data 中文题目: 使用街景图像、深度学习、轮廓处理和地理空间数据的建筑高度估计 作者: Ala’a Al-Habashna 作者单位: 加拿大统计局特别商业项…

如何为 ext2/ext3/ext4 文件系统的 /dev/centos/root 增加 800G 空间

如何为 ext2/ext3/ext4 文件系统的 /dev/centos/root 增加 800G 空间 一、引言二、检查当前磁盘和分区状态1. 使用 `df` 命令检查磁盘使用情况2. 使用 `lsblk` 命令查看分区结构3. 使用 `fdisk` 或 `parted` 命令查看详细的分区信息三、扩展逻辑卷(如果使用 LVM)1. 检查 LVM …

命令行使用ssh隧道连接远程mysql

本地电脑A 跳板机B 主机2.2.2.2 用户名 B ssh端口号22 登录密码bbb 远程mysql C 地址 3.3.3.3 端口号3306 用户名C 密码ccc A需要通过跳板机B才能访问C; navicat中配置ssh可以实现在A电脑上访问C 如何实现本地代码中访问C呢? # 假设本地使…

Vatee万腾平台:以数字之名,筑企业未来之路

在当今这个瞬息万变的数字化时代&#xff0c;企业若想在激烈的市场竞争中脱颖而出&#xff0c;就必须紧跟时代步伐&#xff0c;实现全面数字化转型。而Vatee万腾平台&#xff0c;正是这样一款能够帮助企业迈向数字化未来的强大工具。 Vatee万腾平台&#xff0c;作为数字化转型…

深度学习——损失函数与BP算法

一、损失函数 1. 线性回归损失函数 1.1 MAE损失 MAE&#xff08;Mean Absolute Error&#xff0c;平均绝对误差&#xff09;通常也被称为 L1-Loss&#xff0c;通过对预测值和真实值之间的绝对差取平均值来衡量他们之间的差异。MAE的公式如下&#xff1a; 其中&#xff1a; 是…

机器学习-决策树(ID3算法及详细计算推导过程)

决策树是一种基于树结构进行决策的机器学习算法 &#xff0c;以下是关于它的详细介绍&#xff1a; 1.基本原理 决策树通过一系列的条件判断对样本进行分类或预测数值。它从根节点开始&#xff0c;根据不同的属性值逐步将样本划分到不同的分支&#xff0c;直到到达叶节点&…

【AI系统】LLVM 架构设计和原理

LLVM 架构设计和原理 在上一篇文章中&#xff0c;我们详细探讨了 GCC 的编译过程和原理。然而&#xff0c;由于 GCC 存在代码耦合度高、难以进行独立操作以及庞大的代码量等缺点。正是由于对这些问题的意识&#xff0c;人们开始期待新一代编译器的出现。在本节&#xff0c;我们…

浅谈网络 | 应用层之HTTPS协议

目录 对称加密非对称加密数字证书HTTPS 的工作模式重放与篡改 使用 HTTP 协议浏览新闻虽然问题不大&#xff0c;但在更敏感的场景中&#xff0c;例如支付或其他涉及隐私的数据传输&#xff0c;就会面临巨大的安全风险。如果仍然使用普通的 HTTP 协议&#xff0c;数据在网络传输…

基于 JNI + Rust 实现一种高性能 Excel 导出方案(上篇)

每个不曾起舞的日子&#xff0c;都是对生命的辜负。 ——尼采 一、背景&#xff1a;Web 导出 Excel 的场景 Web 导出 Excel 功能在数据处理、分析和共享方面提供了极大的便利&#xff0c;是许多 Web 应用程序中的重要功能。以下是一些典型的场景&#xff1a; 数据报表导出&am…

最新Linux下使用conda配置Java23或17保姆教程(附赠安装包)

随着技术的不断进步&#xff0c;越来越多的开发者开始在Linux环境下进行Java应用的开发。Java 17作为长期支持版本&#xff08;LTS&#xff09;&#xff0c;提供了许多新特性和性能改进。当然现在最新的是Java23&#xff0c;这个还作为实验版本未广泛使用。对于需要管理多个编程…

RHEL7+Oracle11.2 RAC集群-多路径(multipath+udev)安装步骤

RHEL7Oracle11.2RAC集群-多路径&#xff08;multipathudev&#xff09;安装 配置虚拟存储 使用StarWind Management Console软件&#xff0c;配置存储 dggrid1: 1g*3 Dggrid2: 1g*3 Dgsystem: 5g*1 系统表空间&#xff0c;临时表空间&#xff0c;UNDO&#xff0c;参数文件…

PyTorch 模型转换为 ONNX 格式

PyTorch 模型转换为 ONNX 格式 在深度学习领域&#xff0c;模型的可移植性和可解释性是非常重要的。本文将介绍如何使用 PyTorch 训练一个简单的卷积神经网络&#xff08;CNN&#xff09;来分类 MNIST 数据集&#xff0c;并将训练好的模型转换为 ONNX 格式。我们还将讨论 PTH …

VM Virutal Box的Ubuntu虚拟机与windows宿主机之间设置共享文件夹(自动挂载,永久有效)

本文参考如下链接 How to access a shared folder in VirtualBox? - Ask Ubuntu &#xff08;1&#xff09;安装增强功能&#xff08;Guest Additions&#xff09; 首先&#xff0c;在网上下载VBoxGuestAdditions光盘映像文件 下载地址&#xff1a;Index of http://…

CA系统(file.h---申请认证的处理)

#pragma once #ifndef FILEMANAGER_H #define FILEMANAGER_H #include <string> namespace F_ile {// 读取文件&#xff0c;返回文件内容bool readFilename(const std::string& filePath);bool readFilePubilcpath(const std::string& filePath);bool getNameFro…

【Git】Git 命令参考手册

目录 Git 命令参考手册1. 创建仓库1.1 创建一个新的本地仓库1.2 克隆一个仓库1.3 克隆仓库到指定目录 2. 提交更改2.1 显示工作目录中已修改的文件&#xff0c;准备提交2.2 将文件添加到暂存区&#xff0c;准备提交2.3 将所有已修改的文件添加到暂存区&#xff0c;准备提交2.4 …

【Linux系列】Chrony时间同步服务器搭建完整指南

1. 简介 Chrony是一个用于Linux系统的高效、精准的时间同步工具&#xff0c;通常用于替代传统的NTP&#xff08;Network Time Protocol&#xff09;服务。Chrony不仅在系统启动时提供快速的时间同步&#xff0c;还能在时钟漂移较大的情况下进行及时调整&#xff0c;因此广泛应…

数据库日志

MySQL中有哪些日志 1&#xff0c;redo log重做日志 redo log是物理机日志&#xff0c;因为它记录的是对数据页的物理修改&#xff0c;而不是SQL语句。 作用是确保事务的持久性&#xff0c;redo log日志记录事务执行后的状态&#xff0c;用来恢复未写入 data file的已提交事务…

【vue for beginner】Vue该怎么学?

&#x1f308;Don’t worry , just coding! 内耗与overthinking只会削弱你的精力&#xff0c;虚度你的光阴&#xff0c;每天迈出一小步&#xff0c;回头时发现已经走了很远。 vue2 和 vue3 Vue2现在正向vue3逐渐更新中&#xff0c;官方vue2已经不再更新。 这个历程和当时的pyt…

【Ubuntu 24.04】How to Install and Use NVM

参考 下载 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash激活 Activate NVM: Once the installation script completes, you need to either close and reopen the terminal or run the following command to use nvm immediately. exp…