9.C基础_指针与数组

数组指针(一维数组)

数组指针就是" 数组的指针 ",它是一个指向数组首地址的指针变量。

1、数组名的含义

对于一维数组,数组名就是一个指针,指向数组的首地址。

基于如下代码进行分析:

int a[5] = {1,2,3,4,5};
int* p = a;
  • a是数组a[5]的数组名,在这里a是个常量,一定指向的是a[5]的首地址,不能进行" ++ "改值运算。
  • p是一个指针变量,它指向了a[5]的首地址,所以它是一个数组指针。在这里p是一个变量,可以进行" ++ "改值运算

2、数组名索引与指针索引

当我们想要访问1这个值的时候,可以有a[0]、*(a+0)、*(p+0)、p[0] 这四种访问形式。

  • a[0]:基本的下标法访问
  • *(a+0):a可以看作首地址,偏移量为数组的类型int大小,找到地址后解引用也可访问1这个值
  • *(p+0):p保存了数组首地址,偏移量为int大小,通过解引用访问地址
  • p[0]:特殊,记住即可

注意:*(p+0)、p[0]这两种方法是指针偏移的方法,它实际表示的值与p指向的位置有关。比如p指向的是a[1]这个位置,那么*(p+0)、p[0]访问的不是a[0]而是a[1],而*(p-1)、p[-1]访问的才是a[0]。

3、数组名与数组元素取地址

数组名a与数组元素取地址&a[ i ]它们的值一样,偏移量也一样。但数组名表示整个数组,数组元素取地址仅仅是一个指针。下面分析" a、&a[0]区别 "、" a+1、&a[0]+1 区别"

a、&a[0]的相同点:

  • 地址值相同、偏移量也相同。
  • 都是常量,都不能进行++等变值操作。

a、&a[0]的不同点:

  • a不仅仅指向数组首地址,还可以代表数组;
  • &a[0]只是一个指针,什么都不代表。

4、&a是什么

一维数组可以看成列指针,取地址之后变为行指针。

&a的作用与二维数组名类似:a看成列指针,偏移一个数据元素,&a看成行指针偏移一行。

数组指针(二维数组)

1、一维指针遍历二维数组

由于二维数组的元素在内存中是按行序进行排列的,内存排列依旧是连续的。所以在内存方面,它与一维数组没有任何区别,具体的二维数组内存分配如下:

遍历的代码如下:

#include <stdio.h>/* 计算二维数组总大小 */
#define ARRAY2_SIZE(array,type) 	sizeof(array)/sizeof(type)
/* 计算二维数组中一维数组大小(列大小) */
#define ARRAY2_COL_SIZE(array) 		sizeof(array[0])
/* 计算二维数组的列数 */
#define ARRAY2_COL_NUM(array,type)	ARRAY2_COL_SIZE(array)/sizeof(type)
/* 计算二维数组的行数 */
#define ARRAY2_ROW_NUM(array,type) 	sizeof(array)/ARRAY2_COL_SIZE(array)int main(){int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};int *p = NULL; int col,row;int i;col = ARRAY2_COL_NUM(a,int);row = ARRAY2_ROW_NUM(a,int);p = &a[0][0];//注意这里的赋值,p赋值的是a[0][0]的地址,而不是直接赋值数组名a for(i=0;i<row*col;i++){printf("%d %d\n",*(p+i),p[i]);} return 0;
}

上述代码有一个注意点,p=&a[0][0]而不是p=a。在二维数组中,尽管&a[0][0]的值与a相同,都是指向数组首地址,但是它们的偏移量不同。

2、二维数组的数组指针

二维数组名是一个指向二维数组的首地址的常量。它是一个代表二维数组,偏移量以行为单位。例如:int a[2][3]它每3列为一行,假设首地址为0x00,那么a+1 = 0x00 + sizeof(int) * 3。

指向二维数组的数组指针被称为" 行指针 "。它的定义形式为:<数据类型>(*变量名)[列数],如上述的int a[2][3],它的数组指针为:int (*p)[3] = a。

3、二维数组元素分析

二维数组可以看成两部分组成:二维数组由多个一维数组组成,一维数组由多个数据组成。

所以二维数组名解引用之后得到的是一维数组名,一维数组名解引用后得到的是数据元素。

即:*a+i = a[i],&a[0] = a

a 与 &a[0] 的区别

相同点:

  • 地址值一样,偏移量一样。
  • 都是常量,都不能进行++等变值操作。

不同点:

  • a不仅仅指向数组首地址,还可以代表数组;
  • &a[0]只是一个指针,sizeof(&a[0])返回的是指针大小,而不是二维数组大小

下面是用二维数组的数组指针来遍历的代码:

