C语言初阶--指针

文章目录

  • 1. 指针是什么?
  • 2. 指针和指针类型
    • 2.1. 指针类型
    • 2.2. 指针类型的意义
  • 3. 野指针
    • 3.1. 野指针成因
      • 3.1.1. 未初始化
      • 3.1.2. 超过数组范围,越界访问
      • 3.1.3. 指针指向的空间释放
    • 3.2. 规避野指针
  • 4. 指针运算
    • 4.1. 指针+-整数
    • 4.2. 指针 - 指针
    • 4.3. 指针的关系运算
  • 5. 指针和数组
  • 6. 二级指针
  • 7. 指针数组

1. 指针是什么?

* 1. 指针是内存中一个最小的单元的编号,也就是地址.
* 2. 平时口语中说的指针,通常指的是指针变量,用来存放内存地址的变量.
* 总结:* 指针变量是用来存放地址的变量,地址是唯一标示一块地址空间的.* 指针的大小,在32位平台是4字节,在64位平台是8字节.> 内存空间如何管理?
> 切割成内存的单元 - 1byte(字节)
> 把内存单元编号就称为地址(地址也叫指针).
> 指针其实就是地址,地址就是编号.
#include <stdio.h>
int main()
{int a = 0;int* pa = &a;//pa是指针变量,存放a的地址;return 0;
}

2. 指针和指针类型

2.1. 指针类型


char* pc = NULL;	//char*类型的指针是为了存放char类型变量的地址.
int* pi = NULL;		//int* 类型的指针是为了存放int 类型变量的地址.
short* ps = NULL;	//short* 类型的指针是为了存放short 类型变量的地址.
long* pl = NULL;	//long* 类型的指针是为了存放long 类型变量的地址.
float* pf = NULL;	//float* 类型的指针是为了存放float 类型变量的地址.
double* pd = NULL;	//double* 类型的指针是为了存放double 类型变量的地址.
  • X86 - 32位的环境
  • X64 - 64位的环境
  • sizeof返回的值的类型是无符号整型 unsigned int %zu
  • 0x表示是16进制数字,1个16进制数字转换为4个2进制数字

2.2. 指针类型的意义

1.指针类型决定了指针在被解引用的时候访问几个字节.
如果是int的指针,解引用访问4个字节
如果是char
的指针,解引用访问1个字节
2.指针的类型决定了指针±1操作的时候,跳过几个字节.
决定了指针的步长
如果是int* pi的指针,pi+1跳过4个字节
如果是char* pc的指针,pc+1跳过1个字节

#include <stdio.h>int main()
{int n = 10;//0x0054f8c8char* pc = (char*)&n;//0x0054f8c8int* pi = &n;//0x0054f8c8printf("%p\n", &n);//0x0054f8c8printf("%p\n", pc);//0x0054f8c8printf("%p\n", pc+1);//0x0054f8c9//pc 是char* 类型的指针,+1,跳过1个字节printf("%p\n", pi);//0x0054f8c8printf("%p\n", pi+1);//0x0054f8cc//pi 是int* 类型的指针,+1,跳过4个字节return 0;
}

3. 野指针

  • 野指针:指针指向的位置是不可知的(随机的,不确定,没有明确限制的).

3.1. 野指针成因

3.1.1. 未初始化

int* p;//p没有初始化,就意味着没有明确的指向
//一个局部变量不初始化,放的是随机值.
*p = 10;//非法访问内存,这里的p就是野指针.

3.1.2. 超过数组范围,越界访问

int* arr[10]={0};
int* p = arr;//&arr[0]
int i = 0;
for(i=0;i<=10;i++)
{//0~10--循环11次,arr[10] -形成越界访问!*p=i;p++;
}

3.1.3. 指针指向的空间释放

int* test()
{int a = 10;return &a;
}int main()
{int* p = test();//野指针return 0;
}

3.2. 规避野指针

  • 1.指针初始化
  • 2.小心指针越界
  • 3.指针指向空间释放及时置NULL
  • 4.避免返回局部变量的地址
  • 5.指针使用之前检查有效性
	int* p = NULL; //空指针//*p = 100;//err//建议if(p != NULL){*p = 100;}

4. 指针运算

4.1. 指针±整数

	*p++;//*p;//p++;
	(*p)++;//(*p)解引用的值+1;
int main()
{int arr[10] = {0};int i = 0;int sz = sizeof(arr)/ sizeof(arr[0]);//数组下标写法//for(i = 0; i < sz;i++)//{//	arr[i] = 1;//}/*int* p = arr;for(i = 0; i < sz; i++){*p = 1;p++;}*/int* p = arr;for(i = 0; i < sz; i++){*(p + i) = 1;}return 0;
}

4.2. 指针 - 指针

