C语言 | 数组与指针不等价

 

1024G 嵌入式资源大放送!包括但不限于C/C++、单片机、Linux等。关注微信公众号【嵌入式大杂烩】,回复1024,即可免费获取!

前言

数组与指针是不等价的,如:

  • 数组名不可以改变,而指向数组的指针是可以改变的。

  • 字符串指针指向的字符串中的字符是不能改变的,而字符数组中的字符是可以改变的。

  • 求数组长度时,借用数组名可求得数组长度,而借用指针却得不到数组长度。

 

区别一

数组名的指向不可以改变,而指向数组的指针是可以改变的。

请看如下代码:

#include <stdio.h>

int main(void)
{
  int a[5] = {0, 1, 2, 3, 4}, *p = a;
  char i;
  
  // 数组遍历方式一
  for ( i = 0; i < 5; i++ )
  {
    printf("a[%d] = %d\n", i, *p++);
  }
  
  // 数组遍历方式二
  for ( i = 0; i < 5; i++ )
  {
    printf("a[%d] = %d\n", i, *a++);
  }
  
  return 0;
}

数组遍历方式一:使用指针遍历数组元素,*p++等价于*(p++),即指针指向的地址每次后移一个单位,然后再取地址上的值。这里的一个单位是sizeof(int)个字节,至于为什么是sizeof(int)个字节可以查阅我的总结C语言指针变量的运算

数组遍历方式二:使用数组名自增遍历数组元素,编译出错,错误如下:

error: value required as increment operand

因为数组名的指向是不可以改变的,使用自增运算符自增就会改变其指向,这是不对的,数组名只能指向数组的开头。但是可以改为如下遍历方式:

for ( i = 0; i < 5; i++ )
  {
    printf("a[%d] = %d\n", i, *(a+i));
  }

这可以正确遍历数组元素。因为*(a+i)与a[i]是等价的。

 

区别二

字符串指针指向的字符串中的字符是不能改变的,而字符数组中的字符是可以改变的。

请看如下代码:

//字符串定义方式一
char str[] = "happy";

//字符串定义方式二
char *str = "happy";

字符串定义方式一:字符串中的字符是可以改变的。如可以使用类似str[3]='q'这样的语句来改变其中的字符。原因就是:这种方式定义的字符串保存在全局数据区或栈区,是可读写的。

字符串定义方式二:字符串中的字符是不可以改变的。原因就是:这种方式定义的字符串保存在常量区,是不可修改的。

具体可查阅:char *str与char str[]的区别

PS:关于C内存内存的总结可查阅我的总结:通俗易懂的C语言内存总结

 

区别三


求数组长度时,借用数组名可求得数组长度,而借用指针却得不到数组长度。

请看如下代码:

#include <stdio.h>

int main(void)
{
  int a[] = {0, 1, 2, 3, 4}, *p = a;
  char len = 0;
  
  // 求数组长度方式一
  printf("方式一:len=%d\n",sizeof(a)/sizeof(int));
  
  // 求数组长度方式二
  printf("方式二:len=%d\n",sizeof(p)/sizeof(int));
  
  return 0;
}

运行结果

方式一:len=5
方式二:len=1

求数组长度方式一:借用数组名来求数组长度,可求得数组有5个元素,正确。

求数组长度方式二:借用指针求数组长度,求得长度为1,错误。原因是:

p只是一个指向int类型的指针,编译器不知道其指向的是一个整数还是指向一个数组。sizeof(p)求得的是p这个指针变量本身所占用的字节数,而不是整个数组占用的字节数。

以上就是指针与其指向的数组的三个典型的区别:(1)遍历数组时需要注意;(2)修改字符串中的字符时需要注意;(3)求数组长度时需要注意。

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式大杂烩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值