您的位置:首页 > 编程语言 > C语言/C++

C语言之内存四区1

2015-09-15 16:56 302 查看
一、数据类型的本质

1.数据类型可理解为创建变量的模具(模子);是固定大小内存的别名。我们可以通过运算符sizeof求出数据的长度;

2.sizeof是操作符,不是函数;sizeof测量的实体大小为编译期间就已确定数据类型可以取别名、测量大小;

二、变量本质:
(一段连续)内存空间的别名、内存空间的标号。
有三种修修改变量的方法:

1.
直接修改

2.
间接。内存有地址编号,拿到地址编号也可以修改内存;于是。。。(指针)横空出世了!

3.
c++ 引用

三、内存四区模型和函数调用模型

1.
函数1调用函数2,函数1称为主调函数 函数2称为被调用函数;

2.
规则1:Main(主调函数)分配的内存(在堆区,栈区、全局区)都可以在被调用函数里使用吧。

3. 规则2:在被调用函数里面分配的内存

每个变量的生命周期都是在自身函数中分配的,叫做局部变量,随着函数的死亡而死亡,如果主调函数没有死亡,那么被调函数可以使用主调函数的变量。这种模型就是进栈和出栈模型,变量随着函数进栈保存数据,随着函数出栈把数据销毁;

1、如果在被调用函数里面的临时区(栈)分配内存,主调用函数是不能使用的。
全局区://c++编译器优化
char *getStr1()
{
char *p = "abcd1";
return p;
}
字符串abcd1被分配到静态全局区,指针p是指向全局区中的字符串abcd1,而在函数getStr()中并没有分配内存给字符串abcd1,只分配了指针p的内存

临时区stack
char * getStr3()
{
char buf[100];
memset(buf, 0, sizeof(buf));
strcpy(buf, "abcd1");
return buf;
}
在函数中,为数组开闭内存100字节大小,并且使其值设置0,现在数组中存放是字符串abcd1字节,buf为数组为首地址,返回是时候,因为buf数值是局部变量,所以被编译器销毁,作为buf地址是一个垃圾内存块;

四、指针是一种数据类型

1.
指针也是一种变量,占有内存空间,用来保存内存地址测试指针变量占有内存空间大小

2.
*p操作内存

在指针声明时,*号表示所声明的变量为指针
在指针使用时,*号表示 操作 指针所指向的内存空间中的值
*p相当于通过地址(p变量的值)找到一块内存;然后操作内存
*p放在等号的左边赋值(给内存赋值)
*p放在等号的右边取值(从内存获取值)
3. 指针变量和它指向的内存块是两个不同的概念
//含义1
给p赋值p=0x1111; 只会改变指针变量值,不会改变所指的内容;p = p +1;
//含义2
给*p赋值*p='a'; 不会改变指针变量的值,只会改变所指的内存块的值

//含义3
=左边*p 表示 给内存赋值, =右边*p 表示取值 含义不同切结!

//含义4 =左边char *p

//含义5
保证所指的内存块能修改

4. 指针是一种数据类型,是指它指向的内存空间的数据类型

含义1:指针步长(p++),根据所致内存空间的数据类型来确定

p++-->(unsigned char )p+sizeof(a);

结论:指针的步长,根据所指内存空间类型来定。

五、多级指针做函数参数的理解

1.关于形参:

写在函数上形参变量,还是写在函数里面的变量,

从CC++编译的角度来讲,是没有任何区别的(分配4字节内存);

只不过是 写在函数上形参变量 ,具有对外的属性而已

2. 数据类型分为两种,一个是简单的数据类型,一个是复杂的数据类型。碰见复杂的数据类型不能用简单的数据类型的思
维去思考它。

3.
nt getbuf01(char   *p); int getbuf01(char*     p);
int getbuf02(char **p); int getbuf02(char *   *p); getbuf02(char **        p);
int getbuf03(char (*p)[]); int getbuf03(char (*p)      []);  int getbuf03(char (     *p)[     ]);
int getbuf03(char p[10][30]);
int getbuf04(char *****p);

角度1
站在c++编译器的角度 指针就是一个变量,除此之外啥也不是!不管是1个* 还是8个*对c++编译器来讲,只会分配
4个字节内存

角度2:当我们程序员要使用指针所指向的内存空间的时候,我们关心,这个内存块是一维的,还是二维的。

一般情况:1级指针代表1维,二级指针代表二维。。。

如果有超过char ***级及3级以上的指针,则不代表几维的内存。。。

六、C和java的堆栈区别

1. C可以在临时区分配内存块。。。。。。。java不行

{

char *p1 = 0; //
strcpy(p1, "abcdefg");
strcpy(0, "abcdefg"); //抛砖:在两个函数里面就不一定能明白

}
七、[] *的本质

1. *p 是我们程序员手工的(显示)去利用间接赋值

2. [] 只不过是,c/c++ 编译器帮我们做了一个*p的操作。。。。。。

// buf4[i]======> buf4[0+i] ====>  *(buf4+i)
//===*(buf4+i)   --> bu4[i];


八、int a[10] a是个常量

{
int a[10]; //a是一个指针===》a常量指针===》为什么c++
int *p = a;
p ++;
a ++;
}
//c++编译器要拿着a去析构内存,为了避免你把a的指向改变。。。。。


九、*p是指针存在的最大意义

1. 间接赋值成立的是3个条件

条件1 //定义1个变量(实参) //定义1个变量(形参)

条件2//建立关联:把实参取地址传给形参

条件3://*形参去间接地的修改了实参的值。

2. 间接赋值的工程意义

//函数调用时,形参传给实参,用实参取地址,传给形参,在被调用函数里面用*p,来改变实参,把运算结果传
出来。

//指针作为函数参数的精髓。

//C语言特有的想象,是C语言的精华。。。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: