C与指针

来源:互联网 发布:程序员 白发老头图片 编辑:程序博客网 时间:2024/06/05 04:47

 1、静态/全局内存

static  静态声明的变量分配在这里,全局变量也使用这部分内存。 这些变量在程序开始运行时分配,指导程序终止才消失。所有函数都能访问全局变量,静态变量的作用域只在定义它们的函数内部。

2、动态内存:

  这些内存分配在堆上,可以根据需要释放,而且直到释放才消失。 指针引用分配的内存,作用域局限于引用内存的指针。

3、自动内存

  这些变量在函数内部声明,并且在函数被调用时才创建。 作用域局限于函数内部,而且声明周期也限制在函数的执行时间内。


PS :重点关注作用域和生命周期 


4、int *pi =0 // 正确

     into *pi =123; //错误  

 指针可以赋给0,但不可以赋给其他整数值

5、void 指针是通用指针,可以用来存放任何数据类型。

6、结构体中最好不要用char *,而要用char st[32]; 避免内存泄漏 ,出现野指针。

7、栈帧:

int *pi;

...............

{

int tmp =5;

     pi = &tmp;

}

// 这里pi成了野指针 

foo();

8、函数和指针:

 a、将指针传递给函数,这时函数可以修改指针所引用的数据,也可以更高效的传递大块信息(结构体,类等。)

 b、 声明函数指针。函数指针为控制程序的执行流提供了新的选择 。

9、程序栈

     程序栈是支持函数执行的内存区域,通常和堆共享。也就是说,它们共享同一块内存区域。程序栈通常占据这块区域的下部,而堆用的则是上部。

     程序栈存放栈帧,栈帧有时也称为活跃记录或活跃栈。栈帧存放函数和局部变量[l1] 。堆管理动态内存。



10、拼接字符串时,无论源字符串时存储在字符串字面量池中还是栈帧中,都不应该用来直接存放拼接后的结果,一定要专门为拼接结果分配内存。

11、传递指针 有2种形式: 

a.  给函数出传递一个空缓冲区让它填充并返回

b. 让函数动态分配缓冲区并返回

 传递缓冲区注意点; 

  ....  必须传递缓冲区的地址和长度

 ......  调用者负责释放缓冲区 

 .....  函数通常返回缓冲区的指针 

  这种方法把分配和释放缓冲区的责任都交给了调用者。  


// testchar.cpp : 定义控制台应用程序的入口点。
//


#include "stdafx.h"
#include <iostream>
#include <string>
#include <stdlib.h>
#include "stdio.h"
using namespace std;


#if _MSC_VER
#define snprintf _snprintf
#endif






char *format (char *buffer,const char *name ,size_t quantity)

//最重要的是一定要分配内存。
buffer = (char *) malloc(128);  //可以调用者分配内存,也可以函数内再分配内存
int st =sprintf (buffer,"Item :%s Quantity :%u",name,quantity);
cout <<st<<endl;
return buffer;



int main ()
{
 
char *buffer = NULL;   
char *str =NULL;
str = format(buffer,"Piao",25);
cout <<str<<endl;   //为什么没有出现野指针 ,也即内存泄漏 
free (buffer);


return 0;
}

  



 [l1]函数和函数中的局部变量。


0 0