指针——C语言初阶

一.指针基本概念:

  1. 指针是内存中一个最小单元的编号,也就是地址
  2. 平时口语中说的指针,通常指的是指针变量,是用来存放地址的变量
    #include<stdio.h>
    int main()
    {int a = 0;//a是整型变量,占用四个字节的内存空间,在内存中开辟一块空间int* pa = &a;printf("%p", pa);//pa是一个指针变量,用来存放地址,这里是将a的四个字节的第一个字节的地址存放在ap变量中return 0;
    }

  3. 指针变量:我们可以通过&(取地址操作符)取出变量的内存真实地址,把地址可以存放到一个变量中这个变量就是指针变量。(存放在指针中的值都被当成地址处理)
  4. 指针变量中存放的是地址,通过这个地址,就可以找到一个内存单元
  5. 指针的大小在32位平台是四个字节,在64位平台是八个字节
  6. x86  - 32位

    x64  - 64位


二.指针和指针类型:

  1. 我们都知道普通变量都有不同的类型,由整型,字符型,浮点型等等,而指针变量也有不同的类型
    int a = 5;假设有以上a变量,那么我们可以将a的地址储存进以下指针变量中char* pc = &a;short* ps = &a;int* pi = &a;long* pl = &a;float* pf = &a;double* pd = &a;
    
  2. 我们需要注意的是:例如:int*p——指针类型是int*,指针所指向的类型是int。(不要记混)
  3. 既然一个整型类型的数据可以被别的不同类型数据的指针储存,那么指针类型的意义又是什么呢?

(1)指针+-整数:

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

(2)指针的解引用:
#include<stdio.h>
int main()
{int n = 0x11223344;char* pc = (char*)&n;int* pi = &n;*pc = 0;//重点在调试的过程中观察内存的变化*pi = 0;//重点在调试的过程中观察内存的变化return 0;
}

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

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


三.野指针:

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

(1)野指针成因:
  1. 指针未初始化:
    #include<stdio.h>
    int main()
    {int* p;//p没有初始化,就意味着没有明确的指向//一个局部变量不初始化的话,放的是随机值*p = 10;//非法访问内存了return 0;
    }

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

  3. 指针指向的空间释放:
    #include<stdio.h>
    int* test()
    {int a = 10;//a为局部变量,函数开始时创建,函数结束时销毁return &a;
    }
    int main()
    {int* p = test();*p = 20;//此时p指向的空间已销毁(被释放),不属于当前程序,此时指针p就为野指针return 0;
    }
    

(2)如何规避野指针:
  1. 指针初始化:
  2. 注意指针是否越界
  3. 指针指向被释放空间时置为NULL(空指针)
  4. 指针使用之前应检查其有效性

这里展示几个代码:

比较以下代码,并注意注释的内容:

函数栈帧与销毁:


四.指针运算:

(1)指针+-整数:

总结:

  • 从0位到5位,地址是由低到高的
  • *p++=0;相当于:*p=0   p++  
  • 指针变量的自增自减运算,指针加一或减一运算,表示指针向前或向后移动一个单位(不同类型的指针,单元长度不同 )。这个在数组中非常常用。
    #include<stdio.h>
    int main()
    {int arr[10] = { 0 };int i = 0;int n = sizeof(arr) / sizeof(arr[0]);//计算出数组中元素的个数/*for (i = 0; i < n; i++){arr[i] = 1;}*/int* p = &arr[0];for (i = 0; i < n; i++){*p++ = 1;//*(p+i)=1}return 0;
    }

(2)指针-指针:

观察下图:

可以很直观的得出:数组中两个指针相减得到的是指针和指针之间元素的个数

注意:

  • 不是所有指针都能相减
  • 指向同一块空间的两个指针才能相减!

例题:编写函数(不允许创建临时变量),求字符串的长度(三种方法)

  • 循环
  • 递归
  • 指针-指针
//循环
#include<stdio.h>
int my_strlen(char* n)
{int count = 0;while (*n != '\0'){count++;n++;}return count;
}
int main()
{int len = my_strlen("lover");printf("%d", len);return 0;
}
//递归
#include<stdio.h>从
int my_strlen(char* n)
{if (*n != '\0'){return 1 + my_strlen(n + 1);}else{return 0;}
}
int main()
{int len = my_strlen("lover");printf("%d", len);return 0;
}
//指针-指针
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int my_strlen(char* n)
{char* np = n;while (*n != '\0'){n++;}return n - np;
}
int main()
{char arr[] = "study";int len = my_strlen(arr);printf("%d", len);return 0;
}

(3)指针的关系运算:

