【C语言】指针初阶

在这里插入图片描述

正文开始之前,我们要记住一个东西就是:地址=指针

目录

  • 一、指针的解释
  • 二、指针变量和地址
    • 1、取地址操作符
    • 2、指针变量和解引用操作
      • 1、指针变量
      • 2、拆解指针类型
      • 3、解引用操作符
      • 4、注意事项
    • 3、指针变量的大小
    • 4、指针的解引用
    • 5、void*指针
  • 三、指针的运算
    • 1、指针±整数
    • 2、指针 - 指针
    • 3、指针的关系运算
  • 四、野指针
    • 1、野指针形成的原因
    • 2、指针越界访问
    • 3、指针指向的空间释放
  • 五、const 修饰指针
    • 1、const修饰变量
    • 2、const修饰指针变量

一、指针的解释

通俗来讲就是某一数据的位置。因为数据的存储是需要空间的,这个空间会有一个地址,指针就是用来存放这个地址的,以便于后续快速的访问

二、指针变量和地址

1、取地址操作符

在C语⾔中创建变量就是向内存申请空间

#include <stdio.h>
int main()
{int a = 10;return 0;
}

在这里插入图片描述
我们在内存里可以看到在创建变量a的时候申请了一块空间
我们取地址a之后将地址四行显示,发现a存储在了这个地址里,0a就是十六进制下的10
这里我们介绍一下我们的老朋友,&操作符。在以前的学习中,我们在学习scanf函数的时候接触过这个操作符,这个操作符就叫做取地址操作符。
在这里插入图片描述
&a取出的是a所占的四个字节中地址最小的字节的地址,通过计算机的一套算法,它懂得这个数据是整形,会取出剩下的三个地址

(这时候我们对scanf函数的理解也会深一个层次

scanf("%d",&a);

这里的&a就是取出a的地址,将里边的值进行修改)

2、指针变量和解引用操作

1、指针变量

那我们通过取地址操作符(&)拿到的地址是⼀个数值,这个数值有时候需要存储起来,⽅便后期再使⽤,我们会把这样的地址值存放在指针变量中。

#include <stido.h>
int main()
{int a = 10;int *pa = &a;//这样就把取出的a的地址存放到指针pa中了return 0;
}

指针变量也是变量,专门用来存放地址,存放在其中的值都会被认为是地址

2、拆解指针类型

    int a = 10;int *pa = &a;

*说明pa是指针变量,int 说明pa这个指针变量指向的是一个int类型也就是整型类型的对象
当然如果是short类型的对象那么就

short i = 10;
short *pi = &i;

char类型那么就

char j = 10;
char * pj = &j;

3、解引用操作符

#include <stido.h>
int main()
{int a = 10;int *pa = &a;*pa = 20;return 0;
}

这样就把a的值更改为20了

4、注意事项

int*pa
int *pa
int* pa
int * pa

这几个是一样的,表达上没有任何的区别

3、指针变量的大小

#include <stdio.h>
int main()
{printf("%zd\n", sizeof(char *));printf("%zd\n", sizeof(short *));printf("%zd\n", sizeof(int *));printf("%zd\n", sizeof(double *));return 0;
}

指针变量的大小取决于地址的大小,指针变量的大小和类型是⽆关,只要指针类型的变量在相同的平台下,大小都是相同的

4、指针的解引用

#include <stdio.h>
int main()
{int n = 0x12345678;int *pi = &n; *pi = 0; printf("%d",n):return 0;
}
#include <stdio.h>
int main()
{int n = 0x12345678;char *pi =(char*) &n; //强制转化,不然是不可以用char类型的指针来接受int类型的变量的*pi = 0; printf("%d",n);return 0;
}

第一个运行结果
在这里插入图片描述
第二个的运行结果
在这里插入图片描述
在这里插入图片描述
这说明char类型和int类型的访问权限不同,char类型可以访问一个字节,也就是十六进制下的两位数,int类型可以访问四个字节,也就是十六进制下的八位数

5、void*指针

⽆具体类型的指针,也叫泛型指针,可以接受任何类型的地址
但它不能够进行解引用操作,以及指针±整数的运算(下面来说)

三、指针的运算

1、指针±整数

#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = &arr[0];int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);for (i = 0; i < sz; i++){printf("%d ", *(p + i));//p+i 这⾥就是指针+整数}return 0;
}

这里的指针经过加减后是通过单位进行访问的,也就是如果是int类型,那么指针就加了四个字节,char加一个字节,short加两个字节。

2、指针 - 指针

#include <stdio.h>
int my_strlen(char* s)
{char* p = s;while (*p != '\0')// \0 之前的元素为字符串中的元素p++;return p - s;
}
int main()
{printf("%d\n", my_strlen("abc"));return 0;
}

这样就可以算出字符串中的元素个数

