C/C++面试可能会问三:指针和数组一样吗?

答案:不一样。


哪里不同?

数组名:数组名的值是一个指针常量,也就是数组第一个元素的地址

它的类型取决于数组元素的类型:如果他们是int类型,那么数组名的类型就是“指向int的常量指针”;如果它们是其他类型,那么数组名的类型也就是“指向其他类型的常量指针”。

总结1:数组名是一个指针常量,不可简单的认为是个指针。它始终指向第一个元素的地址。


那么数组在什么情况下不能作为指针常量呢?

在以下两种场景下:

  • 当数组名作为 sizeof操作符 的操作数的时候,此时sizeof返回的是整个数组的长度,而不是指针数组指针的长度。
  • 当数组名作为 &操作符 的操作数的时候,此时返回的是一个指向数组的指针而不是指向某个数组元素的指针常量

!除了以上两点之外,数据名在其他任何情况下都是指向首元素的指针

更进一步解释:

    指针和数组并不是相等的。为了说明这个概念,请考虑下面两个声明:    

int a[10];
int *b;
  • 声明一个数组时,编译器根据声明所指定的元素数量为数组分配内存空间,然后再创建数组名指向这段空间的起始位置
  • 声明一个指针变量的时候,编译器只为指针本身分配内存空间,并不为任何整型值分配内存空间,指针并未初始化指向任何现有的内存空间

因此,表达式*a是完全合法的,但是表达式*b却是非法的。*b将访问内存中一个不确定的位置,将会导致程序终止。

  • 另一方面b++可以通过编译,a++却不行,因为a是一个常量值。

 

void test01()
{
	int arr[] = { 1, 2, 3, 4 };

	//1. sizeof  2.对数组名取地址&arr
	//以上两种情况下,数组名不是指向首元素的指针
	//以上两种请款下,数组名是数组类型
	//!除了以上两点之外,数据名在其他任何情况下都是指向首元素的指针
	//sizeof 可以不加括号,它是c语言关键字
	printf("sizeof arr:%d\n", sizeof arr);
	printf("&arr addr : %d\n", &arr);
	printf("&arr + 1 addr : %d\n", &arr + 1);   
    // 数组指针类型:地址直接加了一个数组的长度16字节。相当于类型+1。
	int *p = arr;

	//数组名是一个常量指针
	//arr = NULL;

	//数组下标能否是负数?
	//可以是负数
	p += 3;
	printf("p[-1]:%d\n", p[-1]);
	//他们等价
	printf("p[-1]:%d\n", *(p - 1));
	//数组指针类型和数组首元素指针类型
	
}
//如何定义一个可以指向数组的指针
void test02()
{
	int arr[5] = { 1, 2, 3, 4, 5 };

	//1. 我们先定义数组类型,再定义数组指针类型
	typedef int(ARRAY_TYPE)[5];  //typedef unsigned int u32
	ARRAY_TYPE myarray; // int myarray[5];
	//
	for (int i = 0; i < 5; ++i)
	{
		myarray[i] = 100 + i;
	}

	for (int i = 0; i < 5; ++i)
	{
		printf("%d " ,myarray[i]);
	}

	//对数组名取地址代表指向整个数组的指针
	ARRAY_TYPE *pArray = &myarray;
	pArray = &arr;

	//1. *pArray 表示拿到pArray指针指向的整个数组
	//2. *pArray类型就是数组名,指向首元素类型的指针

	printf("\n*(*pArray + 1) : %d\n", *(*pArray + 1));

	//2. 直接定义数组指针类型
	typedef int(*ARRAY_POINTER)[5];
	ARRAY_POINTER pArr = &arr;

	//3. 直接定义数组指针变量
	int(*pArrParam)[5] = &arr;

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值