C语言中数组的七十二变
对于数组的学习要掌握这些基本的内容:
一.学会数组的定义和初始化的方式,包括一维数组,二维数组,三维四维等等。
1.char arr1[] = "abc";//4
2.char arr2[] = {'a', 'b', 'c'};//3
这两种初始化方式中第一个数组arr1中有4个元素,而arr2中只有3个元素,
因为使用字符串"abc"给arr1初始化会自动加上一个'\0',因此有四个元素。
二.数组中的下标操作符的活用,理解下标操作符的用法。
下面从下列代码中解析下标操作符的活用
//int main()
//{
// int arr[] = {1,2,3,4,5,6,7,8,9};
// int i = 0;
// //int *p = &arr[0];//和int *p = arr;的作用是一样的
// int *p = arr;//
// for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++)//补充一个知识点,sizeof(arr)返回的是arr这个整个数组所占内存的大小// sizeof(arr[0])代表数组中第一个元素的占内存大小,sizeof(arr)/sizeof(arr[0])// 得到的就是元素的个数
// {
// printf("%d ", arr[i]);//因为数组arr[0]是第一个元素,所以arr[i]代表数组中第i+1个元素的值
// printf("%d ", i[arr]);//比较不常见的用法,与arr[i]一个意思
// printf("%d ", *(arr+i));//一维数组中的数组名是首元素的地址,因此arr也是一个指针类型,*(arr+i)代表第i+1个元素中的值
// printf("%d ", *(p+i));//代表第i+1个元素中的值
// printf("%d ", *(i+p));//代表第i+1个元素中的值
// printf("%d ", i[p]);//代表第i+1个元素中的值
// printf("%d ", p[i]);//代表第i+1个元素中的值
//
// }
总结:arr[i]等于*(arr+i),[]和*的功能都是把地址中的值拿出来,同时i[arr]等于arr[i],这个性质要记住。
三.数组名与数组的关系。
如果定义一个一维数组:
int a[2];
a的值等于&a[0]的值,a代表的是首元素的地址
&a的地址虽然与a和&a[0]相同,但是它代表的
整个数组的地址。
如果定义一个二维数组:
int a[2][2];
&a等于a和a[0]和&a[0][0]的值
但是&a的地址代表整个二维数组的地址
a代表第一排数组的地址,&a[0]与a是一个意思
a+1代表第二排地址的数组
a[0]代表第一排数组的首个元素的地址
a[0][0]代表第一排数组首个元素的值
四.数组中内存的储存方式。
如果定义一个二维数组
1.int a[2][2]={1,2,3,4};
是否可以按2中这样理解,把1中的数组看成2中的形式,aa0看成1中二维数组的第一排的元素,aa1看成1中二维数组的第二排元素。
2.
int *a[2];
int aa0[2]={1,2};
int aa1[2]={3 , 4};
a[0]=aa0;//把第一排的数组中的首地址给指针类型数组a[0]
a[1]=aa1;//把第二排的数组中的首地址给指针类型数组a[1]
如果初始化值相同的话
在 2中的 *a代表 a[0], *a[0]又代表数组 aa0中的 首个元素 , 那么 *(*a)也代表 aar0首个元素的值
类比1中 *(*a)也代表第一排首个元素,好像二维数组可以如2中转化为一维数组来理解,但是实际上是不可以这样理解的,
因为定义一个二维数组后,实际内存中储存关系是连续的,而2中这样定义数组不一定是
连续的,因此不能这样去理解。
五.函数中怎么调用数组。
int a[10];
void arraysUser(int *p)
{
...
}
要在arraysUser函数中使用数组a
arraysUser(a);//这样写即可,意思为把数组的首地址传给指针p,这样即把数组带入到函数中使用,在函数中
//可以改变数组的值,或者使用数组的值
六.strlen()和sizeof()对二维数组的用法的不同之处。
1. 数组名单独放在sizeof()内部,数组名表示整个数组sizeof(数组名)计算的是整个数组的大小,单位是字节
2. &数组名,数组名表示整个数组&数组名,取出的是整个数组的地址
3. 除此之外所有的数组名都表示首元素的地址
重点了解下面两个的输出结果:
//char arr[] = {'a','b','c','d','e','f'};
//printf("%d\n", strlen(&arr));//随机值
//printf("%d\n", strlen(&arr+1));//随机值
虽然两个输出结果都是随机值,但是第二个比第一个值要正好小6
因为&arr的地址是整个数组的地址,那么&arr+1代表的是整个数组
的下一个储存单位的地址,也就是说&arr+1实际上是跳过了这个数组
4.补充一个知识点,如果
short s;
int a=1;
int b=1;
printf("%d\n",sizeof(s=a+b));
上述输出的结果为 2
为什么呢?
因为编译器在执行程序时 先编译->链接->产生执行文件
表达式在执行文件.exe文件中才会执行,而sizeof()在编译的时候
就已经执行,也就是说sizeof()执行时只提取了s的类型short来进行
运算,这也就是为什么sizeof(int)这总写法也是合法的了。
例题:下列输出的结果是什么,如果下面的你都能算对,说明对数组的掌握还不错
1.
//char arr[] = {'a','b','c','d','e','f'};//printf("%d\n", strlen(arr));//随机值//printf("%d\n", strlen(arr+0));//随机值printf("%d\n", strlen(*arr)); //errprintf("%d\n", strlen(arr[1]));//err//printf("%d\n", strlen(&arr));//随机值//printf("%d\n", strlen(&arr+1));//随机值//printf("%d\n", strlen(&arr[0]+1));//随机值
// printf("%d\n", sizeof(arr));//7
// printf("%d\n", sizeof(arr+0));//4
// printf("%d\n", sizeof(*arr));//1
// printf("%d\n", sizeof(arr[1]));//1
// printf("%d\n", sizeof(&arr));//4
// printf("%d\n", sizeof(&arr+1));//4
// printf("%d\n", sizeof(&arr[0]+1));
2.
// printf("%d\n",sizeof(a));//16
// printf("%d\n",sizeof(a+0));//4
// printf("%d\n",sizeof(*a));//4
// //*a == *(a+0) == a[0];
// //arr[i] ==> *(arr+i)
// printf("%d\n",sizeof(a+1));//4
// printf("%d\n",sizeof(a[1]));//4
// printf("%d\n",sizeof(&a)); //4
// printf("%d\n",sizeof(*&a)); //16
// printf("%d\n",sizeof(&a+1)); //4
// printf("%d\n",sizeof(&a[0]));//4
// printf("%d\n",sizeof(&a[0]+1));//4
3.
//printf("%d\n", strlen(arr));//随机值//printf("%d\n", strlen(arr+0));//随机值printf("%d\n", strlen(*arr)); //errprintf("%d\n", strlen(arr[1]));//err//printf("%d\n", strlen(&arr));//随机值//printf("%d\n", strlen(&arr+1));//随机值//printf("%d\n", strlen(&arr[0]+1));//随机值// printf("%d\n", sizeof(arr));//6
// printf("%d\n", sizeof(arr+0));//4
// printf("%d\n", sizeof(*arr)); //1
// printf("%d\n", sizeof(arr[1]));//1
// printf("%d\n", sizeof(&arr));//4
// printf("%d\n", sizeof(&arr+1));//4
// printf("%d\n", sizeof(&arr[0]+1));//4
4.
//char *p = "abcdef";//printf("%d\n", strlen(p));//6//printf("%d\n", strlen(p+1));//5printf("%d\n", strlen(*p));//errprintf("%d\n", strlen(p[0]));//err//printf("%d\n", strlen(&p));//随机值//printf("%d\n", strlen(&p+1));//随机值//printf("%d\n", strlen(&p[0]+1));//5//int arr[3][4];//*(*(arr+1)+0)//*(*(arr)) = *(*(arr+0)+0)// *arr = *(arr+0)//printf("%d\n", sizeof(p));//4//printf("%d\n", sizeof(p+1));//4//printf("%d\n", sizeof(*p));//1//printf("%d\n", sizeof(p[0]));//1//printf("%d\n", sizeof(&p));//4//printf("%d\n", sizeof(&p+1));//4//printf("%d\n", sizeof(&p[0]+1));//4
5.
int a[3][4] = {0};////int *p = a+1;short s = 1;int n = 10;printf("%d\n", sizeof(s=n+1));//2printf("%d\n", s);//printf("%d\n", sizeof(int));printf("%p\n", &a[0][0]);printf("%p\n", &a[0]+1);printf("%d\n",sizeof(a));//48 printf("%d\n",sizeof(a[0][0]));//4printf("%d\n",sizeof(a[0]));//16printf("%d\n",sizeof(a[0]+1));//4printf("%d\n",sizeof(a+1));//4printf("%d\n",sizeof(&a[0]+1));//4printf("%d\n",sizeof(*a));//16//sizeof(*(a+0))printf("%d\n",sizeof(a[3]));//
6.
//int arr[3][4] = {0};//int *p = &arr[0][0];//int *p = &arr;//int(*p)[4];////sizeof()//&arr//char arr[] = {'a','b','c','d','e','f'};//printf("%d\n", strlen(arr));//随机值//printf("%d\n", strlen(arr+0));//随机值printf("%d\n", strlen(*arr)); //errprintf("%d\n", strlen(arr[1]));//err//printf("%d\n", strlen(&arr));//随机值//printf("%d\n", strlen(&arr+1));//随机值//printf("%d\n", strlen(&arr[0]+1));//随机值// printf("%d\n", sizeof(arr));//6
// printf("%d\n", sizeof(arr+0));//4
// printf("%d\n", sizeof(*arr)); //1
// printf("%d\n", sizeof(arr[1]));//1
// printf("%d\n", sizeof(&arr));//4
// printf("%d\n", sizeof(&arr+1));//4
// printf("%d\n", sizeof(&arr[0]+1));//4
7.
//int a[] = {1,2,3,4};//printf("%p\n", &a[0]);//printf("%p\n", &a[0]+1);//printf("%p\n", a);//printf("%p\n", a+1);//printf("%p\n", &a);//printf("%p\n", &a+1);
总结 二维数组 int a[3][4]={0};
在sizeof()中 a单独出现代表整个二维数组
&a代表整个二维数组的地址
a+0 代表二维数组的第一排的地址
而 *(a+0)代表二维数组的第一排 ,a+0与*(a+0)的关系与 a与&a的关系类似
同时 *(a+0)等同于 a[0]
一维数组 int a[4]={0}中
在sizeof()里 a单独出现代表整个一维数组
a+0实际上代表一维数组中第一个元素的地址
*(a+0)代表第一个元素
C语言中数组的七十二变相关推荐
- 从编译器角度分析C语言中数组名和指针的区别
从编译器角度分析C语言中数组名和指针的区别 数组名和指针是两个往往很容易让人们混淆的概念,很多人以为数组名就是一个指针,也有很多人知道数组名不同于指针但是仅知道数组名的值不能像指针一样改变. 例如你可 ...
- 如何确定C语言中数组的大小?
如何确定C语言中数组的大小? 也就是说,数组可以容纳多少个元素? #1楼 如果您要处理未作为参数接收的数组,则sizeof方法是正确的方法. 作为参数发送给函数的数组被视为指针,因此sizeof将返回 ...
- c语言中数组的变量j是什么,c语言中数组,一般数组
c语言中数组,一般数组. 1.什么是数组,数组有什么用? 为了方便处理而把类型相同的变量有序地组织起来的一种形式. 类型相同的元素集中起来,在内存上排成一条直线. 2.数组的声明. 元素类型.变量名和 ...
- C语言中数组的排序算法详解——选择法、冒泡法、交换法、插入法、折半法
选择法排序 选择法排序是指:如果要把一个数组从小到大排列,那么就从该数组中依次选择最小的数字来排序.从第一个数字开始,将第一个数字与数组中剩下数字中最小的那一个交换位置,然后将第二个数字与剩下数字中最 ...
- C语言中数组首地址和数组第一个元素的地址有什么区别
C语言中数组首地址和数组第一个元素的地址关系如下: 1.它们的地址值是相等的. 2.第1个元素的地址如果是p,则p+1就是第2个元素的地址. 3.数组的首地址如果是p,则p+1就跳过这个数组而指向这个 ...
- c语言中的下标变量是什么,c语言中数组的下标从什么开始?
c语言中数组的下标从0开始. 数组中的各元素的存储是有先后顺序的,它们在内存中按照这个先后顺序连续存放在一起.数组元素用整个数组的名字和它自己在数组中的顺序位置来表示. 例如:a[0]就表示名字为a的 ...
- c语言中数组的定义与应用
定义方法: 类型 变量名[元素个数]: 比如: int a[6]; char b[24]; double c[3]; 注意,c语言中数组的元素个数是不能动态定义的(修改:在c99中已经可以了) 也 ...
- c语言中数组的概念及作用,C语言数组的定义及其使用方法
什么是数组? 在我们学习数组前先让我们介绍一下c语言中数组是什么?数组就是一个个元素按照一定顺序排列的集合.它将数据从最低的内存地址保存到最高的内存地址. 声明一个数组 c语言规定了声明数组的格式: ...
- C语言中数组名到底是什么?
一般情况下,C语言中数组名在表达式中被解读为指向数组首元素的指针 C语言中数组名在表达式中被解读为指向数组首元素的指针, 即数组名在表达式中值为数组首元素的地址.(但有个例外,int a[2];int ...
最新文章
- wincc报表步骤实例_Wincc 如何连接SQL Server 数据库
- redis数据持久化的两种方式
- windows系统中hosts文件位置
- c#将十进制转64进制
- css3 :nth-child()选择器的使用
- 004-React入门概述
- ssl1125-集合【哈希表二分查找+快排】
- git撤销commit 并保存之前的修改
- 别人家的公司!Facebook向每位员工发放1000美元,鼓励远程办公
- python通用数据库连接_python 连接数据库pg
- pytorch中的Sequential使用方法
- Spring Boot 整合 Kafka 分布式消息系统快速入门
- premiere提示无法使用前一个音频设备配置怎么办?
- 【C语言】案例四十八 综合案例——天生棋局(围棋棋盘)
- 北京35岁程序员失业,感叹:还是去卖煎饼果子吧~
- H5案例分享-H5游戏跳跃类玩法分享
- 激荡十年:详谈云计算的过去、现在和未来
- 雷电2接口_Intel发布雷电4接口,相比之前的雷电3,雷电4都改进了什么?
- MySQL 最新版行政区划
- php mkdir 失败原因,php mkdir 失败怎么办
热门文章
- <论文翻译>Relation Classification via Multi-Level Attention CNNs
- CSS实现footer“吸底”效果
- wireshark简易抓包分析——ping指定大小包长多28Byte
- 编程小白的人工智能路之Gabor滤波提取掌纹特征并对比掌纹相似度(一)
- mt9d131 驱动简介
- iOS QQ第三方登录
- 华为开发者大赛杭州沙龙圆满落幕,三大赛题获奖宝典重磅揭晓,拿走不谢!!!...
- LOAM系列——ISCLOAM配置、编译、问题解决及VLP16测试效果(完结版)
- SpringBoot+Nacos+OpenFeign环境搭建
- C语言之洛谷刷题之路---顺序结构