今天断断续续的把《征服C指针》的第二章看完了,以下是一些读书笔记和自己看书的时候有感而发写的东西,如果有错误,还请提出,我一定加以修改:)
操作系统会给程序分配虚拟内存
其实,现在的操作系统已经不把值存在电脑里的物理内存里了,这么说不对,存数据的地方还是物理内存,但是因为有并发行的存在,两个程序开启的两个进程,操作系统会给他们分配不同的虚拟内存,如果对这两个进程中的同一个变量进行取地址操作并打印,会发现他们的地址其实是相同的,这两个变量是在各自进程里面彼此独立无关的两个变量
现在的操作系统都会给应用程序的每一个进程分配独立的虚拟地址空间,真正保存内存数据的还是物理地址
C语言的变量有区间性的作用域,分为以下三种作用域
全局变量
在函数之外生命的变量,默认的会成为全局变量。全局变量在任何地方都是可见的,当程序被分割为多个源代码文件进行编译时,声明为全局变量的变量也是可以从其他源代码文件中引用的
文件内部的静态变量
全局变量,一旦添加了static,作用域就只限定在当前的源代码文件中,通过static指定的变量(包括函数),对于其他源代码文件是不可见的
局部变量
局部变量是指在函数中声明的变量,局部变量只能在包含它的声明的语句块(使用{}括起来的范围)中被引用
局部变量通常在它所在的语句块结束的时候被释放,如果你不想释放某个局部变量,可以在局部变量上加上static进行声明
C语言中的存储期
静态存储期
全局变量,文件内的static变量,指定static的局部变量都持有静态存储期,这些变量统称为静态变量
持有静态存储期的变量的寿命从程序运行时开始,到程序关闭时结束(静态变量一直存在于内存的同一个地址上)
自动存储期
没有指定static的局部变量,持有自动存储期
持有自动存储期的变量,在程序运行进入它所在的语句块时被分配内存区域,在语句块执行结束后这片内存区域被释放
malloc()函数分配内存的变量
这种变量的寿命一直延续到使用free()释放为止
C语言中的函数,是“指向函数的指针”。函数被配置在内存的只读区域
C语言的函数,在表达式中可以被解读成“指向函数的指针”
“字符串”是作为“char的数组”来表现的,字符串常量类型也是“char的数组”,表达式中的数组可以解读成“指向初始元素的指针”
什么是静态变量
静态变量时从程序启动到运行结束为止持续存在的变量,静态变量总是在虚拟地址空间上占有固定的区域
函数和全局变量,在分割编译和连接时,如果他们的名称相同,即使他们跨了多个源代码文件也被当作相同的对象来对待。进行这项工作的是一个被称为“链接器”的程序
函数中的变量,也就是自动变量,是存在于完全相同的地址上的,在生命自动变量的函数执行结束后,自动变量就不能使用了,所以不同的函数使用相同的内存区域是没有问题的
C语言中,在现有的被分配的内存区域之上以“堆积”的方式,为新的函数调用分配内存区域
在C语言里,自动变量是保存在栈中的
C语言的函数调用,调用的参数是从后往前按顺序被堆积在栈中的
这个函数里,自动变量buf的内存区域在函数执行结束后就会被释放
这条语句,参数在栈中的存放方向是这样的
这样看到“%d,%s\n”这个字符串,操作系统就能知道后面它需要几个参数
变长函数(还不是很明白)
如果函数原型声明的参数中出现…,对于这部分的参数是不会做类型检查的
如果assert(0)语句被调用,因为参数0为假,所以程序经过这里就会被强制终止
malloc()函数可以进行动态内存分配,它返回指向内存块初始位置的指针,内存分配失败,malloc()函数返回NULL,利用malloc()分配的内存被结束使用的时候,通过free()来释放内存
使用free()函数释放内存之后,对应的内存区域是不会立刻返回给操作系统的,所以如果两个指针同时指向一块malloc()区域,free(第一个指针后),后面的指针有时候也可以被访问到,当然这是运气好的时候。需要注意的是,调用free()之后,是不能引用对应的内存区域的(这就是为什么free了之后指针必须要赋值给NULL)
calloc()函数也是用来分配内存区域的,但是不同的是,他会将该区域清零返回
realloc函数的作用是用于改变已经通过malloc()分配的内存的尺寸
realloc()函数的参数
realloc将ptr指定的区域的尺寸修改成size,并且返回指向新的内存区域的指针
realloc()函数的工作模式
如果通过ptr传递的区域后面有足够大小的空闲空间,就直接实施内存区域扩展,如果没有足够多的空闲空间,就分配其他新的空间,然后将内容复制过去
realloc()函数的奇葩用法
如果通过ptr向realloc()传入NULL,realloc()函数的行为就和malloc()函数完全相同,如果通过size向realloc()函数传入0,realloc()的行为就和free()完全相同
大小端
0x12345678,用char*的指针去指向,打印的时候如果整数时颠倒过来存放的(打印78,56,34,12),这种配置方式一般称为小端
0x12345678,用char*的指针去指向,打印的时候如果整数时颠倒过来存放的(打印12,34,56,78),这种配置方式一般称为大端
大端,小端的区别是,大端方便给人看,小端方便计算机存储