#include<stdio.h>
#define A 5
int main()
{int arr[10] = { 0 };int* p = &arr[A];for (p = &arr[A]; p > &arr[0];){*--p = 0;}return 0;
}

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


五.指针和数组:

  1. 数组名表示的是数组首元素地址(两种情况除外,数组章节讲了——sizeof,&)

(不必多说,数组那节都已经讲了)


六.二级指针:

二级指针变量用来存放一级指针变量的地址

观察下面代码:

  1. pa是一个指针变量,一级指针
  2. ppa是一个二级指针变量
  3. int*是说明ppa是指针,ppa指向的对象是int*类型


七.指针数组:

指针数组是数组,是存放指针的数组(数组我们已经了解了整型数组,字符数组)

观察下列代码:

#include<stdio.h>
int main()
{int a = 10;int b = 20;int c = 30;int arr[10];int* ap = &a;int* bp = &b;int* cp = &c;//parr是存放指针的数组,就是指针数组int* parr[10] = { &a,&b,&c };int i = 0;for (i = 0; i < 3; i++){printf("%d\n", *(parr[i]));}return 0;
}

可以用其打印二维数组:

#include<stdio.h>
int main()
{int arr1[4] = { 1,2,3,4 };int arr2[4] = { 2,3,4,5 };int arr3[4] = { 3,4,5,6 };int* parr[3] = { &arr1,&arr2,&arr3 };int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 4; j++){printf("%d", parr[i][j]);//相当于:arri[j]//parr[1]相当于arr1,也可以改为 *( *(parr+i)+j)//arr[i] <==> *(arr+i)printf("\n");}return 0;
}

知识点:arr[i] <==> *(arr+i)

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

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

相关文章

数据结构刷题

空间复杂度&#xff1a;临时开辟的空间、空间是可以重复利用的 递归为O(n) 时间复杂度&#xff1a;程序执行次数 消失的数字 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 思路1&#xff1a;利用连续的特点求等差和然后减去所有元素得到的就是消…

【简单搭建】WhatsApp筛选Ws等资源卡密售卖平台源码

WhatsApp筛选Ws/Tg外贸营销Supplier推特号/FB号/谷歌号/小火箭Ws/Channel社交账号 1.后台上传各种账号前台可以下单购买 2.号码可以进行刷选查询 3.各种海外社交软件可以购买 4.可以设置分销我的下级 5.对接ustd接口 企业猫在11/16的时候搭建了下&#xff0c;可以搭建出来…

51单片机应用从零开始(六)·逻辑运算

51单片机应用从零开始&#xff08;一&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;二&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;三&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;四&#xff09;-CSDN博客 51单片机应用从零开始&#xff08;…

2023年亚太杯数学建模思路 - 案例:FPTree-频繁模式树算法

文章目录 赛题思路算法介绍FP树表示法构建FP树实现代码 建模资料 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 算法介绍 FP-Tree算法全称是FrequentPattern Tree算法&#xff0c;就是频繁模式树算法&#…

操作系统:输入输出管理(二)磁盘调度算法

一战成硕 5.3 磁盘固态硬盘5.3.1 磁盘5.3.2 磁盘的管理5.3.3 磁盘调度算法 5.3 磁盘固态硬盘 5.3.1 磁盘 磁盘是表面涂有磁性物质的物理盘片&#xff0c;通过一个称为磁头的导体线圈从磁盘存取数据。在读写操作中&#xff0c;磁头固定&#xff0c;磁盘在下面高速旋转。磁盘盘…

第四代智能井盖传感器,万宾科技助力城市安全

在迈向更为智能化、相互联系更为紧密的城市发展过程中&#xff0c;智能创新产品无疑扮演了一种重要的角色。智能井盖传感器作为新型科学技术产物&#xff0c;不仅解决传统井盖管理难的问题&#xff0c;也让城市变得更加安全美好&#xff0c;是城市生命线的一层重要保障。这些平…

人工智能引领环境保护的新浪潮:技术应用及其影响

在全球范围内&#xff0c;环境保护已经成为一个迫切的话题。随着人工智能技术的发展&#xff0c;它开始在环境保护领域扮演越来越重要的角色。AI不仅能够帮助更有效地监测环境变化&#xff0c;还能提出解决方案来应对环境问题。 污染监测与控制&#xff1a; AI系统可以分析来自…

hadoop 大数据环境配置 配置jdk, hadoop环境变量 配置centos环境变量 hadoop(五)

1. 遗漏一步配置系统环境变量&#xff0c;下面是步骤&#xff0c;别忘输入更新系统环境命令 2. 将下载好得压缩包上传至服务器&#xff1a; /opt/module 解压缩文件存放地址 /opt/software 压缩包地址 3. 配置环境变量&#xff1a; 在/etc/profile.d 文件夹下创建shell文件 …

