【C语言复习(十二)】数组基础

C语言期末复习|最后的总结 在 C 语言中,自定义标识符是由程序员为变量、函数、结构体、联合体、枚举、宏、标签等命名时使用的名称。1.大小写字母含义不同。APH 和 aph 代表不同的变量。2.C语言的标识符由字母、数字和下划线组成。3.第一个字符必须是字母或下划线。4.第一个字符不能是数字。9ab是非法的用户标识符。5.C语言中的变量名属于标识符。6.C 语言的关键字(保留字)是具有特殊含义的标识符,它们被 C 语言的编译器保留,不能用作变量名、函数名等普通标识符。7.main。 阅读详情

1、数组的概念

数组是相同类型的变量的有序集合;如int num[5];


2、数组地址与数组名

数组名代表数组首元素的地址;

数组的起始地址需要使用取地址符&才能得到;

数组首元素的地址值与数组的起始地址值相同,但却是不同的两个概念,如上图中所示;

3、数组名

数组名通常可以看作是一个常量指针,即它不能作为左值被赋值,只能作为右值赋值给其他变量;

数组名“指向”的是内存中数组首元素的位置(即首元素地址);

只有在下列场合中,数组名不做为常量指针:

数组名作为sizeof操作符的参数;数组名作为&运算符的参数;

 

4、定义为指针,声明为数组:(指针和数组并不相同)

分析如下示例:
/*another.c*/
char* p="Hello World";


/*test.c*/
#include <stdio.h>
extern char p[];
int main()
{
    printf("%s\n",p);
    return 0;
}


注意观察,首先在another.c文件中定义一个字符指针变量p,并指向一字符串常量;然后test.c文件中把p声明为外部变量,表示它定义在其它文件中,但这里的声明和它的定义稍微不同,声明成了一个字符数组,思考一下,运行程序能打印出”Hello World”吗??
运行结果:


不出意外,都会看到这么一串乱码的字符,这是为什么呢?为什么输出的不是”Hello World”??

简单的分析:

首先编译器在编译another.c文件是,发现定义了变量,那么为此变量分配内存空间,并完成初始化,并且编译器会在符号表中加入此变量:


然后编译test.c,发现p被声明为外部变量,且为字符数组,所以编译器把从变量p的起始地址开始的一段内存空间当作数组空间:注:这里p变量的值实际上就是Hello World字符串常量的起始地址!

 

最后运行程序,我们尝试输出字符数组p内的值,可以发现,实际上这里输出的却是从0xAABBCC00地址开始的值,而我们实际想输出的却是内存0xBBCCDD00单元开始的值;所以结果显然不是Hello World!

详细分析:

要论述这个问题的本质,实际上还要明白,指针变量在使用时,是要经过一次寻址操作的,比如上面的指针变量char* p;如果使用它输出字符串,那么会先读取出指针变量中存放的地址值,再从此地址开始读取我们想要输出的值,而对于数组,比如char p[];要输出它的值,则是直接从数组的起始地址开始读取值;

 

手动寻址,改正错误??

既然上面分析了,数组的操作中不存在寻址操作,那么我们可以手动完成它!

看上面的两张图可知,此时数组变量p的前四个内存单元实际上存储的是一个指针值,该指针值是Hello World字符串常量的存储地址!而此时p作为一个数组,那么数组名p就代表该数组的首元素地址,利用这一点,直接将p强制转换为一个无符号整形指针,然后读取这个指针的值,再作为char*类型输出,就能得到Hello World!

做如下的改动:

printf("%s\n",(char*)(*((unsigned int*)p)));

这样就能输出Hello World了!

为什么能正确输出??为什么要用int*??

如果我们改成:

printf("%s\n",(char*)(*((char*)p)));

