C语言学习之:一维数组、二维数组的取值和取地址问题

1. 一位数组的取值操作与取地址操作

假设现在有一个一位数组 a = [1,2,3,4,5]

  • 因为 a 是一个数组,而在 C 语言中规定,数组变量的名称代表的就是一个数组的地址值,因此,打印 a 即打印 a 的地址值
  • 因为 a 本身就是个地址,因此对它取地址其实得到的还是数组 a 的地址,因此结果也相同
  • 一个数组的地址值本身也是它第一个元素的地址值,因此第三个输出也是同样的结果
  • 因为指针就可以看做是地址,因此我们也可以说数组 a 的指针就是 00AFFBEC
#include<stdio.h>

void main() {

	int a[] = { 1,2,3,4,5 };

	printf("%p\n", a);
	printf("%p\n", &a);
	printf("%p\n", &a[0]);

}

在这里插入图片描述

2. 二维数组的取值操作与取地址操作

二维数组相对于一维数组来说复杂一些

  • 二维数组的变量名称代表的也是整个数组的地址值,也是首地址值,因此以下代码中前五种情况得到的都是二维数组的地址值。
  • 特别注意 *a
    • 在一维数组中由于 a 是第一个元素 a[0] 的地址值,因此对于 a 进行取值操作* 之后,可以直接得到 a[0] 的值;
    • 而在二维数组中,直接对于二维数组 a 进行取值操作得到的竟然不是一个确切的数,依然还是一个地址值,这点需要特别注意。
  • 但是!!! 如果我们用一个指针 p 来指向一个二维数组的首地址 a,那么对于 p 直接进行取值操作得到的就是一个值。也就是说,这里的二维数组中 *p != *a;但是一维数组中的 *p == *a
#include<stdio.h>

void main() {

	int a[2][3] = { {1,2,3},{4,5,6} };
	int* p=a;

	printf("%p\n", a);
	printf("%p\n", &a);
	printf("%p\n", *a);
	printf("%p\n", &a[0]);
	printf("%p\n", &a[0][0]);
	printf("%d\n", *p);

}

在这里插入图片描述

3. 一维数组与二维数组的共同点和差别

在这里插入图片描述

4. 深入讨论 *a 的问题

至于为什么对于二维数组 *a 只能得到地址的问题,可以这么理解:例如一个 2 行 3 列的二维数组可以理解为他依然是一个一维数组,只不过第 1 个元素的位置存放的是 3 个地址值,第二个元素的位置存放的也是 3 个地址值;这三个地址值指向的三个值才是真正的值。因此 a[0] 对应着 a[0][0],a[0][1],a[0][2] 的地址值,因此对 a 取值得到的还是地址值

在这里插入图片描述

  • 18
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
 面向对象编程和可视化集成开发工具的发展,使很多曾经非常流行的编程语言影响下降甚至逐步消失,但有一种语言是例外,它就是C语言,时光流逝丝毫没减低C的魅力,它的风采依然如旧。   C语言已经深深的进入各种操作系统,通过对C语言学习,能够很快的掌握操作系统的底层结构和操作方式,因此C语言学习编程的首选语言。为满足广大读者的要求,本期专题特别推出C语言初级教程。  第一讲 慨述   早期的C语言主要是用于UNIX系统。由于C语言的强大功能和各方面的优点逐渐为人们认识,到了八十年代,C开始进入其它操作系统,并很快在各类大、中、小和微型计算机上得到了广泛的使用。成为当代最优秀的程序设计语言之一。             第二讲 数据类型   在本讲中,我们只介绍数据类型说明。其它说明在以后陆续介绍。所谓数据类型是按被说明量的性质,表示形式,占据存储空间的多少,构造特点来划分的。在C语言中,数据类型可分为:基本数据类型,构造数据类型,指针类型,空类型四大类。                       第三讲 基础语句   C程序的执行部分是由语句组成的。 程序的功能也是由执行语句实现的。     第四讲 运算符和表达式   C语言中运算符和表达式数量之多, 在高级语言中是少见的。正是丰富的运算符和表达式使C语言功能十分完善。 这也是C语言的主要特点之一。        第五讲 输入输出   在C语言中,所有的数据输入/输出都是由库函数完成的,因此都是函数语句。本小节先介绍printf函数和putchar函数。                           第六讲 分支结构   C语言提供了多种形式的条件语句以构成分支结构,如:if、if...else、switch等,这几种形式的条件语句一般来说是可以互相替代的。         第七讲 循环结构   循环结构是程序中一种很重要的结构。其特点是, 在给定条件成立时,反复执行某程序段,直到条件不成立为止。                            第八讲 转移语句   程序中的语句通常总是按顺序方向, 或按语句功能所定义的方向执行的。如果需要改变程序的正常流向, 可以使用本小节介绍的转移语句。      第九讲 数组   数组在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来。这些按序排列的同类数据元素的集合称为数组。                                    第十讲 函数    函数是C源程序的基本模块, 通过对函数模块的调用实现特定的功能。C语言中的函数相当于其它高级语言的子程序。                              第十一讲 指针的慨念    指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; 能很方便地使用数组和字符串; 并能象汇编语言一样处理内存地址,从而编出精练而高效的程序。               第十二讲 多维数组的指针变量    二维数组指针变量说明的一般形式为: 类型说明符 (*指针变量名)[长度] 其中“类型说明符”为所指数组的数据类型。“*”表示其后的变量是指针类型。                  第十三讲 结构    “结构”是一种构造类型,它是由若干“成员”组成的。 每一个成员可以是一个基本数据类型或者又是一个构造类型。                                第十四讲 联合    “联合”与“结构”有一些相似之处。但两者有本质上的不同。在结构中各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量的长度等于各成员中最长的长度。                      第十五讲 枚举与位运算    在“枚举”类型的定义中列举出所有可能的取值, 被说明为该“枚举”类型的变量取值不能超过定义的范围。                             第十六讲 预处理    所谓预处理是指在进行编译的第一遍扫描(词法扫描和语法分析)之前所作的工作。               第十七讲 文件    所谓“文件”是指一组相关数据的有序集合。 这个数据集有一个名称,叫做文件名。  