* 指针 - 指针得到的指针和指针之间的元素个数
* 注:* 不是所有的指针都能相减,只有指向同一空间的2个指针才可以.
	&arr[9]-&arr[0]==9
//指针-指针求字符串长度
int my_strlen(char* str)
{int* start = str;while(*str != '\0'){str++;}return (str-start);
}

4.3. 指针的关系运算

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

5. 指针和数组

  • 数组名表示的是数组元素的首地址.(除了2个例外:sizeof,&)
int arr[10]={1,2,3,4,5,6,7,8,9,0};
int* p = arr;	//p存放的是数组首元素的地址//通过指针来访问数组
for(i = 0; i < sz; i++)
{printf("%d ",*(p + i));//p+i--计算的是arr下标//printf("%d ",*(arr + i));//arr表示首元素地址//arr[i]-->*(arr+i)
}

6. 二级指针

  • 二级指针是存放一级指针变量的地址.
	int a = 10;int* pa = &a;//pa是一个指针变量,一级指针变量//* 表示是指针,int 表示,pa指向int 类型的变量int** ppa = &pa;//ppa是一个二级指针变量//   *--ppa是指针//int* ----ppa指向的对象是int* 类型*ppa;//对ppa中的地址进行解引用,找到pa**ppa;//先通过*ppa找到pa,然后对pa进行解引用操作,找到a

7. 指针数组

  • 存放指针的数组就是指针数组.
	int a = 10;int b = 20;int c = 30;int* pa = &a;int* pb = &b;int* pc = &c;int arr[10];int* parr[10] = { &a, &b, &c };//parr[]数组,指向int* 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 };for(int i = 0; i < 3; i++){for(int j = 0;j < 4; j++){prntf("%d ",parr[i][j]);}printf("\n");  }

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

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

相关文章

Blender常见操作

1.局部视图&#xff1a;Local View&#xff0c;也可称作Solo模式&#xff0c;按快捷键 “/”进入&#xff0c;在按退出&#xff0c;只显示选中的物体&#xff08;可多选&#xff09;&#xff0c;方便编辑 2.物体合并&#xff1a;Ctrl J 其中&#xff0c;当选中多个物体时&am…

二、VLAN原理和配置

vlan不是协议&#xff0c;是一个技术&#xff0c;虚拟局域网技术&#xff0c;基于802.1q协议。 vlan&#xff08;虚拟局域网&#xff09;&#xff0c;将一个物理的局域网在逻辑上划分成多个广播域的技术。 目录 1.冲突域和广播域 概念 范围 2.以太网帧格式 3.以太网帧封装…

Python基础:【扩展系列】Python对小程序或App进行自动化操作常用框架

Python可以用来实现对小程序或App的自动化操作,这通常涉及使用专门的自动化测试和操作工具。 常用框架 以下是一些常用的工具和框架: Appium: Appium 是一个开源工具,用于自动化移动应用程序的测试,包括原生应用、移动网页应用和混合应用。它支持iOS、Android和Windows应…

【酱浦菌-爬虫项目】四种方法爬取百度首页信息

项目原理&#xff1a; 首先&#xff0c;定义了四个函数&#xff0c;每个函数都有不同的功能&#xff1a; func1()&#xff1a;发送一个GET请求到百度网站&#xff0c;并获取响应内容&#xff0c;演示如何使用requests库来获取网页内容。 func2()&#xff1a;发送一个GET请求到…

字节5面挂,恶心到了。。。

字节五面 今天脉脉看到一篇帖子&#xff1a; 楼主是 tx 的前员工&#xff0c;在字节五面&#xff08;加轮&#xff09;被挂后&#xff0c;认定&#xff08;或许私下做了一些调查&#xff09;是字节 HR 向 tx 背调&#xff0c;然后被前同事捏造虚假信息&#xff0c;导致的面试失…

分类规则挖掘(一)

目录 一、分类问题概述&#xff08;一&#xff09;分类规则挖掘&#xff08;二&#xff09;分类规则评估&#xff08;三&#xff09;分类规则应用 二、k-最近邻分类法 一、分类问题概述 动物分类&#xff1a;设有动物学家陪小朋友林中散步&#xff0c;若有动物突然从小朋友身边…

【Linux】yum、vim

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/qinjh_/category_12625432.html 目录 Linux 软件包管理器 yum 什么是软件包 查看软件包 如何安装软件 如何卸载软…

机器学习:基于Sklearn、XGBoost框架,使用逻辑回归、支持向量机和XGBClassifier来诊断并预测一个人是否患有自闭症

前言 系列专栏&#xff1a;机器学习&#xff1a;高级应用与实践【项目实战100】【2024】✨︎ 在本专栏中不仅包含一些适合初学者的最新机器学习项目&#xff0c;每个项目都处理一组不同的问题&#xff0c;包括监督和无监督学习、分类、回归和聚类&#xff0c;而且涉及创建深度学…

