C语言小白急救 指针初级讲解(四千字教程)

系列文章目录

C语言小白急救 表达式求值(两千字教程)
C语言小白急救 操作符详解(8千字保姆级教程)
C语言小白急救 扫雷游戏(万字保姆级教程)
C语言小白急救 使用C语言编写‘三子棋‘

文章目录

  • 系列文章目录
    • [C语言小白急救 表达式求值(两千字教程)](https://editor.csdn.net/md/?articleId=132312494) [C语言小白急救 操作符详解(8千字保姆级教程)](https://editor.csdn.net/md/?articleId=132269381) [C语言小白急救 扫雷游戏(万字保姆级教程)](https://editor.csdn.net/md/?articleId=132259410) [C语言小白急救 使用C语言编写‘三子棋‘](https://mp.csdn.net/mp_blog/creation/editor/132240688)
  • 前言
  • 一、指针介绍
    • 1.指针介绍
    • 2.指针变量
  • 二、 指针和指针类型
    • 1.指针的解引用
    • 2.指针与整数
  • 三、野指针
    • 1. 野指针成因
    • 2.如何规避野指针
  • 四、指针和数组
  • 五、指针的运算
  • 1.指针+- 整数
  • 2.指针-指针
  • 3.指针的关系运算
  • 六、二级指针
  • 七、指针数组
  • 总结


前言


一、指针介绍

1.指针介绍

(1)指针是内存中一个最小内存单元(字节)的一个编号,也就是地址(我们平常所用的二进制位就是其中的一种表现形式)
(2)我们平常口语中所说的指针一般指的是指针变量,是用于存放地址的
总结:指针就是地址,我们平常口语中所说的指针其实是指针变量

2.指针变量

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

在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节。
那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。
总结:
指针变量是用来存放地址的,地址是唯一标示一个内存单元的。
指针的大小在32位平台是4个字节,在64位平台是8个字节

二、 指针和指针类型

我们都知道,变量有不同的类型,整形,浮点型等。那指针有没有类型呢?
准确的说:有的。
那么,为什么要有指针类型呢,它有什么作用?

1.指针的解引用

指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
比如:

    int a = 0x11223344;//将a的地址设置为11223344int* m = &a;//设置一个指针变量来存储a的地址*m = 0;//解应用m,对m中的地址进行操作,使地址变为0

在这里插入图片描述
当Int* 改为 char* 时

int a = 0x11223344;//将a的地址设置为11223344char* m = (char*)&a;//设置一个指针变量来存储a的地址//因为a是int型的若想要用char作为指针变量,需要转换*m = 0;//解应用m,对m中的地址进行操作,使地址变为0

在这里插入图片描述

所以说,不同的指针类型,对指针解引用的时候的权限也不同

2.指针与整数

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

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;
}

在这里插入图片描述
从结果(16进制)可以看出,char* 类型的,向后移动了1个字节;int* 类型的向后移动了4个字节。这样的区别在于我们对元素进行比如遍历之类的操作中十分有用
比如:

int arr[] = { 1,2,3,4 };int* m = arr;char* n = (char*)arr;int i = 0;for (i=0;i<4;i++){printf("%p ",m + i);}printf("\n");for (i = 0; i < 4; i++){printf("%p ", n + i);}

在这里插入图片描述
除打印首元素地址外,一共执行了3次,char* 类型的,向后移动了3个字节,离到第二个元素的位置还差一个字节;int* 类型的向后移动了8个字节,已经到了第三个元素的位置;如果是对元素进行遍历,那么肯定int* 类型更快。

三、野指针

概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

1. 野指针成因

(1)指针未初始化

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

这种情况编译器会报错,无法执行
(2) 指针越界访问

int arr[10] = { 0 };int* p = arr;for (int i=0;i<=10;i++)//循环了11次,但数组中只有十个数{*p = 1;p++;}

这种情况下属于越界访问,编译器会报错,无法执行

(3) 指针指向的空间释放

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

函数 test() 在作用后以及将空间释放,当时你还知道他的地址,这就属于非法访问,也是野指针的一种。比如说:一个陌生人不知道从哪里知道了你的电话号码,整天打电话给你。

2.如何规避野指针

  1. 指针初始化
  2. 小心指针越界
  3. 指针指向空间释放,及时置NULL
  4. 避免返回局部变量的地址
  5. 指针使用之前检查有效性(指针没有明确指向是设为空NULL)

四、指针和数组

大部分情况下数组名表示的是数组首元素的地址
2个例外:
(1)sizeof(数组名),数组名单独放在sizeof内部,此时数组名表示整个数组,计算的是整个数组的大小,单位是字节
(2)&数组名,此时数组名表示整个数组,取出的是整个数组的地址,数组的地址和数组首元素地址,值是一样的,但是类型和意义不一样
例1:数组名表示的是数组首元素的地址

