指针

1、指针

一句话,定义指针变量后,一定要初始化!

int *p,*q=NULL;  
 *q=6; *p=7;    

// 这是不允许的,p,q没有给定指向内存。p是一个随机值,不能随便改变p所指向的内存单元值,故上面*p=6是危险的;而q指向编号为0的内存单元,此内存不分配给任何变量,即q不指向任何变量,故*q=6是不允许的!

总之,使用指针,一定要初始化,是指针指向,确定的内存单元。

2、内存分配

下面两个例子

char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);           //输出乱码
}

char *GetMemory(void)
{
char *p = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);     //输出hello world
}
上面两个例子有什么区别,为什么一个输出乱码,一个正确输出呢?这是有关内存分配的问题!如下:

我们内存用户区分为:程序代码区、静态区、动态区。其中,静态区分为:全局变量、静态变量。动态区分为:堆区、栈区。

---------------
          Heap           |
---------------
          Stack         |
---------------
                Const   |(字符串常量通常放在data-const区中)
    data--Common|
                Data     |
---------------
          Code           |
---------------

A   静态数据区:内存在程序启动的时候才被分配,而且可能直到程序开始执行的时候才被初始化,如函数中的静态变量就是在程序第一次执行到定义该变量的代码时才被初始化。所分配的内存在程序的整个运行期间都存在,如全局变量,static变量等。
注意:初始化的全局变量和静态变量在一块区域,未初始化的全局变量与静态变量在相邻的另一块区域,同时未被初始化的对象存储区可以通过void*来访问和操纵,程序结束后由系统自行释放。

B   代码区:存放函数体的二进制代码;

C   栈区:存放自动变量。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元由编译器自动释放,超出其作用域外的操作没有定义。栈内存分配运算内置于处理器的指令集中,效率很高,但分配的内存容量有限。栈存放函数的参数值,局部变量的值等。

D   堆区(自由存储区):在运行的时候调用程序(如C中的malloc或C++中的new)分配内存,可以在任何时候决定分配内存及分配的大小,用户自己负责在何时释放内存(如用free或delete)。堆中的所有东西都是匿名的,这样不能按名字访问,而只能通过指针访问。


函数指针指向Code区,是程序运行的指令代码,数据指针指向Data,Heap,Stack区,是程序依赖以运行的各种数据

在文件作用域声明inline函数默认为static存储类型,const常量默认为static存储,如果加上extern,则为外部存储类型。

在回到上面例子

char p[] = "hello world";  实际上是将静态区字符串常量"hello world",复制一份到栈中,并把在栈内的首地址给p,即p是栈内"hello world"的地址,只在函数内能访问到。而,char *p = "hello world";实际上是,把字符串常量"hello world"在静态常量区内存首地址给p,其他函数都可访问到。因此,char p[] = "hello world"; 只在函数局部有效,而,char *p = "hello world";反回p的地址后可供其他函数访问。所以,上面两个例子中,第一个不能输出"hello world",而第二个能。

注意,类似于"hello world"的为字符串常量,存放在静态区的常量区内,内存管理的加强,常量是不允许改变的,在VC环境下是这样的。如下面例子:


void swap(char*m,char*n)
{
 char t=*m;
 *m=*n;
 *n=t;
}
int main()
{
 char g[]="swap";
// char *g="swap";
 swap(g,g+1);
 printf("%s/n",g);
 return 0;
}

用char g[]="swap";上面程序能正常交换,输出wsap,而用,char *g="swap";则不能交换,会出现错误。因为,char g[]="swap";中g是"swap"在栈内的复制品地址,此时的"swap"不为常量;而char *g="swap";中g是常量"swap"在静态区的地址,这是"swap"是不允许改变的!

//另外,堆中的所有东西都是匿名的,这样不能按名字访问,而只能通过指针访问。故,在为指针动态分配内存时,其指向是指向堆内一片存储空间的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值