随笔 - 1  文章 - 0  trackbacks - 0
<2026年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

常用链接

留言簿

随笔档案

文章分类

文章档案

搜索

  •  

最新评论


malloc 和 free 错误:

int main()
{
    char * p =NULL;
    p = (char * )malloc(100);
    
    strcpy(p , "hello");  "hello" 实际上是一个地址 将这个地址的内容复制到p 直到  \0 结束
    printf("%s" , p);
    
    if( p != NULL)
    {
        free(p);
//        p = NULL; 解决方法 
    }
    //此时 p 是个野指针 , 指向一块垃圾数据
    if( p!= NULL)
    {
        free(p);
    }
    
    return 0;
}

释放指针所指的空间, 但是指针的值没有重置为NULL
造成释放通过  if(p != NULL) 判断不出来, 所以 free() 时候要进行 指针重置为 NULL


indirect assignment use pointer
void changevar(int * p )
{
    *p = 20;
   //通过函数将运算结果甩出来!!!
   // **** 很方便的返回多个结果很强大  *****
}

int main()
{
    int a = 1;
    int * p = &a;
    
    *p = 10;
    printf("%d" , a);
//    ---------
    changevar(&a);
//  ---------    
    printf("%d" , a);

通过指针做函数参数的方法 间接赋值改变运算结果

形参的提醒:
void changevar(int * p )
//参数表中的参数和函数体的参数本质上是一样的
  
// 参数表的参数多了 个对外属性
    *p = 20;
}

字面量的提示:

使用二级指针修改一级指针的地址:
void getMem(char ** p)
{
    *p = 200;
    //用二级指针间接修改一级指针的指向地址 
}

int main()
{
    char * p = NULL;
    char ** q = NULL;
    
    p =100;
        printf("p: %d \n" , p);
    q= &p;
    getMem(q);     
    
    printf("p: %d" , p); 
    return 0;
    
    //p: 100
    
//p: 200
}


关键就是内存 和 函数调用的模型图;


为什么用一级指针无法改变以及指针的指向, 堆栈调用图很快就能理解!!!
void getMem2(char * p)
{
    p = 400;
    //用二级指针间接修改一级指针的指向地址 
}

int main()
{
    char * p = NULL;
    char * q = (char *)malloc(100);
    
    p =100;
    printf("p: %d \n" , p);
    *q= &p;
    getMem2(q);     
    
    printf("p: %d" , p); 
    return 0;
    
    //p: 100
    
//p: 100
}


指针使用的精髓:
不同函数同时操作一块内存空间时,通过内存首地址将内存传过去。运算结果在不同函数中并将其甩出来给主函数。
将计算过程在不同的函数中进行分解。


void getMem(char ** myp1, int * len1 )
{
    char * tmp1 = (char * )malloc(100);
    strcpy(tmp1 , "helloworld");
    *len1 = strlen(tmp1);
    *myp1 = tmp1;
    
    printf("in func getMem:\n");
    printf("tmp1: %s\n" , tmp1);
    printf("tmp1: %d\n" , tmp1);
    printf("len1: %d\n" , *len1);
}


int main(int argc, char * * argv)
{
    char * p1 = NULL;
    int  len1 = 0;
    
    getMem(&p1, &len1);
    
    printf("in main()\n "); 
    printf("p1: %s\n" , p1);
    printf("p1: %d\n" , p1);
    printf("len: %d\n" , len1);
     


    return 0;
}

/*
   in func getMem:
   tmp1: helloworld
   tmp1: 136160
   len1: 10
   in main()
   p1: helloworld
   p1: 136160
   len: 10
*/

指针做函数参数的典型应用场景:

main 函数 为了完成某个任务 ,写很多子函数。通过指针做函数参数实现 main 和子业务的分层。 模块划分的初步。
分层、 模块、 接口封装和设计、 软件的功能之间的划分 、软件信息系统


在一个函数中进行简介赋值:
int main()
{
    char from[120];
    char to[120];

    char * p1 = NULL;
    p1 = from;
    
    char * p2 = NULL;
    p2 = to;
    
    
    strcpy(p1, "helloworld");
    
    while( *p1 != '\0')
    {
        *p2++ = *p1++;
    }
    *p2 = '\0';//并没有将 '\0'拷进去直接打印会发生错误 
    
    printf("to: %s" , to);
    
    return 0;
}



指针间接赋值的推论:
使用n级指针 , 更改 n-1 级指针的值。

指针的半壁江山 10 铁律。
另外? 函数参数 回调函数


指针作函数参数的输入和输出特性:

主调函数提前分配内存 将内存传给被调用函数 叫指针的输入
被调函数分配内存将结果输出 供给主调函数使用

学习思路:
没有内存哪有指针, 指针是指向内存地址编号的变量。类型是变量的类型。
指针的关键在内存的分析。内存是如何分配的!!!


铁律4:应用指针必须和函数调用相结合(指针做函数参数)

编号

指针函数参数

内存分配方式(级别+堆栈)

主调函数

实参

被调函数

形参

备注

 

01

1级指针

(做输入)

分配

使用

一般应用禁用

分配

使用

常用

Int showbuf(char *p);   

int showArray(int *array, int iNum)

02

1级指针

(做输出)

使用

结果传出

常用

int geLen(char *pFileName, int *pfileLen);

03

2级指针

(做输入)

分配

使用

一般应用禁用

分配

使用

常用

int main(int arc ,char *arg[]); 指针数组

int shouMatrix(int [3][4], int iLine);二维字符串数组

04

2级指针

(做输出)

使用

分配

常用,但不建议用,转化成02

int getData(char **data, int *dataLen);

Int getData_Free(void *data);

Int getData_Free(void **data); //避免野指针

05

3级指针

(做输出)

使用

分配

不常用

int getFileAllLine(char ***content, int *pLine);

int getFileAllLine_Free(char ***content, int *pLine);

 

指针做函数参数,问题的实质不是指针,而是看内存块,内存块是1维、2维。

1) 如果基础类int变量,不需要用指针;

2) 若内存块是1维、2维。



posted on 2017-07-12 18:18 silvercell 阅读(121) 评论(0)  编辑 收藏 引用 所属分类: c raise