就不能读取到Hello World!这是为什么呢??难到一定要用int*??仔细分析一下此语句:
首先,当前p应该是一个字符数组,那么p就代表数组的首元素地址,它的值也等于数组的起始地址,假设为:0xAABBCC00,因为在编译another.c文件时,p为指针变量,并进行了初始化,所以它的0xAABBCC00--0xAABBCC03这个四个字节应该保存的是Hello World的真实地址,回到test.c,那么当前字符数组的前四个字节空间存放的应该是一个无符号整形值,也就是Hello World的存储地址;现在p的值为0xAABBCC00,我们进行强制类型转换:(unsigned int*)p;

这时候我们所得到的,其实是另外一个unsigned int*指针,该指针指向了当前字符数组p的起始地址,也就是:0xAABBCC00;便于理解,可以这样写:

    unsigned int* L=(int*)p;
    printf("%s\n",(char*)(*L));

指针L指向了当前字符数组的起始地址,且认为0xAABBCC00--0xAABBCC03四个字节存放的是一个无符号整数,而这个无符号整数,就是我们迫切需要的Hello World 的存储地址,假设为0xBBCCDD00,即是当前指针变量L中存放的地址为:0xBBCCDD00,然后我们再对L指针做*运算,便可访问0xBBCCDD00地址段,再把它转换为char*类型指针,最后用%s的格式输出,就能得到Hello World了!

如果对p的强制转换写作(char*)p,那么得到的指针虽也指向当前字符数组的起始地址,但是它将把这部分内存中的值当作一个字节一个字节的字符,从而无法通过*((char*)p)得到原Hello World的存储地址,只能得到一个字节的数据;

5、数组小结

数组是一片连续的内存空间;

数组的起始地址和数组首元素地址值相同,意义不同;

数组名在大多数情况下被当成常量指针处理;

数组名不是指针,在外部声明时不能混淆;

C语言期中复习训练 1.以下程序中printf("x");执行的次数是:(5) #include <stdio.h> int main() { int x=0,y=10; while(x<y) { x++;y--; printf("x"); } return 0; } 2.以下程序在运行时输入234,则程序的运行结果是:(44556) void main() { int c; while((c=getchar())!='\n') { 阅读详情

相关推荐

从科研小白到动物行为分析:我的DeepLabCut 3.0安装与初体验全记录

本文记录了从科研小白到成功安装并使用DeepLabCut 3.0进行动物行为分析的全过程。详细介绍了Anaconda环境配置、CUDA版本选择、DeepLabCut安装步骤及验证方法,并分享了初体验中的实用技巧和跨学科研究心得,为生物研究者提供了AI工具应用的实战指南。

weixin_30235225的博客 402

指针指向数组并指定数组首地址的一种方法

