C语言 一维数组详解
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言 一维数组详解相关的知识,希望对你有一定的参考价值。
文章目录
一维数组
在程序中可以使用下标变量,即说明这些变量的整体为数组,数组中的每个变量的数据类型是相同的。
当数组中每个元素都只带有一个下标时,称这样的数组为一维数组。
一维数组是由数字组成的以单纯的排序结构排列的结构单一的数组。一维数组是计算机程序中最基本的数组。二维及多维数组可以看作是一维数组的多次叠加产生的。
上面是文字性的定义描述,下面我们从其他角度来说明什么是一维数组。
多角度看一维数组
- 元素类型角度:数组是相同类型的变量的有序集合
- 内存角度:连续的一大片内存空间
一维数组声明
查看下面这些声明:
int a;
int b[10];
我们把a称作标量,因为它是个单一的值,这个变量是的类型是一个整数。我们把b称作数组,因为它是一些值的集合。
下标和数名一起使用,用于标识该集合中某个特定的值。例如,b[0]
表示数组b的第1个值,b[4]
表示第5个值。每个值都是一个特定的标量。
问题1:那么b的类型是什么呢?它所表示的又是什么?
一个合乎逻辑的答案是它表示整个数组,但事实并非如此。
在C中,在几乎所有数组名的表达式中,数组名的值是一个指针常量,也就是数组第一个元素的地址。它的类型取决于数组元素的类型:如果他们是int类型,那么数组名的类型就是“指向int的常量指针”;如果它们是其他类型,那么数组名的类型也就是“指向其他类型的常量指针”。
问题2:指针和数组是等价的吗?
答案当然是否定的。
数组名在表达式中使用的时候,编译器才会产生一个指针常量。但是本身数组是伴随着程序存在在内存当中的。
问题3:那么数组在什么情况下不能作为指针常量呢?
在以下两种场景下:
-
当数组名作为
sizeof操作符
的操作数的时候,此时sizeof返回的是整个数组的长度,而不是指针数组指针的长度。
例如:sizeof(arr);
-
当数组名作为
&操作符
的操作数的时候,此时返回的是一个指向数组的指针,而不是指向某个数组元素的指针常量。
例如:typeid(&arr).name()
问题3 参考代码
#include<iostream>
void test()
{
int arr[10];
//arr = NULL; // arr作为指针常量,不可修改
int *p = arr; // 此时arr作为指针常量来使用
printf("sizeof(arr):%d\\n", sizeof(arr)); // 此时sizeof结果为整个数组的长度
printf("&arr type is %s\\n", typeid(&arr).name()); // int(*)[10]而不是int*
}
int main()
{
test();
return 0;
}
下标引用
例如下面数组
int arr[] = { 1, 2, 3, 4, 5, 6 };
问题1:*(arr + 3)
,这个表达式是什么意思呢?
首先,我们说数组在表达式中是一个指向整型的指针,所以此表达式表示arr指针向后移动了3个元素的长度。然后通过间接访问操作符从这个新地址开始获取这个位置的值。这个和下标的引用的执行过程完全相同。所以如下表达式是等同的:
arr[3];
问题2:数组下标可否为负值?
答案是可能为负值,哈哈哈。
当然你要分清声明还是语句。
- 声明里的中括号里的数字不能为负。例如 int a[-2]; 是错的,数组大小不能为负。
- 语句里的中括号,C/C++ 看成运算符,不叫标点符号,可以为负数。
数组元素和指针有恒等关系:
a[i] == *(a+i)
所以,i 为 负 的时候,a[i] == *(a- fabs(i))
。只要 a-fabs(i) 这个地址里 有 数值,就可以拿来运算使用。
当然还是不建议这样写的,因为如果a[-1]的地址是不确定的,万一它指向了操作系统的某块内存,则可能影响到操作系统的运行。所以不建议数组下标为负的写法。
问题2:请阅读如下代码,说出结果:
int arr[] = { 1, 2, 3, 4, 5, 6 };
int *p = arr + 2;
printf("*p = %d\\n", *p);
printf("*p = %d\\n", p[-1]);
运行结果为:
问题3: a[i]==i[a]==*(i+a)==*(a+i)?
从汇编角度去说,这样是没问题的,在编译器的眼里,数组名a不过是一段连续内存的首地址。获取某个元素a[i]不过是在a对应的首地址上做偏移,找到对应的内存地址后从中取出其中的内容即可。
我也在VS里试了试,真的是可以。
测试代码:
#include<iostream>
void test()
{
int a[] = { 1, 2, 3, 4, 5, 6 };
for (int i = 0; i < 6; i++)
{
printf("*p = %d\\n", i[a]);
}
}
int main()
{
test();
return 0;
}
运行结果:
以上是关于C语言 一维数组详解的主要内容,如果未能解决你的问题,请参考以下文章