C语言基础---指针的基本语法

概述

内存地址

  • 在计算机内存中,每个存储单元都有一个唯一的地址(内存编号)。
  • 通俗理解,内存就是房间,地址就是门牌号
    在这里插入图片描述

指针和指针变量

  • 指针(Pointer)是一种特殊的变量类型,它用于存储内存地址。
  • 指针的实质就是内存“地址”
  • 指针变量就是存储这个地址的变量。
    在这里插入图片描述

指针作用

可间接修改变量的值

指针变量的定义和使用

  • 指针也是一种数据类型,指针变量也是一种变量
  • 指针变量指向谁,就把谁的地址赋值给指针变量

语法格式:

类型 变量;
类型 * 指针变量 = &变量;
  • & 叫取地址,返回操作数的内存地址
  • 叫解引用,指操作指针所指向的变量的值
  • 在定义变量时,* 号表示所声明的变量为指针类型
    指针变量要保存某个变量的地址,指针变量的类型比这个变量的类型多一个*
  • 在指针使用时,* 号表示操作指针所指向的内存空间
    示例代码:
#include <stdio.h>int main() {// 定义一个int类型的变量,同时赋值为10int a = 10;// 打印变量的地址printf("&a = %p\n", &a);// 定义一个指针变量,int *保存int的地址// int *代表是一种数据类型,int *指针类型,p才是变量名int* p;// 指针指向谁,就把谁的地址赋值给这个指针变量p = &a;// 打印p, *p, p指向了a的地址,*p就是a的值printf("p = %p, *p = %d\n", p, *p);return 0;
}

在这里插入图片描述

通过指针间接修改变量的值

指针变量指向谁,就把谁的地址赋值给指针变量
通过 *指针变量 间接修改变量的值

#include <stdio.h>int main() {// 定义一个int类型变量a,同时赋值为0int a = 0;// 定义int *指针变量,同时赋值a的地址int *p = &a;// 通过指针间接修改a的值*p = 123;printf("a = %d\n", a);// 定义一个int类型变量b,同时赋值为5int b = 5;// p 保存 b的地址p = &b;// 通过指针间接修改b的值*p = 250;printf("b = %d\n", b);return 0;
}

指针与常量

- 语法格式

int a = 1;
const int *p1 = &a;	// 等价于 int const *p1 = &a;
int * const p2 = &a;
const int * const p3 = &a;

从左往右看,跳过类型,看修饰哪个字符
如果是*, 说明指针指向的内存不能改变
如果是指针变量,说明指针的指向不能改变,指针的值不能修改

#include <stdio.h>int main() {int a = 1;int b = 2;// p1 可以改,*p1不能改const int *p1 = &a; // 等价于 int const *p1 = &a;// p1 = &b;    // ok// *p1 = 555;  // err// p2 不能修改,*p2可以修改int *const p2 = &a;// p2 = &b;    //err// *p2 = 555;  // ok// p3 和 *p 都不能改const int *const p3 = &a;// p3 = &b;    // err// *p3 = 555;  // errreturn 0;
}

指针大小

  • 使用sizeof()测量指针的大小,得到的总是:4或8
  • sizeof()测的是指针变量指向存储地址的大小
  • 在32位平台,所有的指针(地址)都是32位(4字节)
  • 在64位平台,所有的指针(地址)都是64位(8字节)
#include <stdio.h>int main() {int *p1;int **p2;char *p3;char **p4;printf("sizeof(p1) = %llu\n", sizeof(p1));printf("sizeof(p2) = %llu\n", sizeof(p2));printf("sizeof(p3) = %llu\n", sizeof(p3));printf("sizeof(p4) = %llu\n", sizeof(p4));printf("sizeof(double *) = %llu\n", sizeof(double *));return 0;
}

指针步长

  • 指针步长指的是通过指针进行递增或递减操作时,指针所指向的内存地址相对于当前地址的偏移量。
  • 指针的步长取决于所指向的数据类型。
  • 指针加n等于指针地址加上 n 个 sizeof(type) 的长度 指针减n等于指针地址减去 n 个 sizeof(type) 的长度
#include <stdio.h>int main() {char ch;char *p1 = &ch;printf("p1:%p, p1+1: %p\n", p1, p1 + 1); // 步长为1字节int a;int *p2 = &a;printf("p2:%p, p2+1: %p\n", p2, p2 + 1); // 步长为4字节double d;double *p3 = &d;printf("p3:%p, p3+1: %p\n", p3, p3 + 1); // 步长为8字节return 0;
}