#include <stdio.h>
/* 计算二维数组总大小 */
#define ARRAY2_SIZE(array,type) 	sizeof(array)/sizeof(type)
/* 计算二维数组中一维数组大小(列大小) */
#define ARRAY2_COL_SIZE(array) 		sizeof(array[0])
/* 计算二维数组的列数 */
#define ARRAY2_COL_NUM(array,type)	ARRAY2_COL_SIZE(array)/sizeof(type)
/* 计算二维数组的行数 */
#define ARRAY2_ROW_NUM(array,type) 	sizeof(array)/ARRAY2_COL_SIZE(array)
int main(){int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};int (*p)[4] = a;int row,col;int i,j; row = ARRAY2_ROW_NUM(a,int);col = ARRAY2_COL_NUM(a,int);for(i=0;i<row;i++){for(j=0;j<col;j++){printf("%-2d ",*(*p+j));//p是二维数组指针,*p就是a[i]即一维数组的指针,偏移量为int }printf("\n");p++;//p是二维数组指针,偏移量为sizeof(int)*col即按行偏移	} 	return 0;
} 

上述代码中也可以用一个指针来寻址:例如a[3][4],寻址a[2][1]只需访问&a[0][0]+2*4+1

练习:使用a来访问a[2][1]这个元素

首先需要偏移到第2行,之后偏移到第1列,最后取值

  • 偏移到第2行:a+2
  • 偏移到第1列之前需要先转换成一维数组名:*(a+2)即a[2]
  • 偏移到第1列:*(a+2)+1
  • 取值:*(*(a+2)+1)

4、&a是什么

二维数组的&a分析方法与一维数组的分析类似。

  • 在一维数组中,我们把a看作列地址,&a看成行地址。
  • 在二维数组中,我们把整个二维数组看成列地址,代表偏移量为一行。&a看成行地址,代表偏移量为一整个二维数组。

数组指针(字符串)

字符串是一维数组的一种形式,数组指针的性质与一维数组的数组指针性质完全一样。

下面分析字符串常量与字符串变量的区别:

指针直接赋值字符串,而不是字符数组名时,该指针指向的就是字符串常量。

/* p指向字符串常量,不可修改值 */
char* p = "Hello";/* p指向字符串变量,可以修改值 */
char a[] = "hello";
char*p = a;

相同点:

  • 都是存放的字符串的首地址,都可以用%s进行打印

不同点:

  • 对于char* p = "Hello";因为它是一个常量,所以不允许修改,即:*p = 'a'是不合法的。
  • 对于char* p = a;因为它是一个变量,所以允许修改,即:*p = 'a'是合法的。

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

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

相关文章

语言模型-神经网络模型(二)

神经网络模型语言模型 神经网络模型神经网络的分类神经网络模型和Ngram对比应用一-话者分离对比优劣 应用二-数字归一化应用三-文本打标 神经网络模型 释义&#xff1a; 与ngram模型相似使用&#xff0c;前n个词预测下一个词&#xff0c;输出在字表上的概率分布&#xff1b;过…

如何设置 Visual Studio Code 的滚轮缩放功能

Visual Studio Code (VSCode) 是一个强大的代码编辑器&#xff0c;提供了许多便捷的功能来提高开发效率。其中之一就是通过滚轮缩放字体大小。以下是详细的设置步骤&#xff1a; 步骤 1&#xff1a;打开设置页面 首先&#xff0c;启动 Visual Studio Code。在左上角点击 “文…

【机器学习基础】线性回归

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科&#xff0c;通过算法和模型让计算机从数据中学习&#xff0c;进行模型训练和优化&#xff0c;做出预测、分类和决策支持。Python成为机器学习的首选语言&#xff0c;…

集成视触觉传感器的机器人操作学习

强化学习是一种仿人学习的方法&#xff0c;其在不断与环境交互试错的过程中进行学习&#xff0c;提高自身的认知。其具有如下的优点&#xff0c;首先是数据依赖性低&#xff0c;强化学习通过与环境的交互来学习&#xff0c;减少了对标记数据的依赖性&#xff0c;可以大量的减少…

Linux 系统框架分析(一)

一、linux内核结构框图 对内核结构框图有个总体的把握&#xff0c;有助于理解为什么驱动要这样写&#xff0c;为什么写的应用程序所用的C库接口能够产生这么多的事情。 框图可以看出来&#xff0c;linux系统&#xff0c;包括五个系统 一、Linux内核结构介绍 Linux 内核是操作…

Spring及相关框架的重要的问题

Java框架 问题一&#xff1a;Spring框架中的单例bean是线程安全的吗&#xff1f; 看下图&#xff0c;不能被修改的成员变量就是无状态的类&#xff0c;无状态的类没有线程安全问题&#xff0c;所以在开发中尽量避免可修改的成员变量。 回答&#xff1a;不是线程安全的&#xf…

Oracle一对多(一主多备)的DG环境如何进行switchover切换?

本文主要分享Oracle一对多(一主多备)的DG环境的switchover切换&#xff0c;如何进行主从切换&#xff0c;切换后怎么恢复正常同步&#xff1f; 1、环境说明 本文的环境为一主两备&#xff0c;数据库版本为11.2.0.4&#xff0c;主要信息如下&#xff1a; 数据库IPdb_unique_n…

Github 2024-08-09 开源项目日报 Top10

根据Github Trendings的统计,今日(2024-08-09统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目6TypeScript项目4Jupyter Notebook项目1Cuda项目1Sentry:开发者优先的错误跟踪和性能监控平台 创建周期:5093 天开发语言:Python,…

android系统中data下的xml乱码无法查看问题剖析及解决方法

背景&#xff1a; Android12高版本以后系统生成的很多data路径下的xml都变成了二进制类型&#xff0c;根本没办法看xml的内容具体如下&#xff1a; 比如想要看当前系统的widget的相关数据 ./system/users/0/appwidgets.xml 以前老版本都是可以直接看的&#xff0c;这些syste…

旅游出行必备商城小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;新闻类型管理&#xff0c;新闻资讯管理&#xff0c;商品类型管理&#xff0c;旅游商品管理&#xff0c;旅游景点&#xff0c;景点分类&#xff0c;系统管理 微信端账号功能包括&am…

GitHub的常用操作

目录 GitHub GitHub加速 克隆GitHub上的项目到本地 克隆GitHub上指定分支的项目 把本地项目上传到GitHub上管理 删除分支里的内容 单个仓库管理多个项目 上传项目到新建的分支 目前正在逐步熟悉GitHub&#xff0c;打算把整理好的代码上传到GitHub上&#xff0c;建立属…

C++ 类与对象

面向对象程序设计基本特点 特点&#xff1a; 抽象&#xff08;数据抽象&#xff0c;行为抽象&#xff09; 数据抽象&#xff1a;int hour,int minute.....,车&#xff1a;长&#xff0c;宽&#xff0c;高.... 功能抽象&#xff1a;showTime(),setTime() .....车&#xff1a;刹车…

使用Cisco进行模拟配置OSPF路由协议

OSPF路由协议 1.实验目的 1&#xff09;理解OSPF 2&#xff09;掌握OSPF的配置方法 3&#xff09;掌握查看OSPF的相关信息 2.实验流程 开始 → 布置拓扑 → 配置IP地址 → 配置OSPF路由并验证PC路由的连通性 → 查看路由器路由信息 → 查看路由协议配置与统计信息 → 查看O…

【从零开始一步步学习VSOA开发】VSOA命令行工具vcx

VSOA命令行工具vcx vcx 介绍 vcx 是一个使用 VSOA RPC 客户端功能执行器&#xff0c;支持 RPC SET/GET 调用。 [rootsylixos:/root]# [rootsylixos:/root]# vcx -help USAGE: vcx [options] url -h : Show help message. -v : Show vcx version. -z …

[MRCTF2020]PYWebsite-1

打开以后查看源码信息 看到flag.php试着打开 提示看到&#xff0c;需要后端审计代码&#xff0c;而且应该要改ip&#xff0c;改成自己本地&#xff0c;burp抓包看一下 改X-Forwarded-For:127.0.0.1 得到flag flag{74242eb7-844f-4638-8aae-9ec37870d585}

通过LLM大模型将「白雪公主的故事」转为图数据存储

&#x1f4a1; 本次将使用LLM大模型将「白雪公主的故事」转为图数据存储于neo4j数据库中&#xff0c;并展示图数据部分的效果 故事内容 很久很久以前&#xff0c;在一个遥远的王国里&#xff0c;有一位美丽的**王后**生下了一个皮肤像雪一样白皙、嘴唇像血一样鲜红的**女儿**…

网页设计模板范例

随着互联网的发展&#xff0c;网页设计变得越来越重要。一个吸引人的网页设计可以吸引更多的用户&#xff0c;提升用户体验&#xff0c;并且使网站内容更加易于浏览和理解。在这篇文章中&#xff0c;我将为大家介绍一个网页设计模板范例。 1. 选择合适的颜色和字体&#xff1a;…

golang for range time.Ticker 和 time.Timer时间通道使用示例 - 每隔指定时间执行一次,执行指定时长后退出执行

golang中的 ticker和timer时间通道除了可以使用for select case语句来执行外&#xff0c; 还可以使用 for range语句来执行ticker或者timer时间通道。 for range time.Ticker 和 time.Timer时间通道使用示例 下面的示例演示了time.Ticker 和 time.Timer的区别和使用演示。 Ti…

JAVA分布式CAP原则

分布式CAP原则主要是使用SpringCloud框架的时候会涉及到该部分知识点 CAP原则指的是在一个分布式系统中&#xff0c;一致性&#xff0c;可用性&#xff0c;分区容错性 实际的项目开发中&#xff0c;这三者往往是不可兼顾的。 AP&#xff1a;牺牲一致性&#xff0c;保证可用性…

【学习笔记】Matlab和python双语言的学习(动态规划)

文章目录 前言一、动态规划动态规划的基本步骤示例1示例2 三、代码实现----Matlab1.示例12.示例2 四、代码实现----python1.示例12.示例2 总结 前言 通过模型算法&#xff0c;熟练对Matlab和python的应用。 学习视频链接&#xff1a; https://www.bilibili.com/video/BV1EK411…