C语言指针详解-上

news2024/11/16 5:55:26

C语言指针详解-上

  • 前言
  • 1.指针的基本概念
    • 1.1指针是什么
    • 1.2指针的声明与初始化
    • 1.3取地址符`&`和解引用符`*`
      • `&` 运算符用于**获取变量的地址**
      • `*` 运算符用于访问指针指向的值
  • 2.指针的类型
    • 常见数据类型的指针
    • 指针与数组、字符串
    • 数组指针
    • 结构体指针
    • 函数指针
    • 二级指针
    • void指针
  • 3.指针运算
    • 3.1指针的解引用
    • 3.2指针 + 整数、指针 - 整数
    • 3.3指针和指针的比较
    • 3.3指针-指针

前言

指针是C语言中一个绕不开的点,也是解题必备的工具,本文将围绕指针这几点进行详解:

  • 指针的基本概念
  • 指针类型
  • 指针运算
  • 指针的用途
  • 指针的安全隐患和解决方法
  • 常用工具

1.指针的基本概念

1.1指针是什么

在C语言中,任何变量的创建都需要在内存中申请空间,而这些空间都有特定的编号,即地址,也称作指针

地址也是一串数字,用于存放地址的变量就是指针变量,我们平常说的指针就是这个指针变量

1.2指针的声明与初始化

  • 在C语言中,声明指针主要分两步:
  • 使用解引用符(*)表明声明的变量是个指针
  • 指定一个指针指向的数据类型

如:

int* p1,p2;

*表明p1是个变量,int表明p1可以存储指向整型变量的地址
对于p2*和它没有关系,所以p2是个整型变量

  • 而在声明指针时,给指针一个具体的地址NULL就是初始化

如:

int x = 10; 
int *p = &x; 

这里创建了变量x,并使用取地址符(&)将x的地址存入p

1.3取地址符&和解引用符*

& 运算符用于获取变量的地址

在之前的学习中,我们应该多次使用了&:

int x;
scanf("%d", &x);

是的,当使用scanf函数读取变量,我们其实传递了变量的地址,这样scanf函数才能正确地将读取到的数据存储到那个变量中。

* 运算符用于访问指针指向的值

如:

int x = 10; 
int *p = &x; 
printf("%d",*p);

p是一个指向x的指针,那么*p就是x的值
我们也可理解为*获取了p中存放的地址,并通过这个地址找到了变量x

2.指针的类型

指针的类型大多取决它所指向的数据类型:

常见数据类型的指针

int *p1;
double *p2;
char *p3;

p1指向整型
p2指向双精度浮点型
p3指向字符

指针与数组、字符串

数组名大多情况下是指向数组首元素的指针:

int arr[10]={1,2,3,4,5,6,7,8,9,10};
for(int i=0;i<10;i++)printf("%d ",*(arr+i));
int* pa=arr;
for(int i=0;i<10;i++)printf("%d ",*(pa+i));

在这里插入图片描述
字符串实际上是一个字符数组,后面跟着一个空字符’\0’作为结束标志
因此,字符串的名字也是第一个字符的地址:

char ch[] = "Hello World!\n";
printf(ch);
char *pc = ch;
printf(pc);

在这里插入图片描述

数组指针

数组指针是指向一个具有固定数量元素的数组的指针。
因为只有元素数量固定,数组类型才能被确定:

int arr[10];     arr是个数组,元素个数10,元素类型为整型
int (*p1)[10];    p1是个指针,指向数组元素个数10,元素类型为整型
int (*p2)[10] = &arr;这是数组指针的初始化
p1 = &arr;这是数组指针的赋值

注:&数组名取出的是整个数组的地址

arr/&arr[0]&arr
数组首元素的地址整个数组的地址
类型int*int(*)[10]

结构体指针

声明和初始化的过程大同小异:

struct Stu
{
	int a;
	char c[20];
};
struct Stu S1;
struct Stu* p1;  声明
struct Stu* p2 = &S1;   初始化