野指针和空指针

  • 指针变量也是变量,是变量就可以任意赋值
  • 任意数值赋值给指针变量没有意义,因为这样的指针就成了野指针
  • 此指针指向的区域是未知(操作系统不允许操作此指针指向的内存区域)
  • 野指针不会直接引发错误,操作野指针指向的内存区域才会出问题
  • 为了标志某个指针变量没有任何指向,可赋值为NULL
  • NULL是一个值为0的宏常量
#include <stdio.h>int main() {int *p;p = 0x12345678; // 给指针变量p赋值,p为野指针, ok,不会有问题,但没有意义// *p = 1000;      // 操作野指针指向未知区域,内存出问题,errprintf("111111111111111111\n");int *q = NULL;  // 空指针return 0;
}

多级指针

C语言允许有多级指针存在,在实际的程序中一级指针最常用,其次是二级指针。
二级指针就是指向一个一级指针变量地址的指针。

#include <stdio.h>int main() {int a = 100;// 一级指针int* p1 = &a;printf("&a=%p\n", &a);printf("p1=%p\n", p1);printf("&p1=%p\n", &p1);// 二级指针,可以存储一级指针变量的地址int** p2 = &p1;printf("p2=%p\n", p2);printf("&p2=%p\n", &p2);// 三级指针,可以存储二级指针变量的地址int*** p3 = &p2;printf("p3=%p\n", p3);printf("&p3=%p\n", &p3);printf("---------------------\n");// 通过一级指针访问100,打印出来printf("*p1=%d\n", *p1);// 通过二级指针访问100,打印出来printf("**p2=%d\n", **p2);// 通过三级指针访问100,打印出来printf("***p3=%d\n", ***p3);return 0;
}

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

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

相关文章

tomcat热部署热加载原理剖析

Tomcat作为一个流行的Java Web服务器&#xff0c;提供了热部署和热加载的功能&#xff0c;使开发人员能够在不重启服务器的情况下更新应用程序。在本文中&#xff0c;我们将深入探讨Tomcat热部署热加载的原理。 首先&#xff0c;让我们了解一下热部署和热加载的概念。热部署是…

每日一VUE——组件的生命周期

文章目录 VUE组件的生命周期生命周期钩子函数实例创建Teleport VUE组件的生命周期 组件生命周期 组件从创建到挂载、更新、到销毁的一系列过程被称为组件的生命周期。 生命周期函数 在组件的各个生命周期节点执行的函数&#xff0c;为生命周期钩子函数。 生命周期钩子函数…

问题 C: 实验11_11_链表匹配

题目描述 已知两个由正整数组成的无序序列A、B&#xff0c;每个序列的元素个数未知&#xff0c;但至少有一个元素。你的任务是判断序列B是否是序列A的连续子序列。假设B是“1 9 2 4 18”&#xff0c;A是“33 64 1 9 2 4 18 7”&#xff0c;B是A的连续子序列&#xff1b;假设B是…

详解QDir类的使用

之前讲读写文件的文章&#xff0c;有涉及部分QDir的使用&#xff0c;讲解感觉不够全面&#xff0c;特此增加一篇。 QDir 是 Qt 框架中用于操作文件和目录的类&#xff0c;它提供了跨平台的文件系统访问接口&#xff0c;可以进行目录遍历、文件查找、创建、删除、移动等操作。以…

vu3+vite+supermap(超图)实现可视域分析

<template><div class="dialog-draggable"><el-dialog draggable destroy-on-close v-if="changeRangeVisibility" :modal="false" v-model="changeRangeVisibility"title="可视域分析" width="24%&quo…

科技感画册制作方法,视觉效果直接拉满

随着科技的不断进步&#xff0c;科技感画册制作也变得更加精彩和引人注目。通过巧妙地运用先进的设计工具和技术&#xff0c;以及结合创新的视觉元素&#xff0c;可以轻松地将画册的视觉效果直接拉满。 那你想知道怎么制作吗&#xff1f;现在我来教你这个方法吧&#xff0c;方法…

tomcat类加载机制

Tomcat是一个流行的开源的Java Servlet容器&#xff0c;用于部署和运行Java Web应用程序。在Tomcat中&#xff0c;类加载机制是非常重要的&#xff0c;它决定了应用程序中的类是如何被加载和管理的。 Tomcat的类加载机制遵循了Java的类加载机制&#xff0c;但也有一些特殊的地…

jni,android

Windows下JNI的使用教程 - sysu_huangwei - 博客园 (cnblogs.com) JNI的使用大致有以下4个步骤&#xff1a; 一、在Java中写native方法 二、用javah命令生成C/C头文件 三、写对应的C/C程序实现头文件中声明的方法&#xff0c;并编译成库文件 四、在Java中加载这个库文件并使用…