Python---列表 集合 字典 推导式(本文以 列表 为主)

推导式&#xff1a; 推导式comprehensions&#xff08;又称解析式&#xff09;&#xff0c;是Python的一种独有特性。推导式是可以从一个数据序列构建另一个新的数据序列&#xff08;一个有规律的列表或控制一个有规律列表&#xff09;的结构体。 共有三种推导&#xff1a;列表…

【带头学C++】----- 六、结构体 ---- 6.7 结构体的对齐规则

6.7 结构体的对齐规则 6.7.1 知识点引入 6.7.2 结构体自动对齐规则 1、确定分配单位(一行分配多少字节) 结构体中最大的基本类型长度决定 2、确定成员的偏移量 成员偏移量成员自身类型的整数倍 需要根据你所在平台的位数&#xff0c;32位和64为类型大小不一样。cpu一次读取…

前段-用面向对象的方式开发一个水管小鸟的游戏

首先准备好各类空文件 index.js css html 和图片 图片是下面这些&#xff0c;如果没有的可在这里下载 2 开发开始 好了&#xff0c;基础准备工作完毕&#xff0c;开发开始&#xff0c; 首先&#xff0c;先把天空&#xff0c;大地&#xff0c;小鸟的盒子准备好&#xff0c;并…

Android studio配置Flutter开发环境报错问题解决

博主前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住也分享一下给大家 &#x1f449;点击跳转到教程 报错问题截图 报错原因已经给出&#xff1a; You need Java 11 or higher to build your app with this version of G…

【智能家居】4、智能家居框架设计和代码文件工程建立

目录 一、智能家居项目框架 二、智能家居工厂模式示意 三、代码文件工程建立 SourceInsight创建新工程步骤 一、智能家居项目框架 二、智能家居工厂模式示意 三、代码文件工程建立 创建一个名为si的文件夹用于保存SourceInsight生成的文件信息&#xff0c;然后在SourceInsig…

DocCMS keyword SQL注入漏洞复现 [附POC]

文章目录 DocCMS keyword SQL注入漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 DocCMS keyword SQL注入漏洞复现 [附POC] 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测…

【超好用的工具库】hutool-all工具库的基本使用

简介&#xff08;可不看&#xff09;&#xff1a; hutool-all是一个Java工具库&#xff0c;提供了许多实用的工具类和方法&#xff0c;用于简化Java开发过程中的常见任务。它包含了各种模块&#xff0c;涵盖了字符串操作、日期时间处理、加密解密、文件操作、网络通信、图片处…

ZYNQ7000---FLASH读写

提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、Flash是什么&#xff1f;二、Flash的分类1、内部结构&#xff08;接口&#xff09;区分&#xff1a;2、外部接口区分&#xff1a;SPIQPSI Flash: QSPI 控制…

京东数据挖掘(京东数据采集):2023年Q3电脑行业数据分析报告

近年来&#xff0c;在远程办公、远程教育等需求的刺激下&#xff0c;电脑的销售增长较为显著。不过&#xff0c;随着市场的成熟乃至饱和&#xff0c;电脑销售市场也逐渐出现增长困难、需求疲软等问题。 2023年第三季度&#xff0c;电脑市场的出货量同比下滑。根据鲸参谋电商数据…

德迅云安全为您介绍关于抗D盾的一些事

抗D盾概述&#xff1a; 抗D盾是新一代的智能分布式云接入系统&#xff0c;接入节点采用多机房集群部署模式&#xff0c;隐藏真实服务器IP&#xff0c;类似于网站CDN的节点接入&#xff0c;但是“抗D盾”是比CDN应用范围更广的接入方式&#xff0c;适合任何TCP 端类应用包括&am…

GB28181 编码规则说明

背景&#xff1a; GB/T28181-2011 《安全防范视频监控联网系统信息传输、交换、控制技术要求》中规定了联网系统应对前端设备、监控中心设备、用户终端ID进行统一编码,该编码具有全局唯一性。这就是国标编码。编码分20位和18位&#xff0c;其中18位编码已经淘汰。下文中&#…

搭建yum源并定时同步

一 、安装yum源 1-准备yum目录 cd /data/www/html createrepo -v ./目录 2-安装服务 yum -y install httpd 3-配置服务 /etc/httpd/conf/httpd.conf 4.配置/etc/yum.repo.d/local.rpeo 二、定时更新yum源 #1. 同步整个源到指定目录 [rootV10SP1-1 pac]# reposync -p /root/…