// 
//  指针总结.h 
//  0730代码实践 
// 
//  Created by apple on 15-7-30. 
//  Copyright (c) 2015年 itcast. All rights reserved. 
// 
 
#ifndef _730__________h 
#define _730__________h 
 
 
#endif 
 
指针跟各种类型数据的结合分类 
#warning---------->>>>>>>>>>>普通指针<<<<<<<<<<<<<<-------------- 
分为一级指针和二级指针 
******************************************************* 
----------------------指针概念与定义方法 
1、指针变量 
 
用来存放地址的变量,就是指针变量 
 
2、指针? 
 
就是地址 
 
3、指针变量的定义 
 
 
数据类型  *指针变量名; 
 
 
int *p;   //定义了一个指针变量,变量名是p 
//int表示,p只能存放一个int类型的变量的地址 
 
char *p1; //定义了一个指针变量,变量名是p1 
//p1只能存放一个char类型数变量的地址 
 
int num=10; 
char *p = # //警告 
 
 
4、指针变量定义的注意事项 
 
1)“*”  必须得有,如果没有就相当于定义一个普通变量 
2)指针变量能用来存放数值或者字符之类的吗? 不能 
3)指针变量,归根结底还是变量,也有全局和局部变量之分 
 
----------------------指针变量初始化和引用 
指针变量也是变量 
指针变量的使用: 定义指针变量  ----> 初始化指针变量 ---> 使用(使用指针变量间接的存取内存单元的值) 
 
指针变量如果不初始化会有什么后果? 
结论:如果一个指针变量定义以后,如果不进行初始化 
     这个指针变量存放的事一个垃圾数,这个指针变量,称之为 野指针 
 
一定要避免操作野指针,因为可能会带来意向不到的错误 
    int *p10;  //值是一垃圾值,有可能存放是系统程序的地址 
    *p10 = 438; //可能会造成系统崩溃 
 
******************************************************* 
 
 
两个指针变量之间的运算 
 
1)两个指针之间的减法运算 
 
(1)0x0006  - 0x0003   =  3  (意义不大) 
 
(2)常见的用法:两个指针都指向同一个数组 
 
i.判断两个指针变量指向的元素是否连续 
ii.判断两个指针变量之间相隔几个元素 
 
int a[5]={1,2,3,4,5}; 
int *p = a; //p指向了数组的第一个元素 
int *p1 = &a[3]; //p指向了数组的第四个元素 
 
 
注意:两个指针变量之间没有加法运算 
 
 
2)两个指针之间的关系运算 
 
// p1 > p 
//1    表示p1在高位 
//0    p在高位或者他们指向了同一个位置 
二级指针:如果一个指针变量存放的是另一个指针变量的地址,则称此指针变量为二级指针 
int *p=&a;int **p1=&p; 
指针为什么要区分类型? 
        不同类型的指针变量在内存中占用8个字节 
        为什么都占用8个字节还要区分类型呢? 
        //如果定义指针变量不定义类型,那么它在取*也就是在取其中的值的时候,就不知道应该读取几个字节,而定义了类型之后,如果是Int类型的就读四个字节,char类型的就读一个字节。 
 
#warning---------->>>>>>>>>>>指针与数组<<<<<<<<<<<<<<-------------- 
数组指针 与指针数组,其中数组指针有分为一维数组指针 和二维数组指针 
 
******************************************************* 
 
数组指针: 
 
    指向数组元素的指针 
 
数组指针的作用: 
 
    使用数组指针间接访问数组的元素 
 
数组指针的定义: 
 
    int *p; 
 
数组指针的初始化: 
 
    int a[4]={1,2,3,4}; 
 
    int *p = a;  //数组指针,定义了一个指针变量p赋值数组的首地址(第一个元素的地址),p指向数组的第一个元素 
 
    int *p = &a[0]; //等价上面一句话 
 
数组指针如何访问数组的元素: 
 
    1)p+1   表示指向数组的下一个元素 
    2)p-1   指向数组的上一个元素 
使用数组指针和使用数组名的区别 
    p = p+1 
    *p++ 
   // p是一个指针变量,既然是一个变量,它存放的值是可以改变的 
    printf(" *p++   = %d\n",*p++); 
    printf(" *p = %d\n",*p); 
//学习的误区:   数组名 a是一个常量  *(10++) 
//数组名++ 这是错误的 
   //printf(" *a++   = %d\n",*a++); //错误的 
printf(" *a = %d\n",*a); 
 
******************************************************* 
 
 
二维数组指针 
 
行指针,用来指向二维数组的每一行,存放的是行的首地址 
 
定义格式:  数据类型  (*行指针变量名)[数组第二维的长度]; 
 
二维数组指针的初始化 
 
int a[2][3]; 
int b[2][2]; 
float f1[4][4]; 
 
//假设我要定义一个指向数组a的一个行指针 
// a  = &a[0]  = &a[0][0]  = a[0] 
int (*p)[3] = a; 
 
二维数组指针的使用 
 