今天想到C语言可以为一个参数指定地址,那么如何为一个数组指定首地址呢? 借鉴参数指定地址的方法,先想到用一个指针来指向一个数组,同时定义数组的数据类型,我是这样定义的 short (*ptr)[1024; 这样就定义了一个指针,该指针指向数组类型为short类型,切长度为1024,但是这个指针或者说是数组并没有初始化的地址, 于是需要给它初始化一下,也就是指定数组的起始地址,我是这样做的

doumeile1的博客 1万+

深入解析MSPM0系列Keil开发中‘ti_msp_dl_config.h‘缺失问题的根源与修复

本文深入解析TI MSPM0系列Keil开发中'ti_msp_dl_config.h'文件缺失问题的根源与修复方法。该错误常见于编译时提示file not found,主要因SysConfig工具未正确生成或工程路径配置错误导致。文章提供了从环境检查、手动生成文件到工程配置调整的系统化解决方案,帮助开发者快速解决这一常见KEIL开发难题。

gold的博客 970

C语言——数组的首元素地址和数组地址

数组地址、数组首元素地址之间的区别

xuandlu的博客 6191

SAP MM自动化进阶:STO交货单自动创建的配置与优化

本文深入解析了SAP MM模块中实现公司间库存调拨订单(STO)交货单自动创建的完整配置流程与优化策略。通过激活自动交货与绑定发货点两大核心配置,打通自动化链路。重点探讨了如何集成ATP可用性检查以智能处理库存不足等异常场景,确保自动化流程的可靠性与业务贴合度,并提供了进阶监控与问题排查方法,助力企业显著提升供应链效率。

weixin_29206669的博客 124

Kettle安装与使用

Pentaho Data Integration作为一个端对端的数据集成平台,可以对多种数据源进行抽取(Extraction)、加载(Loading)、数据落湖(Data Lake Injection)、对数据进行各种清洗(Cleasing)、转换(Transformation)、混合(Blending),并支持多维联机分析处理(OLAP)和数据挖掘(Data mining)。勺子(spoon.bat/spoon.sh):是一个图形化的界面,可以让我们用图形化的方式开发转换和作业。

jnrjian的博客 1万+

C语言定义数组起始地址对齐方式(IAR C99 Kinetis K66)

前言前几天,主管找我问关于定义变量起始地址对齐方式的问题。下面介绍一下问题:上位机生成了一个参数数组 char para[36541] = {…} ;数组比较大,已经内建好了结构体,只要按照指针指到头部地址即可正常读取出来,但是由于处理器读取int 或者 float 数据类型比较要求数据地址是四字节对齐的,而我们这个数组存放在内存中是以两个字节对齐的,这就导致了CPU无法读取数据并死机在了读取flo

爪爪熊的博客 5630

湿敏电阻HR202的两种驱动方案实测:IO充放电法 vs. 交流方波ADC法,哪个更适合你?

本文深入评测湿敏电阻HR202的两种驱动方案:IO充放电法和交流方波ADC法。通过原理图分析、精度实测和资源占用对比,揭示交流方波ADC法在精度和稳定性上的优势,特别适合长期监测场景。同时提供IO充放电法在资源受限情况下的应用建议,帮助工程师根据项目需求做出最优选择。

weixin_30421809的博客 466

C语言中关于数组名什么情况为首元素地址,什么情况为整个数组的地址的问题。

但是&arr和&arr+1相差40个字节,这就是因为&arr是数组的地址,+1操作是跳过整个数组的。这⾥我们发现&arr[0]和&arr[0]+1相差4个字节,arr和arr+1相差4个字节,是因为&arr[0]和arr都是。• &数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素的地址是有区别的)• sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表示整个数组,计算的是整个数组的⼤⼩,除此之外,任何地⽅使⽤数组名,数组名都表⽰⾸元素的地址。

QinMou 835

终于找到两个稳定好用的Docker镜像加速源,拉取速度提升几十倍!

国内使用Docker经常遇到镜像拉取慢、超时失败的问题🐳 本文分享两个亲测好用的免费镜像加速源⚡ 实测拉取速度从十几分钟缩短到几十秒,稳定性接近100%📊 支持一键配置脚本,支持多平台使用✨

XiaoqiangClub的博客 952

SAP BOM批量反查代码分享

SAP BOM反查批量查询代码分享

我小时候很黑的博客 4972

C语言——数组指针

- 数组指针:数组中的第一个元素的地址,也就是数组的首地址。 - 指针数组:用来存放数组元素地址的数组,称之为指针数组。

qixi_ao的博客 915

Windows 下 OpenClaw(小龙虾) 安装全记录:从零到一的保姆级图文教程(持续更新中)

本文主要介绍了Windows 下 OpenClaw 安装全记录:从零到一的保姆级图文教程,希望能对学习使用OpenClaw 的同学们有所帮助。 文章目录 1. 背景 2. 实战教程 2.1 步骤一 安装Node.js 2.2 步骤二:安装并配置OpenClaw 2.3 步骤三:配置模型 2.4 步骤四:对话 3. 后续使用步骤

weixin_43178406的博客 16万+

C语言基础总结

我学习的第一门编程语言是Java,所以之前一直没有系统学习过C语言。这篇文章主要就是我学习过程的一个总结,方便以后复习查看。

