C语言:数组和指针的区别(作为左值和右值的不同行为)

左值和右值

以前一直以为数组就是指针,但是直到我发现下面这两句的输出一样的时候,我才发现我错了

#include <stdio.h>

int main(){
	int a[2];
	printf("%#X\n",a);
	printf("%#X\n",&a);
} 

数组作为右值的时候,会被当成一个指针,因为总不可能把整个数组的元素全部输出来,但是被&取地址的时候是作为左值,就被当成一个对象,所以&返回的就是第一个元素的地址。
具体可以参考这篇博客
https://blog.csdn.net/imred/article/details/45441457

拓展:结构和对象

但是struct和c++的class/对象,作为右值的时候不会被当成指针,比如下面这个代码

#include <stdio.h>

int main(){
	int a[5];
	printf("%#X\n",a);
	printf("%#X\n",&a);

	struct S{
		int e;
		char t;
	};
	struct S s;
	struct S s2;
	struct S s3;
	
	printf("%#X\n",&s);
	printf("%#X\n",s);
	printf("&e:%#X\n",&(s.e));
	printf("%#X\n",&s2);
	printf("%#X\n",s2);
	printf("%#X\n",&s3);
	printf("%#X\n",s3);
	printf("e: %x\n",s.e);
	printf("e: %x\n",s2.e);
	printf("e: %x\n",s3.e);
	printf("t: %d\n",s.t);
	printf("t: %d\n",s2.t);
	printf("t: %d\n",s3.t);
} 

输出是这样的

0X62FE00
0X62FE00
0X62FDF0
0X1
&e:0X62FDF0
0X62FDE0
0XFFFFFFFF
0X62FDD0
0XCE1350
e: 1
e: ffffffff
e: ce1350
t: 0
t: -1
t: 0

输出struct的时候输出的是第一个int的值,而不是它的地址,因为没有初始化,所以输出是随机的。

指针与数组

所以说指针和数组还是有区别的,如下面这个例子

/*bugging.c*/
#include <stdio.h>
#include <stdlib.h>

static char buff [256];
static char* string;
int main ()
{
    printf ("Please input a string: ");
    gets (string);
    printf ("\nYour string is: %s\n", string);
}

会出现"Segment Fault"错误
用数组声明会给buff分配栈里面的空间,虽然没有初始化值,但是是合法的地址,但是只声明一个指针只会给这个指针变量分配一个地址,它的值没有初始化,默认为0,是不合法的地址,应该再加一句

string=buff;

buff作为右值时可以当成一个指针,所以赋值给string是没有问题的。
另外,数组变量作为左值是不能修改的,只能修改对应位置上的值,也就是说数组的名字包含的是一个常量指针const pointer,而不是一个普通的指针变量,它在符号表里面就对应这个数组对象了,不能再赋其他的对象给它。也就是说

int val[3] = { 5, 10, 20 };
val[0] = 1;//ok
val = {2,3,4};// Array type 'int[3]' is not assignable

第二句可以,第三局不可以,无法通过编译。参考https://www.geeksforgeeks.org/cpp-pointers/?ref=shm的Array Name as Pointers部分。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值