需注意,当通过指针访问结构体成员时,可使用箭头运算符 ->,也可使用解引用符*

struct Stu S2={1,"Hello world!"};
p1 = &S2;
printf("%d\n",(*(p1)).a);
printf("%s\n",p1->c);

在这里插入图片描述

函数指针

函数名&函数名都是其地址,存放函数地址的变量就是函数指针:

int Add(int a,int b){return a + b;}
int (*p1)(int,int);   声明
int (*p2)(int,int) = &Add;初始化
int (*p3)(int,int) = Add; p2与p3相同

可以看见,函数指针声明也分两步:

  • 使用解引用符(*)表明声明的变量是个指针
  • 指定一个指针指向的函数类型

函数类型就是:返回类型(参数类型1,参数类型2…)
int(int,int)
其函数指针类型就是int(*)(int,int)

二级指针

指针变量也是一种变量,创建时会在内存开辟空间,而存储指针变量的地址的变量就是二级指针

int *p1;
int* *p2 = &p1;

其中,*p2*表明p2是个指针,int*表明p2指向指针变量,= &p1p1的地址存入p2

void指针

即以void声明的指针,无具体类型,可根据需要强制类型转换成所需的类型。
需注意,不强转就不能解引用

	int a = 0;
	void* p = &a;
	*p = 10;

在这里插入图片描述
在这里插入图片描述
但是可以直接使用其存储的地址,但可能有警告

	char c[20] = "Hello World!";
	void* p = c;
	printf("%s\n", p);

在这里插入图片描述
在这里插入图片描述

3.指针运算

前面我讲了指针的类型,而指针的类型在指针运算中起了关键作用

指针运算主要包括:

  • 指针的解引用
  • 指针 + 整数、指针 - 整数
  • 指针和指针的比较
  • 指针-指针

3.1指针的解引用

指针类型决定了其在解引用时访问几个字节,以及访问的方式

	int n1 = 0x66666666;
	int n2 = 0x66666666;
	int n3 = 0x66666666;
	int* p1 = &n1;
	*p1 = 0;
	char* p2 = (char*) & n2;
	*p2 = 0;
	float* p3 = (float*) & n3;
	*p3 = 0;
	printf("int:%x\nchar:%x\nfloat:%x\n", n1,n2,n3);

在这里插入图片描述

3.2指针 + 整数、指针 - 整数

指针加整数n,其储存的地址加(n* 所指类型的大小),单位字节
可简单验证:

	char ch;
	int a;
	int arr[4] = { 0 };
	char* pc = &ch;
	int* pa = &a;
	int(*parr)[4] = &arr;
	printf("pc=%p\npa=%p\nparr=%p\n", pc, pa, parr);
	printf("pc=%p\npa=%p\nparr=%p\n", pc+1, pa+1, parr-1);

在这里插入图片描述

3.3指针和指针的比较

在两个指针指向同一块空间的不同位置,我们可以进行指针间的比较:

int arr[10]={1,2,3,4,5,6,7,8,9,10};
int*p1=arr;
int*p2=&arr[9];
while(p1<=p2)
{
	printf("%d ",*p1);
	p1++;
}

在这里插入图片描述

3.3指针-指针

相同类型指针可相减,得到相距的元素个数
下面代码使用指针-指针得到字符串长度:

	char ch[10] = "Hahaha";
	char* pc1 = ch;
	char* pc2 = ch;
	while (*pc2 != '\0')pc2++;
	printf("%d\n", pc2 - pc1);

在这里插入图片描述

希望本篇文章对你有所帮助!
当然,本人仅仅是个C语言初学者,如有任何意见,欢迎各位提出!

C语言指针详解-下

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

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

相关文章

多级评论的实现,评论回复功能(两层型)

前言&#xff1a; 技术栈&#xff1a;springboot mysql mybatis 比着写一遍&#xff0c;你也一定会实现多级评论的功能&#xff0c;简单易上手&#xff01; 1.效果 整体的结构只有两层&#xff0c;但是确实现了评论回复功能 [ { "id": 2, "userId": …

