C语言学习笔记之指针的运算

C语言中指针的运算

/*
  以下实验是探究当指针不是指向一片连续的空间 
  而是指向数组时的情况 
  编译器为TDM-GCC 4.9.2 64-bit Release 
*/
	int a1[]={0,1,5,9,4,}; 为避免偶然 我不按顺序排数
	int *p = a1;
	printf("p = %p\n",p);
	printf("p+1 = %p\n",p+1);
	printf("sizeof(int) = %d\n",sizeof(int));//运行之后可以发现p与p+1的差值就是一个 sizeof(int)
	
	double a2[]={0,1,2,3,4,}; 
	double *q = a2;
	printf("q = %p\n",q);
	printf("q+1 = %p\n",q+1);
	printf("sizeof(double) = %d\n",sizeof(double));//同理运行之后可以发现是一个 sizeof(double)
/*
  那为什么指针加一相当于加一个数据类型长度?
  因为在一个数组里,一个元素分为对于数据类型的字节,
  如果int 一个数组 一个元素被划分为4个字节 指针代表一个地址 
  如果加一不是加一个数据类型长度,而是地址加一,
  那么加了一之后还是这个元素,就显得毫无意义,
  所以就设置为加一个数据类型长度,本质上就是移动一个元素下标,移动一个位置
*/ 
	printf("*p = %d\n",*p);  
	printf("a1[0] = %d\n",a1[0]);		// *p = a1 --> *p = a1[0] 那么*(p+n)等于多少?
	printf("*(p+2) = %d\n",*(p+2));
	printf("a1[2] = %d\n",a1[2]);		//可以看到  *(p+2)==a1[2] 
	printf("*(p+3) = %d\n",*(p+3));
	printf("a1[3] = %d\n",a1[3]);		//可以看到  *(p+3)==a1[3] 
	
	//刚才之所以加括号是因为*是一个单目运算符 优先级高于()
	//那么*p+1等于多少??
	printf("*p+1 = %d\n",*p+1);// *p+1=1
	printf("*p+2 = %d\n",*p+2);// *p+2=2
/*
  有无括号是有区别的 
  *(p+n)有括号 此时为地址加n个数据类型长度 因为p是地址 相当于a1[0]移动n个下标
  *p+n   无括号 此时为数值加一 因为*p就是值 相当于就是*p= a1=&a1[0] =0 再加上数值n 而已
  指针可用运算符有
   -,-=,+=,++,--
*/ 
	//那么指针与指针之间的运算呢?
	int *p1 = &a1[3] ;
	printf("p = %p\n",p);//	p = 000000000062FE20
	printf("p1 = %p\n",p1);//p1 = 000000000062FE2C 
	printf("p1 - p = %d\n",p1-p);//	p1 - p = 3
/*
   两个十六进制的地址相减为C C即为十进制12
   此时p1=9,p=0,显然p1-p不是两者差值,那3是什么?
   3是由地址差值除以数据类型长度得来的 即12/4=3
   那么这就说明,指针与指针的运算又与指针本身加减是有所不同的
   指针之间的运算是地址之间的运算,这就很有意思了 
*/   	
	//说点题外话
	int array[]={0,1,2,3,4,5,6,-1};
	int *arr = array; 
	while(*arr != -1)
	{
		printf("%d ",*arr++);//结果输出0,1,2,3,4,5,6 
	}
/*
  指针也可以用作数组空间的连续操作,这其中还是有历史故事的。
  C语言初期,电脑运行速度并没有那么快,
  当时的*p++,表示可以把c语言代码翻译成机器执行指令, 
  因此代码跑起来就更快,这也是指针的来源。 
*/ 

/*
   补充:
   指针是不可以继续乘除的;
   指针之间也可以比较,实质是地址的比较;
   常用比较运算符,指针也可以使用;
*/ 

你可能感兴趣的:(C语言)