4个二进制位可以表示一个16进制数字
1111 -->f
 
指针类型的意义:
指针类型决定了:指针解引用的权限有多大(整型指针解引用访问4个字节,字符型指针解引用只能访问1个字节) 
指针类型决定了,指针走一步,能走多远(步长) 
 
 
例题1:
1 2 3 4 5 6    int  a = 0x11223344 ; char * pc = &a;*pc = 0 ;  int * pa = &a;*pa = 0 ; 
 
char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用能访问四个字节。
例题2:
1 2 3 4 5 6 7 int  arr[10 ] = { 0  };int * p = arr;char * pc = arr;printf ("%p\n" , p);printf ("%p\n" , p + 1 );printf ("%p\n" , pc);printf ("%p\n" , pc + 1 );
 
 
野指针:指针指向的位置是不可知的
为什么出现野指针:
指针使用时未初始化:
 
指针越界:
1 2 3 4 5 6 7 8 9 10 int  arr[10 ] = { 0  };int * p = arr;int  i = 0 ;for  (i = 0 ; i <= 10 ; i++){ 	*p = i; 	p++; } 
 
指针指向的空间释放:
1 2 3 4 5 6 7 8 9 10 11 12 13 int * test ()  {	int  a = 10 ; 	return  &a; } int  main ()  {	int *p = test(); 	*p = 20 ; 	return  0 ; } 
 
退出test函数后空间释放,找不到指针p的地址。
总结:如何规避野指针?
1.指针初始化
2.小心指针越界
3.指针指向空间释放即设置NULL
4.指针使用之前检查有效性
 
 
指针的运算:
指针±整数:
1 2 3 4 5 6 7 8 int  arr[10 ] = { 1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10  };int * p = arr; int * pend = arr + 9 ; while  (p < pend){ 	printf ("%d\n" , *p); 	p++; } 
 
指针-指针:
1 2 3 4 5 6 7 8 9 int  main ()  {	int  arr[10 ] = { 1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ,10  }; 	char  c[5 ]; 	printf ("%d\n" , &arr[9 ] - &c[0 ]); 	printf ("%d\n" , &arr[9 ] - &arr[0 ]); 	return  0 ; } 
 
两指针相减的前提是指针指向同一块空间,指针-指针得到的是两个指针之间元素的个数 
例题:求字符串长度:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 int  my_strlen (char * str)  {	char * start = str; 	while  (*str != '\0' ) 	{ 		str++; 	} 	return  str - start; } int  main ()  {	int  len = my_strlen("abc" ); 	printf ("%d\n" , len); 	return  0 ; } 
 
 
指针和数组:
1 2 3 4 5 6 7 8 9 int  main ()  {	int  arr[10 ] = { 0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9  }; 	int * p = arr; 	int  i = 0 ; 	for  (i = 0 ; i < 10 ; i++) { 		 		printf ("&arr[%d]=%p <==> *(p+%d)=%p\n" ,i,&arr[i],i,p+i); } 
 
arr[i]=*(p+i) =*(arr+i);
&arr[i]=p+i=arr+i;
1 arr[2 ] <==> *(arr+2 ) <==> *(p+2 ) <==> *(2 +p) <==> *(2 +arr) == 2 [arr] 
 
 
二级指针:
1 2 3 4 5 6 7 8 int  main ()  {	int  a = 3 ; 	int * pa = &a; 	int ** ppa = &pa;           printf ("%d,%d,%d\n" , a,*pa,**ppa); } 
 
禁止套娃!!!