C语言深度解剖读书笔记
前段时间把c语言程序设计看了一遍,感觉还是有很多比清楚的地方,可能是使用的不多,而且学的也不够深得缘故吧。因为平时从事android开发,也希望能够把android系统方面的东西搞懂,那么c语言不说精通也该要能够熟练使用吧。所以在网上看看相关的书籍就找到了《C语言深度解剖》。上面主要讲解c语言中容易搞错或者容易忽视的问题,毕竟细节决定成败,能把一些比较基础的细节性的东西搞懂了,c语言基础应该就会比较扎实吧,而且书本身也比较薄,根据个人习惯是希望读薄一点的书的,要是厚书就需要大毅力去读了。
1 关键字
1 关键字
1.1 auto
1.2 register
1.3 static
1.4 基本类型
1.5 sizeof
1.6 switch case
1.7 void
1.8 return
1.9 const
1.10 volatile
1.11 extern
1.12 union
5 内存管理
基本概念:
- 声明
有两重含义:- 告诉编译器这个名字已经匹配到一块内存空间,后面代码在用到该变量名时,该变量名是在别的地方定义的。注:* 声明可以出现多次。*
- 告诉编译器这个名字已经被预定了,其他地方不能再用这个名字了。
- 定义
c语言在创建一个对象时,会给一个对象分配一个内存空间,并为它取上一个名字,而这个名字就是变量名。
1.1 auto
缺省情况下,所有的变量都是用的关键字auto
。
1.2 register
请求编译器尽可能的将register修饰的变量存在CPU的寄存器中。注:是尽可能,而不是必须做,同时register修饰的变量可能并不在内存中,所以通过取地址符&
并不一定能够得到该变量的地址。
1.3 static
主要有2个作用:
- 修饰变量,静态全局变量和静态局部变量
- 静态全局变量,作用域仅限于变量被定义的文件中,从定义开始到文件结束。
- 静态局部变量,即在函数中定义的静态变量,作用域只在函数中。但是被static修饰的变量是存在内存的静态区,即使函数运行结束,该静态变量值也不会被销毁,在函数下次使用该变量时,仍然可以用到这个值。
- 修饰函数
在用static修饰函数的时候,表示该函数的作用域只在本文件中(称为内部函数),别的文件无法使用到该函数。
1.4 基本类型
- 基本类型:short int long float double char
- 构造类型:数组 结构体(struct) 公用体(union) 枚举类型(emurn)
- 指正类型:
- 空类型void:
1.5 sizeof
sizeof是一个关键字,在编译器编译的时候求值。而sizeof i
或者sizeof (int)
在32位系统下是4,sizeof int
是错误的,因为基本数据类型前面不能加sizeof。
1.6 switch case
C语言中,在 switch后面接是一个表达式,而case后面是只能是整型、字符型常量或者常量表达式。
1.7 void
如果一个函数有void修饰则表示无返回值,而void指针类型转换成其他指针类型是不用强制转换的。
1.8 return
return语句不能返回指向"栈内存"的"指针",因为该内存在函数体结束时会被自动销毁。
1.9 const
const是constant的缩写,它修饰的变量为只读的变量,其值在编译的时候不能被使用,因为编译器在编译的时候也不知道该内存中存储的内容。
在编译时,编译器不为普通const只读变量分配存储空间,而是将它保存在符号表中。
const int * p;
int const * p;
int * const p;
const int * const p;
const int *p
;修饰的是*p
,p为指针,*p
为指针指向的对象,不可变。
int const *p
;修饰的是*p
,p为指针,*p
为指针指向的对象,不可变。
int *
const p;修饰的是p
,p为指针,p不可变p指向的对象可变。
const int *
const p;前面一个const修饰的是*p
,后面一个修饰的是p,指针p和p指向对象的都不可变。
在const修饰函数参数时,表示不希望这个参数在函数体内被改变。
1.10 volatile
用它修饰的变量,编译器对访问该变量的代码就不能再进行优化以提升特殊地址的稳定访问,即每次必须从volatile变量的内存位置读取其内容来操作。
1.11 extern
被extern修饰的变量或者函数表示他们的定义是在别的文件中
1.12 union
union维护足够空间放置多个数据成员,这些数据成员公用一个空间,同一时间只能存储其中一个数据成员,所有数据成员具有相同的起始地址。
计算机数据存储大端小端问题
- 大端 字数据的高字节存储在低地址中,字数据的低字节存放在高地址中。
- 小端 字数据的高字节存储在高地址中,字数据的低字节存放在低地址中。
使用union类型来判断目标机器的数据存储类型。
#include<stdio.h>
int checkSystem()
{
union check
{
int i;
char ch;
}c;
c.i=1;
return (c.ch==1);
}
int main()
{
printf("destination machine is little endian:%d\n",checkSystem);
return 0;
}
5 内存管理
堆:
由malloc系列函数或new操作符分配的内存。其生命周期由free或delete决定。在没有释放之前一直存在,知道程序结束。其特点是使用灵活,空间比较大,但容易出错。栈:
保存局部变量。栈上的内容只在函数的范围内存在,当函数运行结束,这些内容也会自动被销毁。其特点是效率高,但空间大小有限。静态区:
保存自动全局变量和static变量(包括statci全局和局部变量)。静态区的内容在整个程序的生命周期内都存在,由编译器在编译的时候分配。