让JMeter测试数据生成更容易

让JMeter测试数据生成更容易 背景&#xff1a; 在软件测试过程中&#xff0c;为了确保系统的稳定性和可靠性&#xff0c;需要对各种场景进行全面的测试。而不同的场景往往需要各种各样的测试数据&#xff0c;这些数据需要具有一定的真实性和多样性&#xff0c;以模拟实际使用…

零基础小白实现C#调用halcon dll的过程,并测试程序证明C#halcon联合开发成功

本篇将介绍零基础小白实现C#调用halcon dll的过程&#xff0c;同时这其中涉及到很多知识&#xff0c;务必将HDevelop和VisualStudio安装成功。下面我将详细阐述C#调用halcon dll的过程&#xff0c;你的点赞和评论是我一直前行的动力。 1. C#调用Halcon DLL的过程 要在C#中调用…

选择TPM管理咨询公司,这几点是关键!

在这个日新月异的商业时代&#xff0c;企业的竞争力不仅体现在产品和服务上&#xff0c;更在于其内部管理的精细化与高效化。TPM作为提升企业综合生产效率的利器&#xff0c;正逐步成为众多企业转型升级的必然选择。然而&#xff0c;如何在众多TPM管理咨询公司中慧眼识珠&#…

嘉盛:股指、国债及商品期货分析

股指展望中证全指在2024年下半年可能迎来约20%的上涨空间。尽管市场估值较低&#xff0c;风险溢价仍维持在高位&#xff0c;这提升了指数的配置性价比。预计无风险利率将继续维持在较低水平&#xff0c;对中证全指估值产生积极影响。盈利方面&#xff0c;预计下半年中证全指EPS…

【广东】邀您共赴纷享销客生态伙伴大会

在数字化浪潮的驱动下&#xff0c;CRM行业正迎来前所未有的创新机遇。作为CRM领域的引领者&#xff0c;纷享销客特别举办“纷享销客2024生态伙伴大会&#xff08;广东站&#xff09;”。我们诚挚邀请各位生态伙伴莅临现场&#xff0c;共同探讨SaaS CRM行业的最新趋势&#xff0…

haproxy负载均衡+mysql读写分离

haproxy负载均衡 [roothaproxy01 ~]# yum -y install ntpdate [roothaproxy01 ~]# yum -y install ntp [roothaproxy01 ~]# systemctl start ntpd 安装haproxy [roothaproxy01 ~]# yum -y install ntpdate 配置文件的地址 [roothaproxy01 ~]# rpm -ql haproxy [roothap…

美摄科技携手蔚来汽车,共创用户出行新体验!

7月27日&#xff0c;蔚来举办了以 AI 为主线的 “NIO IN 2024 蔚来创新科技日”&#xff0c;此次活动展示了蔚来在智能电动汽车领域最新探索与成果&#xff0c;为中国乃至全球的智能汽车行业树立了新的标杆。当晚&#xff0c;央视《主播说联播》以“中国智能车在全球竞争的另一…

MIT6.s081 2021 Lab Multithreading

Uthread: switching between threads 思路 xv6 已经实现了进程的切换机制&#xff0c;本实验要求参考进程的切换&#xff0c;实现一个用户态线程的切换。 要实现线程切换&#xff0c;必然涉及上下文&#xff0c;即寄存器的保存和恢复&#xff0c;那么需要保存哪些寄存器&…

建筑工程项目管理系统-计算机毕设Java|springboot实战项目

&#x1f34a;作者&#xff1a;计算机毕设匠心工作室 &#x1f34a;简介&#xff1a;毕业后就一直专业从事计算机软件程序开发&#xff0c;至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长&#xff1a;按照需求定制化开发项目…

建筑工地安全检查

在现代化的建筑工地中&#xff0c;安全始终是至关重要的核心问题。随着科技的不断进步&#xff0c;凡尔码建筑工地安全系统应运而生&#xff0c;灵活根据施工现场管理要求搭建建筑工地安全系统各个模块&#xff0c;为施工安全带来了全新的保障。 如何注册建筑工地安全系统后台…