int arr[] = {1,2,3,4,5 };
printf("%p\n",arr);
printf("%p\n",&arr[0]);

在这里插入图片描述
打印出的地址一样,所以数组名是数组首元素的地址。
例2:sizeof(数组名)

int arr[] = { 1,2,3,4,5 };printf("%zd\n",sizeof(arr));

在这里插入图片描述
例3:&数组名

int arr[] = { 1,2,3,4,5 };printf("%p\n", &arr);printf("%p\n", &arr+1);

在这里插入图片描述

五、指针的运算

1.指针± 整数

指针±整数是跳过多少个元素

    int arr[] = { 1,2,3,4,5 };int* p = arr;//数组名的是数组首元素的地址//arr+i == p+i//*(arr+i) == *(p+i) == arr[i]//*(arr+i) == arr[i]//*(i+arr) == i[arr]for (int i=0;i<5;i++){printf("%d ",*(p+i));//p+i 是数组中下标为i的值//p+i 是跳过了i*sizeof(int)个字节}

在这里插入图片描述

2.指针-指针

指针相减的前提:指向同一块区域,指针类型相同
指针相减的结果的绝对值是中间的元素个数

    int arr[10] = { 0 };//指针相减的前提:指向同一块区域,指针类型相同printf("%d",&arr[9]-&arr[0]);//指针相减的结果是中间的元素个数

在这里插入图片描述

3.指针的关系运算

size_t My_strelen(char* str)
{char* a = str;//设置一个指针来存储首地址while (*str != '\0')//这个地址存储的值不等于'\0'{str++;//指针+1}return str-a;
}int main()
{char arr[] = "abcdef";size_t count=My_strelen(arr);printf("%zd ",count);return 0;
}

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

简单点讲就是尽量从前往后比较,不要从后往前

六、二级指针

二级指针就是用来存储一级指针的地址的

int a = 10;int* p = &a;//p是指针变量,一级指针变量int** pp = &p;//pp是指针变量,二级指针变量//二级指针变量前面有两颗* 是指这个二级指针变量指向一个指针变量的//二级指针需要解引用两次

七、指针数组

指针数组是数组,里面存放的是指针,根据数组内存放的不同的指针类型,可以分为不同类型的指针数组;如int * char* 等

应用:

    int arr1[] = { 1,2,3,4 };int arr2[] = { 4,5,6,7 };int arr3[] = { 7,8,9,10 };int* arr[] = {arr1,arr2,arr3};for (int i = 0; i < 3;i++)//访问arr1 arr2 arr3{for (int j = 0; j < 4;j++)//访问三数组中的元素{printf("%d ",arr[i][j]);}printf("\n");}

总结

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

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

相关文章

iOS_Crash报告的组成结构

崩溃报告结构如下&#xff0c;每个部分都包含可帮助定位崩溃位置的信息&#xff1a; 1. Header 描述崩溃发生的环境&#xff0c;包含设备、系统、时间、版本等信息。如&#xff1a; Incident Identifier: 6156848E-344E-4D9E-84E0-87AFD0D0AE7B CrashReporter Key: 76f2fb…

企业微信电脑端开启chrome调试

首先&#xff1a; Mac端调试开启的快捷键&#xff1a;control shift command d Window端调试开启的快捷键: control shift alt d 这边以Mac为例&#xff0c;我们可以在电脑顶部看到调试的入口&#xff1a; 然后我们点击 『浏览器、webView相关』菜单&#xff0c;勾选上…

攻防世界-command_execution

原题 解题思路 题目告诉了&#xff0c;这可以执行ping命令且没WAF&#xff0c;那就可以在ping命令后连接其他命令。 服务器一般使用Linux&#xff0c;在Linux中可使用“&”连接命令。 ping 127.0.0.1&find / -name "flag*" ping 127.0.0.1&cat /home/f…

Spring(四):Spring Boot 的创建和使用

关于Spring之前说到&#xff0c;Spring只是思想&#xff08;核心是IOC、DI和AOP&#xff09;&#xff0c;而具体的如何实现呢&#xff1f;那就是由Spring Boot 来实现&#xff0c;Spring Boot究竟是个啥呢&#xff1f; 什么是Spring Boot&#xff0c;为什么要学Spring Boot Sp…

Android Studio实现解析HTML获取图片URL将图片保存到本地

目录 效果activity_main.xmlMainActivityImageItemImageAdapter 效果 项目本来是要做成图片保存到手机然后读取数据后瀑布流展示&#xff0c;但是有问题&#xff0c;目前只能做到保存到手机 activity_main.xml <?xml version"1.0" encoding"utf-8"?…

ARM DIY 硬件调试

