C指针 C指针是C关键核心 一个变量的地址称为该变量的“指针”。例如地址2001是变量j的指针。 如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量”。指针变量就是地址变量,用来存放地址,指针变量的值是地址。 指针是一个地址,指针变量是存放地址的变量 定义指针变量 类型名 * 指针变量名 如:int *p_1,*p_2; #include<stdio.h> int main(void) { int i = 5,j = 1; int *p_1,*p_2;//定义指针变量 p_1 = &i;//把变量的地址赋给指针变量 p_2 = &j; printf("a=%d,b=%d\n",i,j);//输出变量值 printf("&a=%d,&b=%d\n",&i,&j);//输出变量地址 printf("*p_a=%d,*p_b=%d\n",*p_1,*p_2);//输出指针变量指向的值 printf("p_a=%d,p_b=%d\n",p_1,p_2);//输出指针变量里存放的地址 return 0; }
从程序中得到如下信息:
1、指针变量前面的“*”表示该变量的类型为指针型变量。指针变量名是p_1和p_2,而不是*p_1,*p_2。所以赋值时赋给p_1,p_2.
2、在定义指针变量时必须指定基类型。指针的移动和运算涉及字节的长短问题,故需要基类型
3、一个变量的指针的含义包括两个方面,一是以存储单元编号表示的地址(如编号为2000的字节),一是它指向的存储单元的数据类型(如int\char\float等).
4、指针变量中只能存放地址(指针),不要将一个整数赋给一个指针变量
C引用指针变量的三种情况
1、给指针变量赋值
p=&a ===>将a的地址赋给指针变量p,指针变量p的值是变量a的地址,p指向a
2、引用指针变量指向的变量
*p=1;==>表示将整数1赋给p当前所指向的变量,如果p指向变量a,则相当于把1赋给a,即a=1
3、引用指针变量的值
printf(“%d”,p);==>作用是以10进制数形式输出指针变量p的值,如果p指向了a,就是输出了a的地址,即&a.
& 取地址运算符。&a是变量a的地址
* 指针运算符(或“间接访问”运算符),*p代表指针变量p指向的对象。
#include <stdio.h> int main(void) { int a,b; int *p1,*p2,*p; printf("Please enter the a,b valuse is :\n"); scanf("%d,%d",&a,&b); p1 = &a; p2 = &b; printf("The old address p1=%d,p2=%d\n",p1,p2); if ( a<b ) { p = p1; //交换了地址 p1 = p2; p2 = p; } printf("The new address p1=%d,p2=%d\n",p1,p2); printf("a=%d,b=%d\n",a,b); printf("max=%d,min=%d\n",*p1,*p2); return 0; } /* Please enter the a,b valuse is : 1,2 The old address p1=2686736,p2=2686732 The New address p1=2686732,p2=2686736 a=1,b=2 max=2,min=1 */
指针变量作为函数参数
将一个变量的地址传送到另一个函数中
/*利用指针地址的传递来交换变量*/ #include<stdio.h> int main(void) { void max(int *,int *);//这里定义不能省略*符号,表示传递的变量是指针类型,如果不写,则在子函数行会报错 int a,b; int *p_1,*p_2; printf("Please enter the a and b values:\n"); scanf("%d,%d",&a,&b);//输入a,b值 p_1 = &a;//将a,b地址赋值给整型指针变量p_1和p_2 p_2 = &b; if(a<b) max(p_1,p_2);//传递指针变量内放两个变量的地址 printf("The DESC values is :%d,%d",*p_1,*p_2); return 0; } void max(int *p1,int *p2) { int t; t = *p1;//交换指针变量里的值 *p1 = *p2; *p2 = t; }
数组元素的指针
一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的
地址放到一个指针变量中)。所谓数组元素的指针就是数组元素的地址。
int *p=&a[0];<====>int *p;p=&a[0];<===>int *p=a;
至此,引用一个数组元素,有下面两种方式
下标法==>a[i];
指针法==>*(a+i)或*(p+i).其中a是数组名,p是指向数组元素的指针变量
/*如果在利用指针对数组里元素进行访问时,要注意指针的指向及 移动情况,如果越界的话,一般不会出错,但是逻辑上是有问题的,不能获得你想要的结果 */ #include<stdio.h> int main(void) { int a[10],*p=a; int i,j; printf("please enter the ten number values is :\n"); for ( i=0;i<10;i++ ) { scanf("%d",p++); } p = a;//这里的处理是将指针重新指向a[0],因通过上步的循环处理,指针已经指向了a[9]这个地址,如果再做循环则是错误的数据 for ( j=0;j<10;j++,p++) { printf("%d\t",*p); } return 0; }
指针几个场景的小技巧
1、
p++;
*p;
p++使p指向下一元素a[1]。然后若再执行*p,则得到下一个元素a[1]的值。
2、
*p++
由于++和*同优先级,结合方向为自右而左,因此它等价于*(p++)。先引用p的值,实现*p的运算,然后再使p自增1.
3、
*(p++)与*(++p)作用
前者是先取*p值,然后使p加1.后者是先使p加1,再取*p。
若p初值为a(即&a[0]),若输出*(p++),得到a[0]的值,而输出*(++p),得到a[1]的值。
4、++(*p)
表示p所指向的元素值加1,如果p=a,则++(*p)相当于++a[0],若a[0]的值为3,则执行++(*p)(即++a[0])后a[0]的值为4。
注意:是元素a[0]的值加1,而不是指针p的值加1.
5、
如果p当前指向a数组中第i个元素a[i],则:
*(p–)相当于a[i–],先对p进行”*”运算(求p所指向的元素的值),再使p自减
*(++p)相当于a[++i],先使p自加,再进行”*”运算
*(–p)相当于a[–i],先使p自减,再进行”*”运算