*(*(p+i)+j)  //就是获取二维数组的每个元素 
 
 
int arr[2][3] = {1,4,7,2,5,8}; 
 int (*p)[3] = arr; 
/* 
 p是一个指向二维数组的指针,所以他存放的相当于数组名,也就是第一行地址 
  
 p+i    就代表着第i行的第一个元素的地址 
  
 *p   就代表着第一行第一个元素的地址 
  
 *(p+i)  就代表着第i行的对应的内容(第一个元素的地址)  *(p+i)  == a[i] 
  
 *(p+i)+j 就代表着第i行的第j个元素的地址 
  
 *(*(p+i)+j) 就代表着第i行的第j个元素的地址所对应的值 
  
 */ 
a[0][0]=0x7fff5fbff810    a[0][1]=0x7fff5fbff814    a[0][2]=0x7fff5fbff818 
a[1][0]=0x7fff5fbff81c    a[1][1]=0x7fff5fbff820    a[1][2]=0x7fff5fbff824 
 
p = 0x7fff5fbff810     指向二维数组的第一个元素(第一行地址)的地址 
p+1 = 0x7fff5fbff81c   第二行地址 
*p = 0x7fff5fbff810    第一行第一个元素的地址 
*p+1 = 0x7fff5fbff814  第一行第二个元素的地址 
**p = 1 第一行第一个元素的地址所对应的值 
 
******************************************************* 
指针数组: 
 
存放指针的数组,就是指针数组 
 
指针数组的定义: 
 
数据类型  * 数组名[数组长度]; 
int *pa[3]; 
 
//定义了一个指针数组,数组名是pa,可以用来存放3个指针(必须是int类型变量的指针) 
 
指针数组的使用: 
 
int a=3,b=4,c=5; 
int *pa[3]={&a,&b,&c}; 
 
pa[0]  a的地址 
 
pa 
 
int arr[10] ={1,23}; 
int *p 
double *p1; 
 
 
指针数组 
int arr[2][3] = {1,4,7,2,5,8}; 
int *pa[2] = {arr[0],arr[1]}; 
a[0][0]=0x7fff5fbff810    a[0][1]=0x7fff5fbff814    a[0][2]=0x7fff5fbff818 
a[1][0]=0x7fff5fbff81c    a[1][1]=0x7fff5fbff820    a[1][2]=0x7fff5fbff824 
 
 
&pa = 0x7fff5fbff800 指针数组的地址 
pa = 0x7fff5fbff800      指针数组的数组名,指向数组第一个元素的地址&pa[0] 
&pa[0] = 0x7fff5fbff800  第一个元素的地址 
*pa = 0x7fff5fbff810     *&pa[0]指向数组第一个元素的地址所对应的内容 
pa[0] = 0x7fff5fbff810   指向数组第一个元素的地址所对应的内容 
*pa[0]=1    * arr[0]  也就是二维数组第一个元素的值 
 
******************************************************* 
 
 
 
#warning---------->>>>>>>>>>>指针与字符串<<<<<<<<<<<<<<-------------- 
字符串指针: 
 
定义: char *字符串指针变量名 = "字符串内容"; 
 
用作:用来保存一个字符串 
 
char *str = "zfbanzhang zaiyiqi"; 
//"zfbanzhang zaiyiqi" 这个字符串存储在常量去 
//str 只保存了字符串常量的首地址 
 str = "I LOVE YOU"; 
//str是指针变量 
//str重新指向另外一个字符串常量 "I LOVE YOU" 
//保存的是 "I LOVE YOU" 字符串常量的首地址 
 
 
#warning---------->>>>>>>>>>>指针与函数<<<<<<<<<<<<<<-------------- 
******************************************************* 
 
指针函数: 
 
    返回值是指针的函数 
 
指针函数的定义 
 
    指针类型 * 函数名(){ 
     
     
        return 地址; 
    } 
 
******************************************************* 
函数指针变量 
 
存放函数的首地址的指针变量就是函数指针变量 
 
函数指针变量的定义 
 
返回值类型  (*变量名)(函数的参数); 
 
函数的声明: 
 
int sum(int a,int b);----> 函数指针 int (*p1)(int a,int b); 
 
//定义了一个函数指针 p1 
//p1可以存放 返回值是int类型,并且有两个形参,形参的类型还都是int类型的函数的地址 
 
//函数指针的初始化 
 
p1 = sum;  //sum存的就是函数在内存中的首地址 
 
//注意:定义函数指针的时候,可以不用写形参名 
int (*p1)(int ,int ); 
 
 
函数指针的使用 
 
int sum(int x,int y){ 
     
    return x+y; 
     
} 
 
//1、定义函数指针 
int (*p)(int ,int ); 
//2、给函数指针初始化 
p = sum;  //p也指向了sum函数 
 
//3、用函数指针间接的调用函数 
//     (*p)(23,45); 
int s = p(23,45); 
 
 
 
 
 |   
        
 
    
    
    
     
 
 |