语法复习之C语言与指针

news2024/9/25 21:29:29

内存是如何存储数据的?

  在C语言中定义一个变量后,系统就会为其分配内存空间。这个内存空间包括了地址和长度。将变量赋值后,该值就被写入到了指定的内存空间中。内存空间的大小一般以字节作为基本单位。
  普通变量存放的是数据,指针变量存放的是地址。

int a = 10 ; //定义了一个整型变量
int *a ;//定义一个指向整型的指针变量

  为什么指针要有数据类型?因为在定义指针的时候,不光要定义指针的起始地址,还要定义指针的地址长度,方便分配内存空间。而指针变量的数据类型就是内存空间长度。
              在这里插入图片描述
由图可以看到地址和数据一一对应。

取地址运算符和取值运算符

//如果要获取某个变量的地址,可以使用取地址运算符&
char *pa = &a;   //将字符串类型的变量a的地址赋值给字符串指针变量pa
int *pb = &f; 	//将整型类型的变量f的地址赋值给整型变量指针pb

//如果要访问指针变量指向的数据,可以使用取值运算符 *
int *a = 0x100000000//定义一个整型指针变量a,该指针指向的地址为0x10000000
b = *a ;   //将a指针指向的内存空间中0x10000000的值赋值给b
printf("%c, &d\n\r",*pa, *pb);

直接访问和间接访问

  通过指针变量来访问内存中的数据被称为直接访问
  通过定义变量并访问内存中的数据被称为间接访问

//间接访问
char *p_ptr = 0x10000000;
char p;
p = *p_ptr;
//直接访问
char p = 'a';

使用指针的注意事项

//避免访问未初始化的指针,因为不知道该指针指向何处。语法上正确,但是会产生未知错误。
int *a;
*a = 123;

数组与指针

数组与指针的基本关系

  数组名就是指针的首地址,也是数组第一个元素的地址。数组的下标代表的是指针的偏移,偏移量就是数组内存放的数据类型所占的字节数乘以下标。
  如果想用指针来指向数组,则可以直接用数组名赋值,或者用数组的第一个元素取地址。但是数组名和指针变量有区别。数组名属于右值,不可改变,但指针变量属于左值,可以改变。假如a是一个数组名。a++为错误写法。但是p=a;p++;是可以的。
  当指针变量p指向数组的第一个变量时,指针变量p+1则指向数组的第二个元素

#include<stdio.h>
int main(){
	char a[] = "FishC";
	int b[5] = {1,2,3,4,5};
	float c[5] = {1.1,1.2,1.3,1.4,1.5};
	double d[5] = {1.1,2.2,3.3,4.4,5.5};
    printf("*****************************************\n");
	printf("a[0] -> %p, a[1] -> %p, a[2] -> %p\n",&a[0], &a[1], &a[2]);
	printf("b[0] -> %p, b[1] -> %p, b[2] -> %p\n",&b[0], &b[1], &b[2]);
	printf("c[0] -> %p, c[1] -> %p, c[2] -> %p\n",&c[0], &c[1], &c[2]);
	printf("d[0] -> %p, d[1] -> %p, d[2] -> %p\n",&d[0], &d[1], &d[2]);
    printf("*****************************************\n");
    int *p;
    p = b;
	printf("p=b赋值时 p -> %p,\n",p);
    p = &b[0];
	printf("p = &b[0]赋值时 p -> %p,\n",p);
    printf("*****************************************\n");
    printf("*p = %d, *(p+1) = %d, *(p+2) -> %d\n",*p, *(p+1), *(p+2));
    printf("*****************************************\n");
	return 0 ;
}

输出结果为

*****************************************
a[0] -> 0x7ffd2fdaaa30, a[1] -> 0x7ffd2fdaaa31, a[2] -> 0x7ffd2fdaaa32
b[0] -> 0x7ffd2fdaa9c0, b[1] -> 0x7ffd2fdaa9c4, b[2] -> 0x7ffd2fdaa9c8
c[0] -> 0x7ffd2fdaa9e0, c[1] -> 0x7ffd2fdaa9e4, c[2] -> 0x7ffd2fdaa9e8
d[0] -> 0x7ffd2fdaaa00, d[1] -> 0x7ffd2fdaaa08, d[2] -> 0x7ffd2fdaaa10
*****************************************
p=b赋值时 p -> 0x7ffd2fdaa9c0,
p = &b[0]赋值时 p -> 0x7ffd2fdaa9c0,
*****************************************
*p = 1, *(p+1) = 2, *(p+2) -> 3
*****************************************

指针数组与数组指针

  指针数组是数组,数组指针是指针。
  指针数组是存放了多个指针的数组。数组指针是数组本身的指针,并不是指向数组第一个元素的指针。

指针数组

