指针前钱解析

1,指针铁律
          1.1,指针是一种数据类型
               1, 指针也是一种变量,占有内存空间,用来保存内存地址。
                             指针既然是变量也要占用内存大小。一级指针的大小于其类型有关,二级以及二级以上的指针的大小是四个字节(32位机)
               2,*p操作内存
                                 在指针声明时,*号表示所声明的变量为指针
                                  在指针使用时,*号表示 操作 指针所指向的内存空间中的值
                                  *p 相当于通过地址(p 变量的值)找到一块内存;然后操作内存
                                   *p 放在等号的左边赋值(给内存赋值)    如  *p = 10;
                                   *p 放在等号的右边取值(从内存获取值)  int   a = *p;
                 3,指针变量和它指向的内存块是两个不同的概念
                             //含义 1 给 p 赋值 p=0x1111; 只会改变指针变量值(改变其指向), 不会改变所指的内容; p = p +1;p++加的是其步长而不是真正的1
                             //含义 2 给*p 赋值*p='a'; 不会改变指针变量的值,只会改变所指的内存块的值
                            //含义 3 =左边*p 表示 给内存赋值, =右边*p 表示取值 含义不同切结!
                           //含义 4 =左边 char *p
                          //含义 5 保证所指的内存块能修改
                  4,指针是数据类型,是指  它指向内存空间的数据类型
                                 含义 1:指针步长(p++) ,根据所致内存空间的数据类型来确定
                                                                      p++=  ->(unsigned char )p+sizeof(a);
                                结论:指针的步长,根据所指内存空间类型来定。
                               注意: 建立指针指向谁,就把把谁的地址赋值给指针.
                                           不断的给指针变量赋值,就是不断的改变指针变量(和所指向内存空间没有任何关

       1.2:间接赋值(*p)是指针存在的最大意义
                    1)两码事:指针变量和它指向的内存块变量
                    2)条件反射:指针指向某个变量,就是把某个变量地址否给指针
                   3)*p 间接赋值成立条件:3 个条件
                           a)2 个变量(通常一个实参,一个形参)
                           b) 建立关系,实参取地址赋给形参指针
                           c) *p 形参去间接修改实参的值
                     案例
                              Int iNum = 0; //实参
int *p = NULL;
p = &iNum;
iNum = 1;
*p =2 ; //通过*形参 == 间接地改变实参的值
*p 成立的三个条件:
                  4)引申: 函数调用时,n 指针(形参)改变 n-1 指针(实参)的值。
                                  //改变 0 级指针(int iNum = 1)的值有 2 种方式
                          //改变 1 级指针(eg char *p = 0x1111 )的值,有 2 种方式
                          //改变 2 级指针的(eg char **pp1 = 0x1111 )的值,有 2 种方式
                         //函数调用时,形参传给实参,用实参取地址,传给形参,在被调用函数里面用*p,来改变实参,把运算结果传出来。
                         //指针作为函数参数的精髓。
    1.3:理解指针必须和内存四区概念相结合
               1)主调函数 被调函数
                      a) 主调函数可把堆区、栈区、全局数据内存地址传给被调用函数
                      b) 被调用函数只能返回堆区、全局数据,不能返回栈上数据
                2)内存分配方式
                    a) 指针做函数参数,是有输入和输出特性的。
       1.4:应用指针必须和函数调用相结合(指针做函数参数)
                   
                   
                   
                             指针做函数参数,问题的实质不是指针,而是看内存块,内存块是 1 维、2 维。
                                     1)如果基础类 int 变量,不需要用指针;
                                     2)若内存块是 1 维、2 维,需要指针。
        1.5:一级指针典型用法(指针做函数参数)
                        一级指针做输入int showbuf(char *p)int showArray(int *array, int iNum)
                        一级指针做输出int geLen(char *pFileName, int *pfileLen);
                        理解
                              主调函数还是被调用函数分配内存
                              被调用函数是在 heap/stack 上分配内存
        1..6:二级指针典型用法(指针做函数参数)
                      二级指针做输入
                             int main(int arc ,char *arg[]); 字符串数组
                             int shouMatrix(int [3][4], int iLine);
                       二级指针做输出
                           int Demo64_GetTeacher(Teacher **ppTeacher);
                           int Demo65_GetTeacher_Free(Teacher **ppTeacher);
                          int getData(char **data, int *dataLen);
                          Int getData_Free(void *data);
                         Int getData_Free2(void **data); //避免野指针
                   理解
                       主调函数还是被调用函数分配内存
                       被调用函数是在 heap/stack 上分配内存
        1.7: 三级指针输出典型用法
                     三级指针做输出
                            int getFileAllLine(char ***content, int *pLine);
                            int getFileAllLine_Free(char ***content, int *pLine);
                    理解
                         主调函数还是被调用函数分配内存
                         被调用函数是在 heap/stack 上分配内存
      1.8: 杂项,指针用法几点扩充
                       1)野指针 2 种 free 形式
                               int getData(char **data,
                              int *dataLen);int getData_Free(void *data);
                             int getData_Free2(void **data);
                   2)2 次调用
                              主调函数第一次调用被调用函数求长度;根据长度,分配内存,调用被调用 函数。
                   3)返回值 char */int/char **4)C 程序书写结构 商业软件,每一个出错的地方都要有日志,日志级别
        1. 9:一般应用禁用 malloc/new   因为使用malloc/new就会伴随着内存泄漏
         