文章目录 前言加热台焊接热风枪吹焊电烙铁补焊电源调试SD 卡座调试DRAM 电路调试串口电路调试SOC 调试成品 前言 之前打样的几块 ARM 板&#xff0c;一直放着没去焊接。今天再次看到&#xff0c;决定把它焊起来。 加热台焊接 为了提高焊接效率&#xff0c;先使用加热台焊接…

Qt关于hex转double,或者QByteArray转double

正常的00 ae 02 33这种类型的hex数据类型可以直接通过以下代码进行转换 double QDataConversion::hexToDouble(QByteArray p_buf) {double retValue 0;if(p_buf.size()>4){QString str1 byteArrayToHexStr(p_buf.mid(0,1));QString str2 byteArrayToHexStr(p_buf.mid(1,…

Redis实战:Redis的安装及简单使用

本片将介绍 Redis 的安装及简单使用 文章目录 1、Redis安装1.1、Windows下Redis的安装1.2、Linux下Redis的安装1.3、Mac下Redis的安装&#xff08;使用Homebrew&#xff09; 2、Redis使用2.1、启动服务端客户端2.2、Redis简单命令 3、Redis命令大全 1、Redis安装 1.1、Windows…

基于Java+SpringBoot+Vue的学校田径运动会管理系统【源码+论文+演示视频+包运行成功】

博主介绍&#xff1a;✌擅长Java、微信小程序、Python、Android等&#xff0c;专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3fb; 不然下次找不到哟 Java项目精品实战案…

AMBA总线协议(1)——概述

目录 一、AMBA总线简介 二、基于AMBA 的典型微控制器 三、AHB介绍 1、概述 2、典型结构 &#xff08;1&#xff09; AHB 主机&#xff08;AHB Master&#xff09; &#xff08;2&#xff09;AHB 从机&#xff08;AHB Slave&#xff09; &#xff08;3&#xff09;AHB 仲裁…

机器人远程控制软件设计

机器人远程控制软件设计 That’s all.

【前端】vscode javascript 代码片段失效问题解决

1. 文件--首选项--用户代码片段-vue.json : 添加 // { // // Place your global snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and // // description. Add comma separated ids of the languages where the snippet is app…

iShot Pro for Mac 2.3.9最新中文版

iShot Pro是一款非常优秀的Mac截图软件&#xff0c;软件非常易于操作&#xff0c;主页面还设置了学习教程&#xff0c;可以轻松玩转软件所有功能&#xff0c;并且功能非常强大&#xff0c;不仅可以实现多种截图方式&#xff0c;还可以进行标注、贴图、取色、录屏、录音、OCR识别…

QT 基本对话框

包括&#xff1a; 1.标准文件对话框 dialog.h #ifndef DIALOG_H #define DIALOG_H#include <QDialog> #include <QTextCodec> #include <QLabel> #include <QLineEdit> #include <QPushButton> #include <QGridLayout> #include <QFr…

开源的密码学工具库:openssl安装在docker容器环境Linux(ubuntu18.04)

OpenSSL&#xff08;Open Secure Socket Layer&#xff09;是一个开源的密码学工具库&#xff0c;它提供了一系列的加密、解密、认证和通信安全相关的功能。OpenSSL 最初是为了支持安全的网络通信而设计的&#xff0c;但后来它的功能逐渐扩展到了许多不同的领域&#xff0c;包括…

详细整合Spring+SpringMVC+MyBatis+logback(SSM)项目

整体目录结构 表结构 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.a…

Zabbix-6.4.4 邮箱告警SMS告警配置

目录 ​------------------------- # 邮箱告警 ---------------------------------- 1.安装mailx与postfix软件包 2.修改mailx配置文件 3. 创建文件夹 4. 编写mail-send.sh脚本 5. 将该脚本赋予执行权限 6. 进入web界面进行设置—> Alerts —> Media Types 7. 添…

【Java从0到1学习】09 正则表达式

1. 正则表达式概述 在编写处理字符串的程序或网页时&#xff0c;经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句话说&#xff0c;正则表达式就是记录文本规则的代码。 正则表达式&#xff0c;又称正规表示法、常规表示法&#xff…

Redis基础概念和数据类型详解

目录 1.什么是Redis&#xff1f; 2.为什么要使用Redis&#xff1f; 3.Redis为什么这么快&#xff1f; 4.Redis的使用场景有哪些&#xff1f; 5.Redis的基本数据类型 5.1 5种基础数据类型 5.1.1 String字符串 5.1.2 List列表 5.1.3 Set集合 5.1.4 Hash散列 5.1.5 Zset有序集…

第8章:集成学习

个体与集成 同质&#xff1a;相同的基学习器&#xff0c;实现容易&#xff0c;但是很难保证差异性。异质&#xff1a;不同的基学习器&#xff0c;实现复杂&#xff0c;不同模型之间本来就存在差异性&#xff0c;但是很难直接比较不同模型的输出&#xff0c;需要复杂的配准方法。…