1.1 数据结构讨论的范畴 Niklaus Wirth Algorithm + Data Structures = Programs 程序设计: 为计算机处理问题编制一组指令集 算法:处理问题的策略 数据结构:问题的数学模型 例如: 数值计算的程序设计问题 结构静力分析计算 ─━ 线性代数方程组 全球天气预报 ─━ 环流模式方程 非数值计算的程序设计问题 例一: 求一组(n个)整数中的最大值 算法: 基本操作是“比较两个数的大小” 模型:? 例二:计算机对弈 算法:对弈的规则和策略 模型:? 例三:足协的数据库管理 算法:需要管理的项目?如何管理?用户界面? 模型:? 概括地说, 数据结构描述现实世界实体的数学模型(非数值计算)及其上的操作在计算机中的表示和实现 1.2 基本概念 一、数据与数据结构 数据: 所有能被输入到计算机中,且被计算机处理的符号的集 合计算机操作的对象的总称 是计算机处理的信息的某种特定的符号表示形式 数据元素: 数据中的一个“个体”,数据结构中讨论的基本单位 数据项:数据结构中讨论的最小单位 数据元素是数据项的集合 例如: 运动员(数据元素) 姓名 俱乐部名称 出生日期 参加日期 职务 业绩 其中    出生日期  年  月  日 是组合项 数据结构:带结构的数据元素的集合 例如,一个含12位数的十进制数可以用三个4位的十进制数表示 3214,6587,9345 ─ a1(3214),a2(6587),a3(9345) 在a1、a2和a3 之间存在“次序”关系  a1,a2 、 a2,a3 3214,6587,9345 ≠ 6587,3214,9345  a1  a2  a3    a2  a1  a3 又例,2行3列的二维数组 {a1, a2, a3, a4, a5, a6} a1 a2 a3 a4 a5 a6 行的次序关系:row = {<a1,a2>,<a2,a3>,<a4,a5>,<a5,a6>} 列的次序关系:col = {<a1,a4>,<a2,a5>,<a3,a6>} 再例,一维数组 {a1, a2, a3, a4, a5, a6}中存在 次序关系: {<ai, ai+1>| i=1, 2, 3, 4, 5} 数据的逻辑结构可归结为以下四类: 线性结构 树形结构 图状结构 集合结构 数据结构的形式定义为: 数据结构是一个二元组 Data_Structures = (D, S) 其中:D是数据元素的有限集,S是D上关系的有限集。 严格地讲,以上定义仅是数据的逻辑结构的定义 数据的存储结构 ─━ 逻辑结构在存储器中的映象 数据元素的映象方法: 用二进制位(bit)的位串表示数据元素 (321)10 = (501)8 = (101000001)2 A = (101)8 = (001000001)2 关系的映象方法:(表示 x, y 的方法) 顺序映象 以存储位置的相邻表示后继关系 y的存储位置和x的存储位置之间差一个常量C 而C是一个隐含值,整个存储结构中只含数据元素本身的信息 链式映象 以附加信息(指针)表示后继关系 需要用一个和x在一起的附加信息指示y的存储位置 在不同的编程环境中,存储结构可有不同的描述方法, 当用高级程序设计语言进行编程时,通常可用高级编程语言中提供的数据类型描述之。 例如:以三个带有次序关系的整数表示一个长整数时,可利用C语言中提供的整数数组类型,定义长整数为: typedef int Long_int [3] 二、数据类型 在用高级程序语言编写的程序中,必须对程序中出现的每个变量、常量或表达式,明确说明它们所属的数据类型。因为类型明显或隐含地规定了,在程序执行期间,变量或表达式所有可能取值的范围,以及在这些之上允许进行的操作。 数据类型是一个值的集合和定义在此集合上的一组操作的总称。 三、抽象数据类型(Abstract Data Type 简称ADT) 是指一个数学模型以及定义在此数学模型上的一组操作 ADT有两个重要特征: 数据抽象 用ADT描述程序处理的实体时,强调的是其本质的特征、其所能完成的功能以及它和外部用户的接口(即外界使用它的方法) 数据封装 将实体的外部特性和其内部实现细节分离,并且对外部用户隐藏其内部实现细节 例如 抽象数据类型复数的定义: ADT Complex { 数据对象:D={e1,e2|e1,e2∈RealSet } 数据关系:R1={<e1,e2> | e1是复数的实数部分, | e2 是复数的虚数部分 } 基本操作: InitComplex( &Z, v1, v2 ) 操作结果:构造复数Z,其实部和虚部分别被赋以参数v1和 v2的值。 DestroyComplex( &Z) 操作结果:复数Z被销毁。 GetReal( Z, &realPart ) 初始条件:复数已存在。 操作结果:用realPart返回复数Z的实部值。 GetImag( Z, &ImagPart ) 初始条件:复数已存在。 操作结果:用ImagPart返回复数Z的虚部值。 Add( z1,z2, &sum ) 初始条件:z1,z2是复数。 操作结果:用sum返回两个复数z1,z2的和值。 } ADT Complex 假设:z1和z2是上述定义的复数,则Add(z1,z2,z3)操作的结果将得到z3=z1+z2 抽象数据类型的描述方法 抽象数据类型可用(D,S,P)三元组表示 其中,D是数据对象,S是D上的关系集,P是对D的基本操作集。 ADT 抽象数据类型名 { 数据对象:〈数据对象的定义〉 数据关系:〈数据关系的定义〉 基本操作:〈基本操作的定义〉 } ADT 抽象数据类型名 其中,数据对象和数据关系的定义用伪码描述,基本操作的定义格式为 基本操作名(参数表) 初始条件:〈初始条件描述〉 操作结果:〈操作结果描述〉 基本操作有两种参数:赋值参数只为操作提供输入值;引用参数以&打头, 除可提供输入值外,还将返回操作结果。 “初始条件”描述了操作执行之前数据结构和参数应满足的条件,若不满足,则操作失败,并返回相应出错信息。 “操作结果”说明了操作正常完成之后,数据结构的变化状况和应返回的结果。若初始条件为空,则省略之。 抽象数据类型的表示和实现 抽象数据类型需要通过固有数据类型(高级编程语言中已实现的数据类型)来实现
一:数组 1:一维数组:(JAVA中的数组类似于C中的指针形式的数组)  定义:type var_name[]: 如 int a[]; float b[]; int month_days[];  使用:var_name=new type[size];如 a=new int[10]; month_days=new int[12];java的专业用法。  也可以在定义时,直接赋值如:int a[]={1,2,3,4,5};(这一点与C相同);   其它与C语言中的数组概念相同,包括利用数组下标赋值、取值以及内存中的存储方式等。  与C语言不同,数组也是类(对象),有许多方法可调用(如长度等) 二:多维数组(二维数组)  定义:int two[][]=new int[4][5];//类似于一维数组;  二维数组的另几种定义方法: 1:int two[][]={{1,2,3,4},{0,0,0,0},{3,4,5,6}}三行四列的二维数组(与C相同) 2:int two[][]=new int[4][]; two[0]=new int[5]; two[1]=new int[5]; two[2]=new int[5]; two[3]=new int[5]; 也可: two[0]=new int[1]; two[0]=new int[2]; two[0]=new int[3]; two[0]=new int[4]; 注意:数据也是对象: int n[]=new int[10]; int x=n.length; System.out.println("n数组的长度: " +x);结果为10; 总结:数组相当于C语言中的指向数组的指针, 数据的初始化有二种形式工:定义是赋值,或初始化(NEW运算后)赋值二种形式。 数据也是对象。 数组的copy; 如:int a[]=new int[10]; int b[]=new int[10]; for(int i=0;i<10;i++)a[i]=i; for(int i=0;i<10;i++)b[i]=a[i]; b=a; 介绍一个JAVA类:ArrayList类; java.util.ArrayList:动态数组; 主要方法:
很好用的东西很经典的一本C教程,TKS这算是谭浩强C语言设计比较新的版本了!目录很详细,使用很方便目录 第1章 C语言程序设计的概念  1.1 程序与程序设计语言   1.1.1 计算机与程序   1.1.2 计算机程序设计语言   1.1.3 高级语言程序的开发过程  1.2 C语言及其标准   1.2.1 C语言的出现   1.2.2 C语言的标准  1.3 C语言程序概要   1.3.1 函数   1.3.2 语句   1.3.3 名字与声明   1.3.4 变量及其赋值   1.3.5 算术运算   1.3.6 赋值类运算符的副作用及限制  习题一 第2章 基本数据类型  2.1 基本数据类型的特征   2.1.1 数值的定点表示与浮点表示   2.1.2 整数的有符号类型与无符号类型   2.1.3 类型宽度与取值范围  2.2 数据常量   2.2.1 整型常量   2.2.2 字符类型及其常量   2.2.3 实型常量   2.2.4 符号常量  2.3 数据类型转换   2.3.1 几个概念   2.3.2 数据类型的隐式转换   2.3.3 数据类型的显式转换   2.4 数据的控制台输入与输出   2.4.1 格式化输出函数pIintf()   2.4.2 格式化输入函数scanf()   2.4.3 字符输入/输出函数getchar()与putchar()  习题二 第3章 C语言程序的流程控制  3.1 算法   3.1.1 算法的组成要素与基本性质   3.1.2 算法描述工具   3.1.3 自项向下、逐步细化的算法设计过程  3.2 判断   3.2.1 命题的“真”、“假”与C语言中的逻辑值   3.2.2 关系运算与关系表达式   3.2.3 逻辑运算与逻辑表达式  3.3 选择型程序设计   3.3.1 if...else结构的应用   3.3.2 if.elseif结构的应用   3.3.3 switch结构的应用   3.3.4 条件表达式  3.4 循环型程序设计   3.4.1 迭代与穷举算法   3.4.2 while结构   3.4.3 dowhile结构   3.4.4 for结构   3.4.5 循环结构的中途退出与重复周期的中途结束  习题三 第4章 模块化程序设计  4.1 函数   4.1.1 设计C语言程序就是设计函数   4.1.2 函数结构   4.1.3 函数定义与函数声明   4.1.4 虚实结合与传值调用   4.1.5 递归函数  4.2 变量的存储属性   4.2.1 变量的作用域与生存期   4.2.2 C语言中变量的存储类型   4.2.3 通过const声明将变量存储在只读区  4.3 模块的编译与链接   4.3.1 分别编译   4.3.2 用项目管理多文件程序的编译与链接过程   4.3.3 头文件  4.4 宏定义与宏替换   4.4.1 字符串宏定义及其基本格式   4.4.2 使用宏需注意的问题   4.4.3 撤销己定义的宏   4.4.4 带参数的宏定义  习题四 第5章 数组  5.1 一维数组   5.1.1 一维数组定义及数组元素引用   5.1.2 数组元素的引用方法   5.1.3 一维数组的初始化   5.1.4 一维数组元素的查找与排序   5.1.5 数组与函数  5.2 字符串   5.2.1 字符数组与字符串   5.2.2 字符串的输入/输出   5.2.3 字符串处理函数  5.3 二维数组与多维数组   5.3.1 二维数组及其定义   5.3.2 二维数组的初始化   5.3.3 向函数传送二维数组   5.3.4 多维数组  习题五 第6章 指针  6.1 指针基础   6.1.1 地址与指针   6.1.2 指针变量及其定义   6.1.3指针变量的引用   6.1.4 指针的移动与比较   6.1.5 指向指针变量的指针与多级指针   6.1.6 指向void类型的指针  6.2 指针与数组   6.2.1 数组元素的指针引用   6.2.2 多字符串的存储与处理   6.2.3 内存的动态分配与动态数组的建立  6.3 指针与函数   6.3.1 指针参数与函数的地址传送调用   6.3.2 带参数的主函数   6.3.3 返回指针值的函数   6.3.4 指向函数的指针  习题六 第7章 用户定制数据类型  7.1 结构体类型基础   7.1.1 结构体类型及其定制   7.1.2 定义结构体类型变量及对变量的初始化   7.1.3 结构体变量的操作   7.1.4 嵌套结构体类型   7.1.5 位段  7.2 结构体数组   7.2.1 结构体数组的定义与初始化   7.2.2 对结构体数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暖仔会飞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值