c语言指针进阶总结

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 是修饰指针变量,还是修饰所指向的内存空变

 

二位数组图解

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值