C语言指针和数组

写在前面

想必在C语言的学习过程中,指针是让大家最为头痛的一个东西,那么接下来我将通过几个例题让大家更了解指针和数组。

数组名的意义

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。

例题

一维数组

int main( )
{
  int a[] = {1,2,3,4};
  printf("%d\n",sizeof(a));
  printf("%d\n",sizeof(a+0));
  printf("%d\n",sizeof(*a));
  printf("%d\n",sizeof(a+1));
  printf("%d\n",sizeof(a[1]));
  printf("%d\n",sizeof(&a));
  printf("%d\n",sizeof(*&a));
  printf("%d\n",sizeof(&a+1));
  printf("%d\n",sizeof(&a[0]));
  printf("%d\n",sizeof(&a[0]+1));
  return 0;
}

大家可以思考一下这些输出值都是什么???
接下来就来揭晓答案

int main( )
{
  int a[] = {1,2,3,4};
  printf("%d\n",sizeof(a));//答案:16  a表示整个数组
  printf("%d\n",sizeof(a+0));//答案:4/8  a+0是第一个元素的地址,sizeof(a+0)计算的是地址的大小,故在32位平台上是4,64位平台上为8
  printf("%d\n",sizeof(*a));//答案:4  *a是数组的第一个元素,sizeof(*a)计算的是第一个元素的大小
  printf("%d\n",sizeof(a+1));//答案:4/8  a+1是第二个元素的地址,sizeof(a+1)计算地址的大小,故在32位平台上是4,64位平台上为8
  printf("%d\n",sizeof(a[1]));//答案:4  计算的是第二个元素的大小
  printf("%d\n",sizeof(&a));//答案:4/8  &a虽然是数组的地址,但也是地址,计算一个地址的大小,故在32位平台上是4,64位平台上为8
  printf("%d\n",sizeof(* &a));//答案:16  计算数组的大小
  printf("%d\n",sizeof(&a+1));//答案:4/8  &a取出的是整个数组的地址,&a+1也表示地址,故在32位平台上是4,64位平台上为8
  printf("%d\n",sizeof(&a[0]));//答案:4/8  &a[0]取出的是第一个元素的的地址,故在32位平台上是4,64位平台上为8
  printf("%d\n",sizeof(&a[0]+1));//答案:4/8
  return 0;
}

字符数组

第一题

int main()
{
	char arr[ ] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr + 0));
	printf("%d\n", sizeof(*arr));
	printf("%d\n", sizeof(arr[1]));
	printf("%d\n", sizeof(&arr));
	printf("%d\n", sizeof(&arr + 1));
	printf("%d\n", sizeof(&arr[0] + 1));
	
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr + 0));
	printf("%d\n", strlen(*arr));
	printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr + 1));
	printf("%d\n", strlen(&arr[0] + 1));
	return 0;
}

