一维数组和二维数组的运算(sizeof与strlen的区别)

在数组运算前,先了解一下数组的解引用到底是怎么回事。

#include <windows.h>
#include <stdio.h>
int main()
{
	int arr[] = {1,2,3,4,5,6,7,8,9,0};
	printf("%d\n", *arr);
	system("pause");
	return 0;
}


这段代码输出来的是什么呢?




由此可见,数组的数组名其实是数组首元素的地址。

那么,如果要访问一个数组中其他元素呢?

#include <stdio.h>
int main()
{
	int arr[10] = {0};
	int i = 0;
	for(i=0; i<sizeof(arr)/sizeof(arr[0]); ++i)
	{	
		printf("&arr[%d] = %p\n", i, &arr[i]);
		printf("%p\n", arr+i);
	}
	return 0;
}

这里输出的是&arr[i]的地址,那么从arr[0]到arr[9]的地址能不能通过arr+i的方式打印出来呢?我们来看


                    


观察结果我们发现,通过对数组名+整数的运算,其实可以获取到数组每个人元素的地址。这样我们就可以用指针访问我们的数组了。


看完一维数组的表示方式,下列关于数组的一些运算我们必须掌握。


//一维数组


int a[] = {1,2,3,4};


printf("%d\n",sizeof(a));  //16    数组的大小(4个元素,一个占4个字节)


printf("%d\n",sizeof(a+0));  //4   第一个元素的大小


printf("%d\n",sizeof(*a));  //4    数组的解引用,数组首元素的大小(int型)


printf("%d\n",sizeof(a+1));  //4   第二个元素的大小


printf("%d\n",sizeof(a[1]));  //4  第二个元素的大小


printf("%d\n",sizeof(&a));  //4    数组的地址大小都是4


printf("%d\n",sizeof(&a+1)); //4   这个数组的下一个数组的地址


printf("%d\n",sizeof(&a[0])); //4  首元素的地址


printf("%d\n",sizeof(&a[0]+1)); //4  第二个元素的地址




//字符数组


char arr[] = {'a','b','c','d','e','f'};

printf("%d\n", sizeof(arr));  //6      数组的大小(6个元素,一个占1个字节)


printf("%d\n", sizeof(arr+0));//4      首元素的地址


printf("%d\n", sizeof(*arr)); //1   数组的解引用,首元素的大(char型)


printf("%d\n", sizeof(arr[1]));//1   第二个元素的大小


printf("%d\n", sizeof(&arr)); //4   数组的地址是4


printf("%d\n", sizeof(&arr+1));//4   下个数组的首地址


printf("%d\n", sizeof(&arr[0]+1));//4  第二个元素的地址



printf("%d\n", strlen(arr)); //随机


printf("%d\n", strlen(arr+0));//随机
/*
printf("%d\n", strlen(*arr));//error
*/
/*printf("%d\n", strlen(arr[1]));*/ //error


printf("%d\n", strlen(&arr));//随机


printf("%d\n", strlen(&arr+1));//随机


printf("%d\n", strlen(&arr[0]+1));//随机




为什么在运算strlen 时会出现这么多随机数呢?不妨先来看看strlen的用法


它从内存的某个位置(可以是字符串开头,中间某个位置,甚至是某个不确定的内存区域)开始扫描,直到碰到第一个字符串结束符'\0'为止



而对于strlen(*arr),在对arr解引用求长度时,会自动将首元素的地址先用ASCII码值表示出了,然后向后查找,系统会一直查找下去(a的ASCII为97)




strlen(&arr)是对arr的地址求长度,而arr的地址里没'\n',所以他会一直找到'\n'才能停下了,会产生一个随机值



          

char *p = "abcdef";

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     指针的地址为4


printf("%d\n", sizeof(&p+1));//4 下个指针的地址


printf("%d\n", sizeof(&p[0]+1));//4 第二个元素的地址



printf("%d\n", strlen(p));//6 求整个数组的长度

printf("%d\n", strlen(p+1));//5      从第二个元素开始的长度

/**printf("%d\n", strlen(*p));//error  

printf("%d\n", strlen(p[0]));*///error

printf("%d\n", strlen(&p));//x 从首元素地址开始找'\n',随机值

printf("%d\n", strlen(&p+1));//x 同上

printf("%d\n", strlen(&p[0]+1));//5第二个元素开始的长度


 

这里产生的错误和上面的strlen 一样会从首元素对应的ASCII值出查找,所以一样会出错。


//二维数组

int a[3][4] = {0};


printf("%d\n",sizeof(a));//48 整个数组的大小


printf("%d\n",sizeof(a[0][0]));// 4 第一个元素的大小


printf("%d\n",sizeof(a[0]));//16 第一行元素的大小(int型)


printf("%d\n",sizeof(a[0]+1));//4 第一行的第二个元素的大小


printf("%d\n",sizeof(a+1));//4 第二个元素的地址


printf("%d\n",sizeof(&a[0]+1));//4 第一行第二个元素的地址


printf("%d\n",sizeof(*a));//16 数组首元素(相当于第一行的大小)


printf("%d\n",sizeof(a[3]));//16 下个数组的首个元素(第一行)大小



接下来总结一下sizeof和strlen的区别:

sizeof:

1、sizeof的单位是字节

2、sizeof(数组名)表示整个数组的大小(和类型有关)

3、sizeof(&数组名)表示整个数组的地址(和类型无关)

4、sizeof(*数组名)表示数组首元素的大小

strlen:

1、strlen(数组名)表示数组的长度(如果是非字符串则会产生一个随机值)

2、strlen(*数组名)表示从首元素对应的ASCII开始找'\n',会出错

3、strlen(&数组名)表示从首元素的地址开始找'\n',直到找到'\n',会产生一个随机值

   结果和你想的一样吗?


  • 12
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值