3、指针的关系运算

#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };int* p = &arr[0];int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);while (p < arr + sz) //指针的⼤⼩⽐较{printf("%d ", *p);p++;}return 0;
}

四、野指针

1、野指针形成的原因

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

2、指针越界访问

#include <stdio.h>
int main()
{int arr[10] = { 0 };int* p = &arr[0];int i = 0;for (i = 0; i <= 11; i++){//当指针指向的范围超出数组arr的范围时,p就是野指针*(p++) = i;}return 0;
}

3、指针指向的空间释放

#include <stdio.h>
int* test()
{int n = 100;return &n;
}
int main()
{int* p = test();printf("%d\n", *p);return 0;
}

这些原因其实都很常见,也很有规矩,看一下就能看出来是理所应当的,没啥需要解释的
想办法规避它们就行了

五、const 修饰指针

1、const修饰变量

#include <stdio.h>
int main()
{int m = 0;m = 20;//m是可以修改的const int n = 0;n = 20;//n是不能被修改的return 0;
}

被const修饰的变量是不能修改的

2、const修饰指针变量

int * p;//没有const修饰
const int * p;//const 放在*的左边做修饰
int const * p;//const 放在*的左边做修饰
int * const p;//const 放在*的右边做修饰

第二行和第三行实际是一样的。
我的理解是看const修饰的量,被其修饰的量是不能改变的,我们先来看第二行和第三行代码,*p不能改变,*p是变量值,也就是指针指向的那个变量的内容,它是不能够改变的,但p也就是地址,指针本身,是可以改变的。
第四行代码,const修饰p,地址,指针本身,是不能改变的,但指针指向的变量的内容是不能改变的
在这里插入图片描述

分享就到这了~

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

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

相关文章

数据结构:链表的冒泡排序

法一&#xff1a;修改指针指向 //法二 void maopao_link(link_p H){if(HNULL){printf("头节点为空\n");return;}if(link_empty(H)){printf("链表为空\n");return;}link_p tailNULL;while(H->next->next!tail){link_p pH;link_p qH->next;while(q…

CUDA C:核函数、主机函数、设备函数

相关阅读 CUDA Chttps://blog.csdn.net/weixin_45791458/category_12530616.html?spm1001.2014.3001.5482 核函数(Kernel Function)指的是在主机(CPU)调用&#xff08;某些情况下也可以在设备调用&#xff09;&#xff0c;在设备(GPU)上执行的函数&#xff0c;使用__global__…

YOLOv8改进 | Conv篇 | 全新的SOATA轻量化下采样操作ADown(参数量下降百分之二十,附手撕结构图)

一、本文介绍 本文给大家带来的改进机制是利用2024/02/21号最新发布的YOLOv9其中提出的ADown模块来改进我们的Conv模块,其中YOLOv9针对于这个模块并没有介绍,只是在其项目文件中用到了,我将其整理出来用于我们的YOLOv8的项目,经过实验我发现该卷积模块(作为下采样模块)…

liunx前后端分离项目部署

文章目录 1、nginx的安装和自启动2.nginx负载均衡3.前后端项目部署-后端部署4.前后端项目部署-前端部署 1、nginx的安装和自启动 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel1.安装我们nginx所需要的依赖 wget http://nginx.org/download/nginx-1.…

Open3D 点云法向量计算与可视化 (25)

Open3D 点云法向量计算与可视化 (25) 一、算法原理二、算法实现三、可视化显示和长度调节一、算法原理 通常计算点云的法向量可以使用以下两种常见的方法: 最小二乘法(Least Squares Method):该方法通过拟合局部表面的平面来计算法向量。对于给定点周围的邻域,可以通过…

故障排除:Failed to load SQL Modules into database Cluster

PostgreSQL 安装和故障排除 重新安装前的准备工作 在重新安装 PostgreSQL 之前&#xff0c;确保完成以下步骤&#xff1a; 重新卸载 PostgreSQL 并重启电脑。 删除以下目录&#xff1a; C:\Program Files\PostgreSQL\13C:\Users\admin\AppData\Roaming\pgadmin 重启安装过…

【计算机网络】传输层——TCP和UDP详解

文章目录 一. TCP和UDP简介二. UDP 协议详解1. UDP报文格式2. UDP的使用场景 三. TCP 协议详解1. TCP报文格式2. TCP协议的重要机制确认应答&#xff08;保证可靠传输的最核心机制&#xff09;超时重传连接管理&#xff08;三次握手、四次挥手&#xff09;&#xff01;&#xf…

内网设备如何在互联网上能访问

应用场景 设备安装到了客户现场&#xff0c;如果要调试设备&#xff0c;当前的处理方式是技术人员出差到客户现场、让客户开通VPN、让客户安装远程工具&#xff0c;远程到客户计算机上进行调试等方法。人不在家里想远程家里的电脑&#xff0c;当前处理方式就是在家里电脑上安装…

【信息提取】FindSomething 浏览器插件

下载地址 FindSomething 浏览器插件 概述 在网页的源代码或js中找到一些有趣的东西 FindSomething 用于快速在网页的html源码或js代码中提取一些有趣的信息&#xff0c;包括可能请求的资源、接口的url&#xff0c;可能请求的ip和域名&#xff0c;泄漏的证件号、手机号、邮箱…

【Android12】Monkey压力测试源码执行流程分析

Monkey压力测试源码执行流程分析 Monkey是Android提供的用于应用程序自动化测试、压力测试的测试工具。 其源码路径(Android12)位于 /development/cmds/monkey/部署形式为Java Binary # development/cmds/monkey/Android.bp // Copyright 2008 The Android Open Source Proj…

Leetcoder Day21| 回溯理论基础+组合

语言&#xff1a;Java/Go 回溯理论基础 回溯函数也就是递归函数&#xff1b; 所有回溯法的问题都可以抽象为树形结构&#xff1b; 回溯法解决的都是在集合中递归查找子集&#xff0c;集合的大小就构成了树的宽度&#xff0c;递归的深度&#xff0c;都构成的树的深度。 适用的题…

深度学习基础(一)神经网络基本原理

之前的章节我们初步介绍了机器学习相关基础知识&#xff0c;目录如下&#xff1a; 机器学习基础&#xff08;一&#xff09;理解机器学习的本质-CSDN博客 机器学习基础&#xff08;二&#xff09;监督与非监督学习-CSDN博客 机器学习基础&#xff08;四&#xff09;非监督学…

深入理解计算机系统学习笔记

2.3整数运算 有时候会发现两个正数相加会得出一个负数&#xff0c;而比较表达式x<y和比较表达式x-y<0会产生不同的结果。这些属性是由于计算机运算的有限性造成的。理解计算机运算的细微之处能够帮助程序员编写更可靠的代码。 2 .3. 1 无符号加法 原理&#xff1a; 在正…

前端学习---- 前端HTML基本元素的介绍

一&#xff1a;显示相关的HTML基础知识 1. 推荐的前端编写工具 2. VScode的html速写规则&#xff08;从a标签开始再用&#xff09; ①、&#xff01;&#xff1a;代表生成html的基本框架元素 ②、html元素&#xff1a;直接书写html,不需要加<>,按回车会自动生成 ③、{}…

Java之线程池:线程池常用类、接口;线程池执行流程,配置参数,分类

线程池 什么是线程池&#xff1f; 线程池&#xff1a;一种基于池化思想管理和使用线程的机制 线程池常用类和接口 ExecutorService接口&#xff1a;进行线程池的操作访问Executors类&#xff1a;创建线程池的工具类ThreadPoolExecutor及其子类&#xff1a;封装线程池的核心参…

蓝桥杯备战刷题(自用)

1.被污染的支票 #include <iostream> #include <vector> #include <map> #include <algorithm> using namespace std; int main() {int n;cin>>n;vector<int>L;map<int,int>mp;bool ok0;int num;for(int i1;i<n;i){cin>>nu…

【技术分享】使用nginx完成动静分离➕集成SpringSession➕集成sentinel➕集成seata

&#x1f973;&#x1f973;Welcome 的Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于技术点的相关分享吧 目录 &#x1f973;&#x1f973;Welcome 的Huihuis Code World ! !&#x1f973;&#x1f973; 一、 使用nginx完成动静分离 1.下载…

JAVA毕业设计129—基于Java+Springboot+thymeleaf的物业管理系统(源代码+数据库)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootthymeleaf的物业管理系统(源代码数据库)129 一、系统介绍 本项目前后端分离&#xff0c;本系统分为管理员、小区管理员、用户三种角色 1、用户&#xff1a; 登…

一种简易的多进程文件读写器

目录 1. 前言2. 初步实现3. ParallelFileProcessor 1. 前言 在数据清洗场景下&#xff0c;我们可能需要对一个 .jsonl 文件清洗以得到另一个 .jsonl 文件。一种直观的做法就是逐行读取&#xff0c;逐行清洗&#xff0c;然后逐行写入&#xff0c;这一流程的示意图如下&#xff…

【wails】(6):使用wails做桌面应用开发,使用gin+go-chatglm.cpp进行本地模型运行,在windows上运行成功

1&#xff0c;整体架构说明 主要使用&#xff0c;参考的开源项目是&#xff1a; https://github.com/wailsapp/wails 前端项目&#xff1a; https://github.com/Chanzhaoyu/chatgpt-web 运行模型&#xff1a; https://github.com/Weaxs/go-chatglm.cpp 参考代码&#xff1a; h…