int *p1[5];

  首先从优先级开始分析,[]符号的优先级大于* ,所以优先看p1[5],这是一个数组,里面包含五个元素。后面看*,这是一个指针变量,所以p1[5]里面存放了五个指针变量,最后看int,表明了指针变量的存放的数据类型是int类型。结合起来就是定义了一个数组,数组的元素指针,指针指向的地址中存放的数据类型是int类型。

int a = 1;
int b = 2;
int c = 3;
int d = 4;
int e = 5;
int *p1[5] = {&a,&b,&c,&d,&e};

  指针数组的实际用法

#include<stdio.h>
int main(){
    char *p1[5] = {
        "char *a =\"hello\"代表的是一个字符串",
        "所以上一句中的a代表的是字符串的首地址",
        "char *p1[5]中的p1[5]存放了五个字符串的首地址",
        "%s代表用字符串的首地址来打印字符串",
        "所以%s中可以用p1[i]可以打印出字符串"
    };
    for(int i = 0; i < 5 ;i++){
        printf("%s\n",p1[i]);
    }
	return 0 ;
}

输出结果:

char *a ="hello"代表的是一个字符串
所以上一句中的a代表的是字符串的首地址
char *p1[5]中的p1[5]存放了五个字符串的首地址
%s代表用字符串的首地址来打印字符串
所以%s中可以用p1[i]可以打印出字符串

数组指针

int (*p2)[5]

  也是从优先级开始分析,括号里面的优先级最高,所以p2被定义成了一个指针,指向了一个含有五个元素的数组。指针的类型就是他指向的数据类型,int定义的就是数组元素的类型。所以这个数组指针的含义是定义了一个数组指针p2,指针指向了含有五个整型元素的数组。

#include<stdio.h>
int main(){
    int temp[5] = {1,2,3,4,5};  //  这是一个数组,temp是数组名。
    int (*p2)[5] = &temp;       //定义一个整形数组指针p2,p2指向数组temp本身 p2 = &temp
    int i;
    for(i=0;i<5;i++){
        printf("%d\n",*(*p2 + i));  //p2指向数组本身 p2 = &temp  *p2 = temp  所以*(*p2 + i) = *(temp + i)  即可遍历数组元素
    }
    return 0;
}

输出结果

1
2
3
4
5

函数与指针

  有些函数需要传递参数

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

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

相关文章

75 应急响应-数据库漏洞口令检索应急取证箱

必须知识点 1.第三方应用由于是选择性安装&#xff0c;如何做好信息收集和漏洞探针也是获取攻击者思路的重要操作&#xff0c;除去本身漏洞外&#xff0c;提前预知或口令相关攻击也要进行筛选 2.排除三方应用攻击行为&#xff0c;自查漏洞分析攻击者思路&#xff0c;人工配合工…

Qt 项目实战 | 多界面文本编辑器

Qt 项目实战 | 多界面文本编辑器 Qt 项目实战 | 多界面文本编辑器界面设计创建子窗口类实现菜单的功能更新菜单状态与新建文件操作实现打开文件操作添加子窗口列表实现其他菜单功能 完善程序功能保存窗口设置自定义右键菜单其他功能 小结项目源码 官方博客&#xff1a;https://…

初试Shiro

Shiro是一个用于身份验证、授权和会话管理的Java安全框架。它提供了一套易于使用的API&#xff0c;可以帮助开发人员构建安全性强大的应用程序。 环境准备 添加依赖 <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</ar…

vueDay04——v-if else show

一、v-if的使用 我们可以像c语言一样去使用v-if结构 比如单用v-if&#xff0c;连用v-if v-else&#xff0c;或者是v-if v-else-if v-else 注意&#xff1a; 1.v-if v-else-if需要绑定值,而v-else不需要绑定值 2.if结构可以用在不同的标签类型之间 <div v-if"fir…

【MATLAB源码-第57期】基于matlab的IS95前向链路仿真,输出误码率曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 IS-95&#xff0c;也被称为cdmaOne&#xff0c;是第一代的CDMA&#xff08;Code Division Multiple Access&#xff0c;码分多址&#xff09;数字蜂窝通信标准。IS-95的全称是Interim Standard-95&#xff0c;最初由Qualcomm…

灵活、可用、高扩展,EasyMR 带来全新 Yarn 的队列管理功能及可视化配置

YARN&#xff08;Yet Another Resource Negotiator&#xff09;是 Hadoop 生态系统中的资源调度器&#xff0c;主要用于资源管理和作业调度。YARN 自身具备队列管理功能&#xff0c;通过对 YARN 资源队列进行配置和管理&#xff0c;实现集群资源的分配&#xff0c;以满足不同应…

Doceker-compose——容器群集编排管理工具

目录 Docker-compose 1、Docker-compose 的三大概念 2、YAML文件格式及编写注意事项 1&#xff09;使用 YAML 时需要注意下面事项 2&#xff09;ymal文件格式 3&#xff09;json格式 3、Docker Compose配置常用字段 4、Docker-compose的四种重启策略 5、Docker Compos…