清理 Conda 和 pip 缓存

清理 Conda 缓存 查看 Conda 缓存的使用情况 conda clean --dry-run --all 删除不再使用的包和缓存 conda clean --all 清理 pip 缓存 Python缓存文件的默认位置&#xff1a; Windows 10&#xff1a;C:\Users\username\AppData\Local\pip\Cache macOS&#xff1a;/Users/…

JAVA系列 小白入门参考资料 继承

目录 1. 为什么需要继承 2. 继承的概念 3. 继承的语法 4. 父类成员访问 4.1 子类中访问父类的成员变量 1. 子类和父类不存在同名成员变量 2. 子类和父类成员变量同名 4.2 子类中访问父类的成员方法 1. 成员方法名字不同 2. 成员方法名字相同 ​5. super关键字 …

Kubernetes学习笔记06

第十六章、Kubernetes容器交付介绍 如何在k8s集群中部署Java项目 容器交付流程 开发代码阶段 编写代码编写Dockerfile【打镜像做准备】持续交付/集成 代码编译打包制作镜像上传镜像仓库应用部署 环境准备PodServiceIngress运维 监控故障排查应用升级 k8s部署Java项目流程 …

AI在建筑行业中的现状

1、关键发现: -AI正逐渐成为建筑师工作流程的一部分,其发展受到实验和自学的推动。 -使用AI的设计师对其在项目早期阶段的应用最为满意,尽管有些人在其他地方也找到了创新用途。 -当前建筑领域内缺乏AI的规范和道德指导,引起了一些担忧。 -关于AI在建筑中的位置存在不同意…

使用Github+Picgo+npm实现免费图床

本文参考自 Akilar&#xff0c;原文地址&#xff1a;https://akilar.top/posts/3e956346/ Picgo的配置 Github图床仓库内容不能超过1GB&#xff0c;因为Github原则上是反对仓库图床化的&#xff0c;超过1GB之后会由人工审核仓库内容&#xff0c;如果仓库被发现用来做图床&…

如何解决Go中uint类型溢出问题

如何解决Go中uint类型溢出问题 Golong的uint类型溢出问题通常会发生在大量的运算中&#xff0c;特别是涉及到大量循环和大数运算中。当uint类型的值超过其最大值时&#xff0c;会发生溢出&#xff0c;从最小值开始循环&#xff0c;一般有如下几种解决办法&#xff1a; 1. 使用…

Spring Boot项目中集成Logback作为日志框架-笔记

在Spring Boot项目中集成Logback作为日志框架是一个标准做法&#xff0c;因为Spring Boot默认就使用Logback作为日志系统。以下是集成Logback的步骤&#xff1a; 1. 默认集成 Spring Boot会自动配置Logback&#xff0c;所以通常情况下&#xff0c;你不需要添加任何额外的依赖或…

介绍一下mybatis的基本配置(mybatis-config.xml)

src/main/resources/mybatis-config.xml 这句代码&#xff0c;是XML的声明&#xff0c;它指定了&#xff0c;XML的版本 和 编码方式 <?xml version"1.0" encoding"UTF-8" ?>这句代码&#xff0c;声明了XML文档类型&#xff0c;它告诉解析器&#x…

RTCRTC

#include "stm32f10x.h" void MyRTC_Init(void) { //1.开启PWR和BKP的时钟 使能BKP和RTC的访问 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_BKP,ENABLE); PWR_BackupAccessCmd(ENABLE); …

MongoDB的安装与操作

MongoDB的安装 MongoDB的使用与封装安装&#xff1a; 1、官网下载地址&#xff1a;https://www.mongodb.com/try/download/community 2、安装mongodb-windows-x86_64-4.4.28-signed.msi 3、安装Robo3T客户端robo3t_v1.4.3.ziphttps://robomongo.org/&#xff08;客户端MongoD…

k8s负载均衡

在Kubernetes中&#xff0c;负载均衡通常由服务对象来实现。你可以使用Service资源来暴露一个容器&#xff08;或一组容器&#xff09;&#xff0c;并且提供负载均衡功能。 以下是一个简单的服务定义示例&#xff0c;它使用了Cluster内部负载均衡器实现&#xff08;也就是说&a…

H266 编码标准开源编码器 VVenC 介绍

H266 H.266&#xff0c;也称为VVC&#xff08;Versatile Video Coding&#xff09;&#xff0c;是最新的国际视频编码标准&#xff0c;由MPEG&#xff08;Moving Picture Experts Group&#xff09;和ITU&#xff08;International Telecommunication Union&#xff09;联合开…