C语言 字符指针和字符数组的区别

前言

在日常敲代码的过程中我们会遇见这样一个问题

//例子1
void mian()
{
	int a;
	scanf("%d", &a);
}

例子1:这里我们看到,在为int a赋值的时候我们需要取a的地址对其赋值

void mian()
{
	int dwCount;
	int* a = &dwCount;
	scanf("%d", a);
}

例子2:这里我们换成一个指针,对指针int* a赋值,则不需要加取地址符号&,原因不难理解,上一个例子对a赋值需要其地址,所以我们需要加&,而这里指针int* a本身就是一个地址,所以没必要再加&取指针变量a本身的地址。

//例子3
void mian()
{
	char a[10];
	scanf("%s", a);
}

例子3:这里在对字符数组a[]赋值的时候,并没有使用取地址符号,而是直接用的数组名。

综上

我们不得不得出一个疑问,数组a[]和指针int* a在赋值时都没有使用取地址符号&,那它们有什么相同点呢?区别又在哪里呢?


字符指针和字符数组的区别

首先我们先要搞清楚指针和数组的工作原理

指针
void mian()
{
	int dwNum = 0;
	int* a = &dwNum;
}

我们画图说明:(地址随便假设的)
在这里插入图片描述
我们可以看到:编译器在内存中创建了两个变量a和dwNum,dwNum的值为0,首地址为0x11,a的值为0x11(也就是dwNum的首地址),首地址为0x11。这样指针a就指向的dwNum。
那么在使用指针创建字符串时,肯定和指针的工作原理一样的,看下面这段代码:

int main()
{
	char* a = "Hello World!";
	printf("%p\n", a);
	printf("%p\n", &a[1]);
	printf("%p\n", &a[2]);
	printf("%p\n", a);
	printf("%p\n", a + 1);
	printf("%p\n", a + 2);
	return 0;
}

运行结果都一样:
在这里插入图片描述

到这里我们不难得出一个结论,当我们用指针创建字符串的时候,编译器会自动在内存中开辟一段连续内存存放每一个字符,并将字符串的首地址存放在指针char* a中。那么我们可以画图理解(和指针的图差不多的):
在这里插入图片描述


数组

同样我们看例子:

void main()
{
	char a[10];
	printf("%p\n", a);
	printf("%p\n", a + 1);
	printf("%p\n", a + 2);
	printf("%p\n", a);
	printf("%p\n", &a[1]);
	printf("%p\n", &a[2]);
}

运行结果:
在这里插入图片描述
这里我们看到了和指针一样的结果,都是在内存中开辟一段连续的空间来存放数据,并将字符数组的首地址赋值给了数组名。那我们同样可以画一个图说明数组的工作原理:
在这里插入图片描述


总结

在功能上,字符指针和字符数组都时在内存中开辟空间存放字符串,并将首地址赋值给指针和数组名。通过下标法(a[0])或者地址法(*a)对其数据进行访问。
通过字符指针和字符数组的图我们可以发现不同在于,指针可以更改指向,所以可以直接更改其字符串。而数组的地址不能更改,其数据也不能直接赋值更改,只能用strcpy()等函数进行覆盖。

int main()
{
	char* a = "Hello World!";
	printf("%p\n", a);
	a = "Hello C!";//a指向新开辟的内存并存放"Hello C!",从而达到修改字符串的目的
	printf("%p\n", a);
	return 0;
}

运行结果:

在这里插入图片描述


void main()
{
	char a[10] = { '1','2','3' };
	a = { '4','5','6' };//直接更改  报错:表达式必须是可修改的左值	
}

运行结果:在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值