六、新闻主题分类任务

以一段新闻报道中的文本描述内容为输入&#xff0c;使用模型帮助我们判断它最有可能属于哪一种类型的新闻&#xff0c;这是典型的文本分类问题。我们这里假定每种类型是互斥的&#xff0c;即文本描述有且只有一种类型&#xff0c;例如一篇新闻不能即是娱乐类又是财经类&#xf…

JavaScript教程(十七)--- 模块化

JavaScript 模块 这篇指南会给你入门 JavaScript 模块的全部信息。 模块化的背景 JavaScript 程序本来很小——在早期&#xff0c;它们大多被用来执行独立的脚本任务&#xff0c;在你的 web 页面需要的地方提供一定交互&#xff0c;所以一般不需要多大的脚本。过了几年&…

企业Linux常见用户命令/补充Linux文件系统删除原理/userdel(故障原理/etc/skel)详谈-9628字

想提高自己想拿20k以上冲冲冲&#xff01;&#xff01;&#xff01;&#xff0c;想要从0 学习到linux架构师可以关注小编专栏 本来都很卷&#xff0c;你还不努力&#xff0c;想拿高薪&#xff0c;付出行动! linux难点第一阶段非常难 1.命令多复杂&#xff08;大家抓不住重点&am…

Python爬虫与数据可视化论文课题免费领取咨询

引言 作为一名在软件技术领域深耕多年的专业人士&#xff0c;我不仅在软件开发和项目部署方面积累了丰富的实践经验&#xff0c;更以卓越的技术实力获得了&#x1f3c5;30项软件著作权证书的殊荣。这些成就不仅是对我的技术专长的肯定&#xff0c;也是对我的创新精神和专业承诺…

boot https ssl

生成命令&#xff1a; keytool -importkeystore -srckeystore D:\sslTest.keystore -destkeystore D:\sslTest.keystore -deststoretype pkcs12keytool -genkeypair -alias "sslTestKey" -keyalg "RSA" -keystore "D:\sslTest.keystore"yml: s…

鸿蒙ArkTS小短剧开源项目进行中

鸿蒙小短剧开源项目进行中 短剧项目名称&#xff1a;CCShort-TV 短剧项目名称&#xff1a;CCShort-TV 使用ArtTS语言&#xff0c;API9以上&#xff0c;HarmonyOS系统的短剧开源代码&#xff0c;使用GSYVideoPlayer作为核心播放器的小短剧。主要以ArkTS&#xff0c;ArkUI编写为…

RISCV指令集体系简读之RV32M

RV32M向RV32I中添加了整数乘法和除法指令&#xff1b; RV32M具有有符号和无符号整数的除法指令&#xff1a;divide(div)和divide unsigned(divu)&#xff0c;它们将 商放入目标寄存器。在少数情况下&#xff0c;程序员需要余数而不是商&#xff0c;因此RV32M提供 remainder(rem…

使用IT-Tools+Cpolar在Windows搭建自己的IT工具箱并实现远程在线使用

文章目录 1. 使用Docker本地部署it-tools2. 本地访问it-tools3. 安装cpolar内网穿透4. 固定it-tools公网地址 本篇文章将介绍如何在Windows上使用Docker本地部署IT- Tools&#xff0c;并且同样可以结合cpolar实现公网访问。 在前一篇文章中我们讲解了如何在Linux中使用Docker搭…

协程:轻量级多线程编程的解决方案

文章目录 一、引入二、概念1、什么是协程2、轻量级怎么理解&#xff1f;为什么快&#xff1f;3、用途4、信息交换方式5、协程和线程的比较6、各语言对协程的支持 三、Kilim1、是什么2、原理 四、实践案例1、打印文字案例2、试试能创建多少个任务1&#xff09;多线程2&#xff0…

MercadoLibre(美客多)入仓预约系统操作流程-自动化约号(开篇)

目录 一、添加货件信息 二、输入货件信息 三、选择发货 四、填写交货日期 五、注意事项 MercadoLibre&#xff08;美客多&#xff09;于2021年10月18号上线了新预约入仓系统&#xff0c;在MercadoLibre美客多平台上&#xff0c;新入仓预约系统是一项非常重要的功能&#x…

【Scala中的package】

Scala中的package package com.zishi.scala.a03.pack/*** 使用打包技术来解决不同包下Cat类*/ object Demo {import com.zishi._val cat new abc.Cat()val cat2 new deg.Cat() }package com.zishi.abc {class Cat {} }package com.zishi.deg {class Cat {} }/*** 包也可以像…