weixin_50216991的博客 2万+

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

专升本C语言——资料复习大全(需要完整版请私信作者)

【解析】结构化程序主要由3种基本控制结构组成,顺序结构是最基本的算法结构,当执行由这些语句构成的程序时,将按这些语句在程序中的先后顺序逐条执行,没有分支,没有转移,没有步骤之间的相互约束,没有对某一步骤的多次使用,完全按照步骤的原有次序依次执行,B选项叙述正确。【解析】C编译程序把文件后缀为C的源程序文件编译成文件后缀为.obj的二进制文件,链接将一个或多个目标文件与程序用到的库文件连接起来,形成一个可以在操作系统直接运行的执行程序.exe,故排除B、C、D项,答案选择A选项。故选项A、D说法正确。

Cherry的博客 1万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

【C语言】复习——数组 详细版

哈喽,大家好,我是小延!本期主要介绍了C语言中数组的相关知识。通过好几个示例代码详细说明,可以快速帮助初学者理解数组的相关概念和使用方法。

HuaJ_的博客 2207

【C语言复习专题】数组

详细介绍一维数组和二维数组的语法和使用以及一些关于数组的算法练习

ChiaWei_Lee的博客 1097

C语言复习

本文通过菜鸟教程、《C程序设计》课本以及课件对C语言难点进行复习梳理 C语言知识点大概梳理图 文章目录一、程序设计基础1、语言对比 [1]2、结构化程序设计3、面向对象程序设计4、C程序开发步骤二、数据类型与表达式1、数据类型2、进制计数3、信息存储单位4、常量(Constant)5、存储类别6、运算符三、程序控制结构1、格式化输出四、函数1、函数声明和函数原型2、标准库函数2、内联函数3、全局变量五、预处理命令1、文件包含2、条件编译六、数组1、多维数组作为函数的参数2、字符数组七、指针1、行位移量与元

MAN_Sue的博客 2270

C语言复习笔记--数组

如下图:我们通常用下标引用符[ ]来访问数组元素.例如我们访问。

2301_80159237的博客 1033

C语言数组相关问题深度理解

大家好呀!我是小杨。小杨把C语言中的数组中常见的问题做了一个小总结,希望在方便自己理解复习的同时也能够帮助到大家。

小杨的博客 3621

C语言复习笔记

C语言,编程入门基础。初学者必备!!!

lonelysnowman的博客 2930

C语言知识点复习梳理

C语言知识点复习梳理 C语言的知识点讲完了,接下来就是做一下整理与总结,然后就会进入其他知识的学习。 本文目录如下: 基础知识。 顺序程序设计。 数据类型。 标准输入输出。 进制转换。 选择结构。 循环结构。 数组。 函数。 指针 结构体。 文件。 题外话 这里就是说一些我觉得很基础的问题,无关紧要,但是希望可以解决你的疑惑。 有什么好的C语言...

qq_37864510的博客 3273

C语言复习整理(数组以前,自用)

数值型数据间的混合运算规则为:(1) 整型数据中字符型(char)和短整型(short)转换成基本整型(int),基本整型(int)转换成长整型(long),有符号(signed)转换成无符号(unsigned);j:k,因此第二次条件运算的结果为4。C语言逻辑与表达式(expr1 && expr2)的执行过程是:先计算expr1的值,若expr1的值为真,则计算expr2的值,并根据expr2的值结合真值表决定(expr1 && expr2)的结果(当expr2为真时,结果为真,否则结果为假);

2401_87570443的博客 916

C语言期末复习题(非常基础)

几个题

Tian Meng的博客 1336

嵌入式C语言复习-基础篇

本文系统复习了嵌入式开发中C语言的核心知识点

DianZeF的博客 1179
上一篇: 【C语言复习(四)】指针基础
下一篇: 【C语言复习(十三)】数组和指针
CMbug
博客等级 码龄12年 36粉丝 122原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值