c语言学习笔记(15) 数组基础
2015-10-20 17:52
246 查看
摘要:总结了数组的概念,数组大小的计算方法,数组地址和数组名的关系,数组存在的一些盲点,最后用一个BUG实例对数组和指针的一个差别进行了分析。
一、数组的概念
数组是相同类型变量的有序集合,比如我们定义一个数组int a[5],那么这个数组名字就叫a,a就代表数组元素中的第一个元素的起始地址,这个数组里面有五个元素,每个元素都是int类型的,其中a[0],a[1],a[2],a[3],a[4],分别代表数组中的元素的内容,并非数组元素的名字,数组元素没有名字。
二、数组的大小
数组在一片连续的内存空间中存储元素,其中元素的个数,可以显示或者隐式的指定。
比如:int a[5]={1,2}
int b[]={1,2}
其中a有五个元素,如果对其进行了元素的赋值,其他不写出来的都默认填进去0,也就是a[]={1,2,0,0,0},如果显示的指定了大小,但是列表中没有给出元素,那么就会填充随机值,这一点可以利用来初始化数组为0,只需要int a[5]={0};b只含有两个元素,隐式指定列表写了几个元素,就是几个元素。
另外,数组的大小:sizeof(a)
数组的长度(也就是元素的个数):sizeof(a)/sizeof(*a)
三、数组地址与数组名
1.数组名代表数组首元素的地址
2.数组的地址需要用取地址符&才能得到
3.数组首元素的地址值和数组的地址值相同
4.数组首元素的地址和数组的地址虽然值相同,但是意义不同
意义不同是因为,数组地址代表的是一整块存放数组元素内存空间的地址,但是首元素只是代表这个第一个元素的地址,虽然他们的地址相同,但是意义不同。
四、数组名的盲点
1.数组名可以看做一个常量指针,什么意思呢?就是不能作为左值使用,只能作为右值。
2.数组名“指向”的是数组当中首元素的起始地址。
3.在表达式中数组名只能作为左值使用,比如a[5]=b[5],绝对是错误的。
4.只有在下列场合,数组名不能看做常量指针:
数组名作为sizeof()函数的参数
数组名作为取地址运算符的参数
五、BUG实例解析
这个例子主要是为了说明数组和指针的一个区别,在文件test.c中,声明为数组了,但是定义在another.c文件中的时候是定义为一个指针,使用的时候会出现错误。根本原因,是因为指针存在一个寻址过程,而数组没有。具体例子 如下:
为什么呢?其实原因很简单:原本another里面,我们定义了一个char*类型的指针p,p指向一个字符串hello world,p指针里面存放的是hello world字符串的起始地址,在test.c里面,我们将其声明成了数组,在打印的时候,数组直接指出输出p里面的东西,p里面存放的是地址,当然输出乱码了。而指针不同,打定义为指针的时候,会做一次寻址,根据p里面存放的地址,找出指向的内存单元的内容。所以编译器在处理数组的时候和处理指针的时候,有本质区别。所以数组名并不是指针,尤其在外部声明的时候要注意。
这篇帖子就总结到这里,如有不正确地方还请指出,大家共同进步!
一、数组的概念
数组是相同类型变量的有序集合,比如我们定义一个数组int a[5],那么这个数组名字就叫a,a就代表数组元素中的第一个元素的起始地址,这个数组里面有五个元素,每个元素都是int类型的,其中a[0],a[1],a[2],a[3],a[4],分别代表数组中的元素的内容,并非数组元素的名字,数组元素没有名字。
二、数组的大小
数组在一片连续的内存空间中存储元素,其中元素的个数,可以显示或者隐式的指定。
比如:int a[5]={1,2}
int b[]={1,2}
其中a有五个元素,如果对其进行了元素的赋值,其他不写出来的都默认填进去0,也就是a[]={1,2,0,0,0},如果显示的指定了大小,但是列表中没有给出元素,那么就会填充随机值,这一点可以利用来初始化数组为0,只需要int a[5]={0};b只含有两个元素,隐式指定列表写了几个元素,就是几个元素。
另外,数组的大小:sizeof(a)
数组的长度(也就是元素的个数):sizeof(a)/sizeof(*a)
三、数组地址与数组名
1.数组名代表数组首元素的地址
2.数组的地址需要用取地址符&才能得到
3.数组首元素的地址值和数组的地址值相同
4.数组首元素的地址和数组的地址虽然值相同,但是意义不同
意义不同是因为,数组地址代表的是一整块存放数组元素内存空间的地址,但是首元素只是代表这个第一个元素的地址,虽然他们的地址相同,但是意义不同。
四、数组名的盲点
1.数组名可以看做一个常量指针,什么意思呢?就是不能作为左值使用,只能作为右值。
2.数组名“指向”的是数组当中首元素的起始地址。
3.在表达式中数组名只能作为左值使用,比如a[5]=b[5],绝对是错误的。
4.只有在下列场合,数组名不能看做常量指针:
数组名作为sizeof()函数的参数
数组名作为取地址运算符的参数
五、BUG实例解析
这个例子主要是为了说明数组和指针的一个区别,在文件test.c中,声明为数组了,但是定义在another.c文件中的时候是定义为一个指针,使用的时候会出现错误。根本原因,是因为指针存在一个寻址过程,而数组没有。具体例子 如下:
<span style="font-size:18px;">test.c #include <stdio.h> extern char p[]; int main(void) { printf("%s\n",p); return0; } another.c char* p="hello world!"; 最后输出结果:乱码!</span>
为什么呢?其实原因很简单:原本another里面,我们定义了一个char*类型的指针p,p指向一个字符串hello world,p指针里面存放的是hello world字符串的起始地址,在test.c里面,我们将其声明成了数组,在打印的时候,数组直接指出输出p里面的东西,p里面存放的是地址,当然输出乱码了。而指针不同,打定义为指针的时候,会做一次寻址,根据p里面存放的地址,找出指向的内存单元的内容。所以编译器在处理数组的时候和处理指针的时候,有本质区别。所以数组名并不是指针,尤其在外部声明的时候要注意。
这篇帖子就总结到这里,如有不正确地方还请指出,大家共同进步!
相关文章推荐
- C语言(8) 变量在内存中的分配原则
- C语言(7) 模块化编程及多文件开发注意事项
- C语言(4) 原码、反码、补码与位运算
- C++ 11 function
- C语言(6) unix命令/C手动编译/include指令/Xcode 清空缓存的方法
- C++ 11 tuple & 可变参数模板
- C语言(5) 函数使用需要注意的地方
- 《C++ Primer 5th edition》 第一章 开始
- C++ 11语法甜点2
- c语言函数指针的定义
- 【好玩的棋盘游戏】编写一个玩家操作的函数和电脑能够操作的两人棋盘游戏,哪边有三个相连的胜出
- C语言--字符串处理函数的使用
- VC++ 关机代码
- C++ 11语法甜点1
- 【经典游戏编程题】C语言:编写一个棋盘游戏,与二维数组结合
- C语言(3) 运算符及优先级
- C++单根类的实现
- c++类静态成员详解
- C++ 11完美转发
- C++ 11 auto & decltype