自动打电话软件给企业带来了什么?

使用机器人外呼系统肯定都是想要给自己企业带来好处和解决问题的&#xff0c;想让自己的企业有所改变&#xff0c;有更好的发展&#xff0c;所以才会选择使用机器人外呼系统。而它也确实没让大家失望&#xff0c;使用了机器人外呼系统之后确实有许多企业发生了很大改变和进步&a…

鲁棒性目标检测 TOP2 方案分享

关联比赛: ACM MM2021 安全AI挑战者计划第七期&#xff1a;鲁棒性标识检测 ACM MM2021 鲁棒性目标检测比赛 TOP 2 方案 ​ 赛题背景 在商品知识产权领域&#xff0c;知识产权体现为在线商品的设计和品牌。不幸的是&#xff0c;在每一天&#xff0c;存在着非法商户通过一些…

一文学会本地部署可视化应用JSONCrack并配置公网地址实现远程协作

文章目录 前言1. Docker安装JSONCrack2. 安装Cpolar内网穿透工具3. 配置JSON Crack界面公网地址4. 远程访问 JSONCrack 界面5. 固定 JSONCrack公网地址 前言 本文主要介绍如何在Linux环境使用Docker安装数据可视化工具JSONCrack&#xff0c;并结合cpolar内网穿透工具实现团队在…

[Python学习日记-9] Python中的运算符

简介 计算机可以进行的运算有很多种&#xff0c;但可不只加减乘除这么简单&#xff0c;运算按种类可分为算数运算、比较运算、逻辑运算、赋值运算、成员运算、身份运算、位运算&#xff0c;而本篇我们暂只介绍算数运算、比较运算、逻辑运算、赋值运算 算数运算 一、运算符描述…

猫头虎分享:Python库 Pillow 的简介、安装、用法详解入门教程

猫头虎分享&#xff1a;Python库 Pillow 的简介、安装、用法详解入门教程 &#x1f4da; 大家好&#xff0c;今天猫头虎要和大家分享一款非常实用的 Python 图像处理库——Pillow。 &#x1f4a1; Pillow 是 Python 中非常流行的图像处理库&#xff0c;基于已经停止维护的 PI…

CE修改器步骤9学习教程

一、打开教程&#xff0c;因为我的电脑是64位的&#xff0c;所以打开这个&#xff08;x86_64&#xff09; 二、 跳转到步骤9&#xff0c;并让ce读取其内存 三、使用之前教程学到的知识&#xff0c;找到四个角色的健康值地址&#xff08;找到即可&#xff0c;不必找基址&#xf…

【STM32 FreeRTOS】Tickless低功耗模式

STM32低功耗模式 STM32 提供了 3 种低功耗模式&#xff0c;以达到不同层次的降低功耗的目的 睡眠模式&#xff08;内核停止工作&#xff0c;外设仍在运行&#xff09;停止模式&#xff08;所有时钟都停止&#xff09;待机模式&#xff08; 1.8 V 内核电源关闭&#xff09; Fr…

Qt-认识Qt(1)

目录 QT是做什么的&#xff1f; 什么是QT GUI开发的各种技术方案 QT支持的平台 Qt的版本和优点 开发工具概述 Qt是做什么的&#xff1f; Qt是用来干嘛的&#xff1f; 什么是Qt Qt是⼀个跨平台的C图形用户界⾯应用程序框架。它为应用程序开发者提供了建立艺术级图形界⾯所…

SSH远程管理/TCP Wrappers访问控制

文章目录 SSH远程管理/TCP Wrappers访问控制SSH(Secure Shell)协议OpenSSH配置信息服务监听选项用户登录控制登录验证方式 常用目录---ssh 远程安全登录---scp 远程安全复制---sftp FTP上下载 配置密钥对验证环境配置ECDSA算法RSA算法RSA算法实操在centos7 IP:20.0.0.51操作一、…