4 数组

1.1 数组

数组方便一次定义大量变量空间,而且也方便访问,访问时利用地址累加,访问每个数组空间即可。

1.1.1 一维数据中的关键符号

以int buf[100] = {0} 为例
buf:一是数组名,sizeof(buf)时,buf就是数组名的含义;二是等价于&buf[0],表示数组第一个元素的首字节地址,是一个常量值。
buf[0]:第一个元素的空间,可以对其进行读写操作。
&buf[0]:等价于buf,是一个地址常量,只能作为右值。
&buf:表示数组首地址,是一个地址常量,只能作为右值。
buf和&buf的值相等,但含义不同,buf表示数组第一个元素的首字节地址,加1加的是一个元素空间的大小,而&buf表示的是数组首地址,加1加的是整个数组空间大小。

1.2 数组和指针

1.2.1 如何使用指针访问数组

(1)利用下标

#include<stdio.h>
int main()
{
	int buf[10]={1,2,3,4,5,6,7,8,9,10};
	int i;
    for ( i = 0 ;i < sizeof(buf)/sizeof(buf[0]);i++)
    printf("%d\n", buf[i]);
    return 0;

}

(2)利用指针常量访问

#include<stdio.h>
int main()
{
	int buf[10]={1,2,3,4,5,6,7,8,9,10};
	int i;
    for ( i = 0 ;i < sizeof(buf)/sizeof(buf[0]);i++)
    printf("%d\n", *(buf+i));
    return 0;
}

(3)利用指针变量访问

#include<stdio.h>
int main()
{
	int buf[10]={1,2,3,4,5,6,7,8,9,10};
	int i;
	int *p = buf;
    for ( i = 0 ;i < sizeof(buf)/sizeof(buf[0]);i++)
    printf("%d\n", *(p+i));
    return 0;

}

Alt

1.3 数组、指针和sizeof运算符

sizeof运算符用于括号()里面数据类型或者变量所占用的内存字节数。
举例1
char str[] = “hello”;
char *p = str;
sizeof(str):结果等于6,还包括’\0’字符;
sizeof(str[0]):结果等于1,返回的是数组第一元素空间大小;
strlen(str):结果是5,strlen用于测试字符节数组中字符的个数,遇到 ‘\0’结尾,但不包含’\0’
sizeof(*p):返回结果是1,*p表示第一个元素str[0]的空间,空间大小是1;
strlen( p):返回结果是5,p里存放的是字符串首地址,strlen测试“hello”字符个数;
sizeof( p):返回结果是4,是指针变量空间的大小。
举例2
int b[100];
sizeof(b):返回结果是400,此时的b代表整个数组空间。

1.4 数组的传参

对于数组来说,传参传递的都是数组的首元素首字节地址,起始就是一个普通变量的地址,目的是提高数组传参效率。
int fun(int *p)
没有明确的判断,有可能只是需要传递一个普通整型变量地址
int fun(int p[30])
明确告诉我们需要传递一个30个元素的整型数组

1.5 #define和typedef的区别

#define和typedef都可以用来给现有类型起别名,但#define只是简单的宏替换,在预编译时被处理;而typedef不是的,在编译时被处理。
区别一
#define dchar char *;
typedef char * tchar;
dchar p1,p2; //等价于char *p1,p2;只是p1才是指针变量
tchar p1,p2; //等价于char *p1,*p2;p1,p2都是指针变量
区别二
#define 可以实现类型组合
#define dint int ;
typedef int tint ;
unsigned dint p1,p2; //等价于unsigned int p1,p2
unsigned dint p1,p2; //不正确
区别三
typedef可以组建新类型
typedef char[200] charbuf;
charbuf buf; //等价于char buf[200]

1.6 指针数组和数组指针

1.6.1 简单理解指针数组和数组指针

指针数组实质是一个数组,数组里的元素全部是指针变量;数组指针实质是一个指针,指针指向的是一个数组。

1.6.2分析指针数组和数组指针的表达式

(1)找核心
(2)找结合
(3)继续向外结合直到整个符号结束
优先级:( ) >[ ]>星号*
如果核心是和星号*结合,表示核心是指针;
如果核心是和星号[]结合,表示核心是指针数组;
如果核心是和星号()结合,表示核心是函数;
举例
int *p[5]等价于int *(p[5]):指针数组;p是一个数组,数组有5个元素,数组中的元素都是指针,指针指向的元素类型都是int类型。
int (*p)[5]:数组指针;p是一个指针,指针指向一个数组,数组有5个元素,数组中存的元素是int类型。

1.7 二维数组

数组名代表数组首元素的首地址

1.7.1 普通指针指向二维数组的第一维

int *p1 = a[0];//数组名代表数组首元素的地址
int *p2 = a[1];//数组名代表数组首元素的地址
printf("a[0][0] = %d.\n",*p1);//*p1对应的是a[0][0]的值
printf("a[0][1] = %d.\n",*(p1+1));//*(p1+1)对应的是a[0][1]的值
printf("a[1][0] = %d.\n",*p2);//*p2对应的是a[1][0]的值
printf("a[1][1] = %d.\n",*(p2+1));//*(p2+1)对应的是a[1][1]的值

1.7.2 数组指针访问二维数组

printf("a[0][0] = %d.\n",**p);//**p对应的是a[0][0]的值
printf("a[0][1] = %d.\n",*(*p+1));//*(*p+1)对应的是a[0][1]的值
printf("a[0][4] = %d.\n",*(*p+4));//*(*p+4)对应的是a[0][4]的值

printf("a[1][0] = %d.\n",**(p+1);//**(p+1)对应的是a[1][0]的值
printf("a[1][1] = %d.\n",*(*(p+1)+1);//*(*(p+1)+1)对应的是a[1][1]的值
printf("a[1][4] = %d.\n",*(*(p+1)+4);//*(*(p+1)+4)对应的是a[1][4]的值

注意:数组指针类型中的值必须和它指向的二维数组的第二维中的元素相等。如在二维数组int a[2][5],能指向该二维数组的数组指针类型为int ()[5]。
小结
a[i][j]等同于 * ( * (p+i)+j);
p不解引用,对p加减是在第一维里偏移地址;
p解引用一次,对p加减是在第二维里偏移地址;
p解引用二次,才能访问到值,如
(*p);

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值