码迷,mamicode.com
首页 > 其他好文 > 详细

<C和指针---读书笔记8>

时间:2017-09-05 01:46:57      阅读:231      评论:0      收藏:0      [点我收藏+]

标签: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[]; 是错误的,因为声明时,编译要分配地址,不知道长度信息就无法分配地址。

 

<C和指针---读书笔记8>

标签:aar   cin   padding   依次   函数参数   函数   出错   组元   应用   

原文地址:http://www.cnblogs.com/mokang0421/p/7476052.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!