标签:aar cin padding 依次 函数参数 函数 出错 组元 应用
首先讨论一维数组。
int b[10] 声明了一个整数型数组,数组名称为b,它由10个int型数据组成,依次为b[0] 、b[1]、... b[9]
那么b是什么类型? 从我们直观的分析来看,b是一整个数组。
在C中,几乎所有情况,b---数组名,是一个指针常量,指向"自己的元素类型"。且是常数指针,永远指向第一个数组元素。
比如,此处b是一个指针,一个指向int型的指针。且值大小为 &b[0]。
个别情况:sizeof(数组名) = 元素个数 、 &数组名 -----后面再介绍
b[3] 是指数组b的第4个元素。比如 b[3] = 11; 将常数11写入b[3]。其物理意义是: 把int型11,存入一个地址内部。显然b[3]是一个物理地址的代号,那它真正的地址是多少? 显然等于&b[3]= & b[0] + 3*sizeof(int)。 它也等于 *(b+3) -----用于左值。
在C语言中,下标引用实际上只是 间接访问的一种伪装形式。下标引用从直观上更加容易理解。
下标引用 = 指针加减法操作。
例子:
int arry[10];
int *ap = arrry +2 ;
声明arry数组,arry本身是一个指针型常量,那么arry+2 = &arry[0] + 2*sizeof(int) = &arry[2]. 表明ap是一个指针,并指向第三个元素。
ap |
指针常量,指向元素2 (编号从0开始) |
*ap |
左值:存入元素2内; 右值,获取元素2内的值 |
Ap[0] |
从字面上,我们觉得这是错的,因为ap是个指针啊,它又不是数组,你怎么对它进行这种操作呢? 其实:我们记得下标引用时 间接访问的一种伪装。所以这个依旧是简洁访问的一种 *(arry + 0) = *ap 用作左值:存入元素2内;右值,获取元素2内的值
|
Ap+6 |
Ap是一个指针,指针的加法 = + 6*sizeof(int) 所以是指向 元素8 |
*ap+6 |
arry[2]的内容+6 |
*(ap+6) |
用作左值:存入元素8内;右值,获取元素8内的值 |
ap[6] |
同理, ap[6] = *(arry + 6) ,跟上面一样 |
&ap |
显然是获取指针变量的地址。
|
Ap[-1] |
Ap[-1] = *(arry -1 ) , 用作左值:存入元素1内;右值,获取元素1内的值 |
Ap[9] |
Ap[9] = *(arry +9) 超出了范围。是很冒风险的事 |
2[aary] |
依旧是合法的,很奇怪是吧, 2[arry] = *(2+arry) = *(arry+2) |
在具体的应用中,该怎么书写? 默认数组使用下标,因为易读、易维护。除非必须考虑效率的情况的下,才使用指针。
int arry[10]; int a; for(a=0;a<10;a++) arry[a] = 0;
它执行arry[a]的时候,都会 *(arry+a) = &arry[0] + a* 4。每次都算a*4的值需要
int arry[10]; int *p; for( p = arry; p< arry+10 ; p++) *p = 0;
这里每次 需要执行一个 加法, p++ = p +1*4 ,1*4会被缓存下来,这样只需要执行一次乘法,后面都是+4操作。
其实这里效率仍没有彻底的体现出来:但鉴于指针容易出错,所以非必要情况下,数组用下标引用即可。
在函数定义、函数原型声明中,如果参数里面有数组元素,该怎么写?
函数定义:
#include <stdio.h>
int strlen (char str[]);
int strlen2 (char str[2]);
int main (void) {
int size =0;
char str1[] = "aaakang";
char str2[2] = "ka";
char *p ="hahah";
printf("%d\n",sizeof(str1)) ;
printf("%d\n",sizeof(str2)) ;
size = strlen(str1);
printf("%d\n",size) ;
size = strlen2(str2);
printf("%d\n",size) ;
}
int strlen (char str[]) {
int len =0;
len = sizeof(str);
return (len);
}
int strlen2 (char str[2]) {
int len =0;
len = sizeof(str);
return (len);
}
首先打印的 sizeof(数组名1) = 长度 8 ,可长度明明是7个啊? 这个留到字符串时候再说。
sizeof(数组名2) = 长度2 。
在函数定义时,我们自以为传递进来的是一整个数组,然后子函数里面对其取sizeof。其实函数参数列表里面的数组,
C编译器都只是把它看成 一个指针变量。 只不过 数组名 =*p = &arry[0]。
sizeof(str)算出来一直是4.
函数列表内数据时数组名的,在调用时,我们用指针传参进去也是对的。
在调用时,我们不指定数组长度,依然是对的,因为C编译器只取首地址。不copy真个数组,不会分配内存。
这里还要补充一点: int a[] = {1, 2 ,3, 4}. 只有当后面元素存在时,才允许[] 不指定长度,编译器自动指定。
单纯的 int b[]; 是错误的,因为声明时,编译要分配地址,不知道长度信息就无法分配地址。
标签:aar cin padding 依次 函数参数 函数 出错 组元 应用
原文地址:http://www.cnblogs.com/mokang0421/p/7476052.html