指针与数据的分析

本文探讨了C语言中的变量本质,引出指针的概念,详细解释了指针作为内存地址别名的特性,并通过代码示例展示了指针的声明、使用以及运算规则。同时,文章还分析了数组的内存结构,比较了通过数组名和取地址符&获取数组地址的区别,并阐述了指针与数组之间的相互转换和使用。

在详细说指针之前,先来聊一聊,C语言中的变量到底是什么东西。所谓的变量,只不过是一段内存空间的别名,那么,我们是否能直接操作该地址呢,对于这个问题,就引入了指针。指针,可以将其理解为一个变量,只是该变量值为地址。下面我们先来看一段代码。

#include<stdio.h>

int main(){

	int i =5;
	int* p = &i;

	printf("%p\n", &i);
	printf("%p\n", p);
	printf("%d\n", *p);

	*p = 10;

	printf("%d\n", i);
	printf("%d\n", *p);

	return 0;
}
[lin@bogon C]$ ./a.out 
0x7fff0bdc2834
0x7fff0bdc2834
5
10
10

这里,就直接使用指针来改变变量i的值,而且从输出结果来看,p中存的值与变量i在内存中的地址一样的,说明咱们的分析是正确的。
在指针声明的时候,*号表示所声明变量为指针。而在指针使用时,*号表示指针所值内存空间的值。
指针是一种特殊的变量,在进行整数的运算规则是
  n+p = (unsigned int)p + n * sizeof(*p);
下面,我们来验证一下是否真的如此。

#include<stdio.h>

int main(){

	int a[5] = {1, 2, 3, 4};
	int* p = a;

	printf("%p\n", p);
	printf("%p\n", p+1);
		
	return 0;
}
[lin@bogon C]$ ./a.out 
0x7fffc9a76690
0x7fffc9a76694

通过程序,我们看到结果却是如此。

指针之间只支持减法计算,而且,类型必须相同,两指针相减的意义为两指针所值元素的下角标。
  p1-p2 = ((unsigned int)p1 - (unsigned int)p2)/sizeof(type);
  让我们看一段代码,看事实是否如此。

#include<stdio.h>

int main(){

	int a[5] = {1, 2, 3, 4};
	
	int* p1 = a;
	int* p2 = &a[2];
	printf("%d\n", p2 - p1);
	
	return 0;

}
[lin@bogon C]$ ./a.out 
2

下面,我们来聊聊数组。数组就是内存中连续的一段空间,而且每个元素都是相同类型的。数组的元素个数可以通过显示或者隐式进行指定。

	int a[5] = {1, 2, 3, 4};	//显示指定
	int b[] = {5, 6, 7};		//隐式指定

下面,我们再看看以下的代码,是否发现什么有趣的地方。

#include<stdio.h>

int main(){

	int a[5] = {1, 2, 3, 4};	printf("%p\n", a);
	printf("%p\n", &a);	
	
	return 0;

}
[lin@bogon C]$ ./a.out 
0x7fff6552d0c0
0x7fff6552d0c0

发现两种不同的方法对同一数组地址的获取,结果完全相同。那么两者到底有什么差别呢。原来,差别在于两者在内存中的所占据的大小不相同,通过数组名获取数组地址,在内存中只占据了sizeof(array_typr)的大小,反观通过取地址符号&对数组进行取值,其在内存中所占的大小为sizeof(array_tyoe)*array_size的大小。

在指针指向数组的情况下,指针能当数组名使用,数组名能当指针进行使用。让我们来看看代码。

#include<stdio.h>

int main(){

	int a[5] = {1, 2, 3, 4, 5};
	int* p1 = a;
	int i = 0;
	
	for(i=0; i<sizeof(a)/sizeof(*a); i++){

	printf("%d\n", a[i]);
	printf("%d\n", *(p1+i));
	printf("%d\n", i[a]);
	printf("%d\n", *(a+i));

	}
	
	return 0;

}

在让我们来看看结果

[lin@bogon C]$ ./a.out 
1
1
1
1
2
2
2
2
3
3
3
3
4
4
4
4
5
5
5
5

我们可以得出结论
a[i] = *(p+i) = *(i+p) = i[a];

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值