思考一下,来看答案:`

int main()
{
	char arr[ ] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//答案:6  arr表示整个数组
	printf("%d\n", sizeof(arr + 0));//答案4/8  arr表示首元素的地址,sizeof(arr+0)表示首元素地址的大小,故在32位平台上是4,64位平台上为8
	printf("%d\n", sizeof(*arr));//答案:1  *arr表示首元素
	printf("%d\n", sizeof(arr[1]));//答案:1  arr[1]表示第二个元素
	printf("%d\n", sizeof(&arr));//答案:4/8  &arr表示整个数组的地址,但也是地址,故在32位平台上是4,64位平台上为8
	printf("%d\n", sizeof(&arr + 1));//答案:4/8  &arr+1为未知量的地址,但也是地址,故在32位平台上是4,64位平台上为8
	printf("%d\n", sizeof(&arr[0] + 1));//答案:4/8  &arr[0]为第一个元素的地址,故在32位平台上是4,64位平台上为8
	
	printf("%d\n", strlen(arr));//答案:随机值  arr里面存的是字符而非字符串,所以没有\0,从数组首元素开始计算步长,当遇到其他存储空间中的\0才会停止,所以结果为随机值
	printf("%d\n", strlen(arr + 0));//答案:随机值  arr里面存的是字符而非字符串,所以没有\0,从数组首元素开始计算步长,当遇到其他存储空间中的\0才会停止,所以结果为随机值
	printf("%d\n", strlen(*arr));//答案:err  *arr为第一个元素,strlen会把他当做一个地址,故会报错
	printf("%d\n", strlen(arr[1]));//答案:err  *arr为第二个元素,strlen会把他当做一个地址,故会报错
	printf("%d\n", strlen(&arr));//答案:随机值  arr里面存的是字符而非字符串,所以没有\0,从数组首元素开始计算步长,当遇到其他存储空间中的\0才会停止,所以结果为随机值
	printf("%d\n", strlen(&arr + 1));//答案:随机值-6  arr里面存的是字符而非字符串,所以没有\0,从数组最后一个元素的后面开始计算步长,当遇到其他存储空间中的\0才会停止,所以结果为随机值-6
	printf("%d\n", strlen(&arr[0] + 1));//答案:随机值-1  arr里面存的是字符而非字符串,所以没有\0,从数组第二个元素开始计算步长,当遇到其他存储空间中的\0才会停止,所以结果为随机值-1
	return 0;
}

strlen遇到\0才会停下

第二题

int main( )
{
	char arr[ ] = "abcdef";
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr + 0));
	printf("%d\n", sizeof(*arr));
	printf("%d\n", sizeof(arr[1]));
	printf("%d\n", sizeof(&arr));
	printf("%d\n", sizeof(&arr + 1));
	printf("%d\n", sizeof(&arr[0] + 1));
	
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr + 0));
	printf("%d\n", strlen(*arr));
	printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr + 1));
	printf("%d\n", strlen(&arr[0] + 1));
	return 0;
}

请大家先思考片刻

接下来看答案:

int main( )
{
	char arr[ ] = "abcdef";
	printf("%d\n", sizeof(arr));//答案:7  arr此时表示整个数组,a b c d e f \0
	printf("%d\n", sizeof(arr + 0));//答案:4/8  arr+0此时表示首元素地址
	printf("%d\n", sizeof(*arr));//答案:1  *arr此时表示首元素
	printf("%d\n", sizeof(arr[1]));//答案:1  arr[1]表示第二个元素
	printf("%d\n", sizeof(&arr));//答案:4/8  &arr表示整个元素的地址
	printf("%d\n", sizeof(&arr + 1));//答案:4/8  
	printf("%d\n", sizeof(&arr[0] + 1));//答案:4/8
	
	printf("%d\n", strlen(arr));//答案:6  a b c d e f \0 到\0停止,故结果为6 
	printf("%d\n", strlen(arr + 0));//答案:6 
	printf("%d\n", strlen(*arr));//答案:err
	printf("%d\n", strlen(arr[1]));//答案:err
	printf("%d\n", strlen(&arr));//答案:6  从首元素开始算,到\0停止
	printf("%d\n", strlen(&arr + 1));//答案:随机值  从\0后开始数,直到遇到\0停止
	printf("%d\n", strlen(&arr[0] + 1));//答案:5  从第二个元素开始算,到\0停止
	return 0;
}

第三题

int main()
{
	char* p = "abcdef";
	printf("%d\n", sizeof(p));
	printf("%d\n", sizeof(p + 1));
	printf("%d\n", sizeof(*p));
	printf("%d\n", sizeof(p[0]));
	printf("%d\n", sizeof(&p));
	printf("%d\n", sizeof(&p + 1));
	printf("%d\n", sizeof(&p[0] + 1));
	
	printf("%d\n", strlen(p));
	printf("%d\n", strlen(p + 1));
	printf("%d\n", strlen(*p));
	printf("%d\n", strlen(p[0]));
	printf("%d\n", strlen(&p));
	printf("%d\n", strlen(&p + 1));
	printf("%d\n", strlen(&p[0] + 1));
	return 0;
}

OK,思考片刻来看答案

int main()
{
	char* p = "abcdef";//P指向常量字符串首元素的地址
	printf("%d\n", sizeof(p));//答案:4/8  sizeof(p)即求常量字符串的首元素地址的大小
	printf("%d\n", sizeof(p + 1));//答案:4/8  还是求地址的大小
	printf("%d\n", sizeof(*p));//答案:1  首元素
	printf("%d\n", sizeof(p[0]));//答案:1  p[0]-->*(p+0)
	printf("%d\n", sizeof(&p));//答案:4/8
	printf("%d\n", sizeof(&p + 1));//答案:4/8
	printf("%d\n", sizeof(&p[0] + 1));//答案:4/8
	
	printf("%d\n", strlen(p));//答案:6  p指向常量字符串首元素的地址,
	printf("%d\n", strlen(p + 1));//答案:5  从第二个元素开始查
	printf("%d\n", strlen(*p));//答案:err  *p为字符串
	printf("%d\n", strlen(p[0]));//答案:err  p[0]为a
	printf("%d\n", strlen(&p));//答案:随机值  p后内存中未知
	printf("%d\n", strlen(&p + 1));//答案:随机值  p后内存未知
	printf("%d\n", strlen(&p[0] + 1));//答案:5  从第二个元素开始数
	return 0;
}

二维数组

int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//答案:48  a表示整个数组
	printf("%d\n", sizeof(a[0][0]));//答案:4  首元素
	printf("%d\n", sizeof(a[0]));//答案:16  第一行整行
	printf("%d\n", sizeof(a[0] + 1));//答案:4/8  a[0]作为数组名没有单独放在sizeof内部,也没有取地址,a[0]是第一行第一个元素的地址,所以a[0]+1是第一行第二个元素的地址
	printf("%d\n", sizeof(*(a[0] + 1)));//答案:4  第一行第二个元素
	printf("%d\n", sizeof(a + 1));//答案:4/8  a作为数组名没有单独放在sizeof内部,也没有取地址,a是二维数组第一个元素的地址,即第一行的地址,所以a+1是第二行的地址
	printf("%d\n", sizeof(*(a + 1)));//答案:16  第二行的元素
	printf("%d\n", sizeof(&a[0] + 1));//答案:4/8  就是第二行的地址
	printf("%d\n", sizeof(*(&a[0] + 1)));//答案:16  就是第二行的元素
	printf("%d\n", sizeof(*a));//答案:16  a作为数组名没有单独放在sizeof内部,也没有取地址,a就是首元素的地址即第一行的地址,所以*a就是第一行
	printf("%d\n", sizeof(a[3]));//答案:16  a[3]就是第四行数组名(如果有),其实没有,也能通过类型计算大小
	return 0;
}

3+5表达式有两个结果
1.值属性=8
2.类型属性=int

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值