[微服务]Spring Cloud Sleuth全链路追踪

Spring Cloud Sleuth全链路追踪 全链路追踪组件追踪的数据遵循的规则: 1,Span:基本单元; 执行一次服务调用就生成一个span,用于记录当时的情况 ,以一个64位ID作为唯一标识.span还有其他数据标识如摘要,时间戳信息,关键tag等; 2,Trace:一次请求; 以一个64位ID为唯一标识,可以…

各品牌PLC存储器寻址的规则

在PLC编程时&#xff0c;字节或多字节的变量一般支持绝对地址寻址&#xff08;比如&#xff0c;IW0、MD4等&#xff09;。要想正确寻址&#xff0c;则必须要搞清楚寻址的规则。目前常见的规则有两种&#xff1a;字节寻址和字寻址。下图清晰地表达了两种规则的编号情况&#xff…

AI:WEB 1 靶机

1.找ip地址 2.检测端口 3.上文件检索 发现是apache 的组件 4.漏洞扫描攻击 nikto -h 网站 扫描网站漏洞 目录爆破 5.利用发现敏感目录 6.登录 发现 都是403 使用上层发现ok 这是一个查询功能点 7.敏感目录 sql注入 检验 详细信息 检测到注入方式 查看数…

系统架构设计师之RUP软件开发生命周期

系统架构设计师之RUP软件开发生命周期

EasyAR使用

EazyAR后台管理&#xff0c;云定位服务 建模 需要自行拍摄360度视频&#xff0c;后台上传&#xff0c;由EazyAR工作人员完成构建。 标注数据 需要在unity安装EazyAR插件&#xff0c;在unity场景编辑后&#xff0c;上传标注数据。 uinity标注数据 微信小程序中使用&#x…

Kali Linux 安装使用远程桌面连接远程服务器

1. 安装远程桌面连接软件 目前为止&#xff0c;我们已经可以通过其它机器以远程桌面的方式连接 Kali Linux&#xff0c;但想要使用 Kali Linux 远程连接其它机器还无法做到&#xff0c;下面就看看如何实现。 更新软件源列表&#xff1b; $ sudo apt-get update $ sudo apt-g…

二、可行性分析与需求分析

文章目录 概念考点练习题一、可行性分析与需求分析1.可行性分析的任务2.可行性研究3.甘特图4.数据流图5.数据字典数据字典的内容 6.需求分析7. 实体联系ER图8. 状态转换图 二、练习题 概念考点练习题 一、可行性分析与需求分析 1.可行性分析的任务 用最小的代价在尽可能短的时…

Xilinx MicroBlaze定时器中断无法返回主函数问题解决

最近在使用Xilinx 7系列FPGA XC7A100T时&#xff0c;运行MicroBlaze软核处理器&#xff0c;添加了AXI TIMER IP核&#xff0c;并使能定时器溢出中断&#xff0c;发现定时器触发中断后&#xff0c;无法返回主函数的问题&#xff0c;最后发现修改编译器优化等级就正常了。 FPGA型…

量子力学的基础公设

量子力学的基础公设 - 知乎

MySQL---JDBC编程

文章目录 什么是JDBC&#xff1f;JDBC的工作原理JDBC的使用添加依赖创建数据源DataSource创建数据库连接Connection创建操作命令Statement执行SQL指令释放资源 通过JDBC演示CRUD新增查询修改删除 什么是JDBC&#xff1f; JDBC&#xff1a;Java Database Connectivity&#xff…

10000阅读量感言

目录 前言 10000阅读量 回忆 感谢 结尾 前言 2023年10月25日20点26分&#xff0c;我终于突破10000阅读量了&#xff01;为了记录下来&#xff0c;我写下了这篇博客。 10000阅读量 以上是我卡点截的一张图&#xff0c;我当时看到自己10000阅读量还是很惊喜的&#xff0c;还…

算法训练营第一天 704 .二分查找、27.移除元素

算法训练营第一天 | 704 .二分查找、27.移除元素 &#xff08; 一 &#xff09;、704 二分查找 题目链接&#xff1a;https://leetcode.cn/problems/binary-search/description/ 解题思路&#xff1a; ​ 数组 nums 是有序排列的&#xff0c;二分查找每次都是对半查询&…

【离散数学必刷题】命题逻辑(第一章 左孝凌)刷完包过!

复习16题&#xff1a; 【1】下列哪个语句是真命题&#xff08;&#xff09; A、今天天气真好&#xff01; B、我正在说谎。 C、如果7 2 10 &#xff0c;那么4 6 5。 D、如果7 2 9 &#xff0c; 则 4 6 5。 对于A&#xff0c;只有具有确定真值的陈述句才是命题&#xf…