二级指针与多级指针 
           使用指针申请二维空间     
  #include <stdio.h>
#if 0
//利用返回值进行申请不连续的二维空间
void ** Shenqin(int base,int row,int line)
{
    void **p = (void **)malloc(sizeof(void*)*row);
    for(int i = 0;i<row;i++)
    {
        p[i] = (void *)malloc(base*line);
    }
    return p;
}
#endif
#if 0
//利用三级指针 参数进行申请不连续的二维空间
void Shenqin(void ***p,int base,int row,int line)
{
    *p = (void**)malloc(sizeof(void*)*row);//*p可以把***p降级为**p
    for(int i =0;i<row;i++)
    {
        (*p)[i] = (void*)malloc(base*line);
    }

}
#endif
#if 1
//申请连续的二维空间
void ** Shenq(int base,int row,int line)
{
    void **p = (void**)malloc(sizeof(int*)*row);
    void *p1 = (void *)malloc(base*row*line);
    int (*PA)[line] =p1;
    for(int i =0;i<row;i++)
    {
        p[i]=PA++;
    }
    return p;
}
//连续的二维空间的释放
void Free(void **p)
{
    free(p[0]);
    free(p);
}
#endif
#if 1
//不连续的二维空间的释放
void FreeKongjian(void **p,int row)
{
    for(int i = 0;i<row;i++)
    {
        free(p[i]);
    }
    free (p);
}
#endif
int main(void)
{

   // int **p = Shenqin(sizeof(int),3,4);
    //int **p=NULL;
   // Shenqin(&p,sizeof(int),3,4);
    int **p =Shenq(sizeof(int),3,4);
    for(int i = 0;i<3;i++)
    {
        for(int j = 0;j<4;j++)
            p[i][j]=i+j;
    }
    for(int i = 0;i<3;i++)
    {
        for(int j = 0;j<4;j++)
            printf("%d ",p[i][j]);
        putchar(10);
    }
    Free(p);
   // FreeKongjian(p,3);
    return 0;
}


2, 指针和数组的巨大区别
        





3,字符与一级指针的内存模型
     
 

4, const基础
int main()
{
const int a; //
int const b;
const char *c;
char * const d; char buf[100]
const char * const e ;
return 0;
}
 
int func1(const )
初级理解:const 是定义常量==》const 意味着只读
含义:
//第一个第二个意思一样 代表一个常整形数
//第三个 c 是一个指向常整形数的指针(所指向的内存数据不能被修改,但是本身可以修改)
//第四个 d 常指针(指针变量不能被修改,但是它所指向内存空间可以被修改)
//第五个 e 一个指向常整形的常指针(指针和它所指向的内存空间,均不能被修改)
Const 好处
//合理的利用 const,
//1 指针做函数参数,可以有效的提高代码可读性,减少 bug;
//2 清楚的分清参数的输入和输出特性
结论:
//指针变量和它所指向的内存空间变量,是两个不同的概念。 。 。 。 。 。
//看 const 是放在*的左边还是右边 看 const 是修饰指针变量,还是修饰所指向的内存空变

二位数组图解





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值