前言
为什么要开一篇这个呢,主要是因为感觉自己对c语言掌握是越来越模糊了,于是开一篇这个记录一下,同时也有益数据结构的学习,顺便打打二进制的基础(
基于《C primer》的学习,前面的基本语句部分我这里就不赘述了,直接从指针开始看
编程过程:
定义程序的目标 -> 设计程序 -> 编写代码 -> 编译 -> 运行程序 -> 测试和调试程序 -> 维护和修改程序
特性
可移植性
即在一种系统中编写的c程序稍作修改或不修改就能在其他系统运行,如需修改,也只需改主程序的头文件的少许项
可以访问硬件、操控内存中的位
编译型语言
编译
编译器
是把源代码转换成可执行代码的程序,可执行代码即计算机的机器语言表示的代码
还会检查c语言程序是否有效
一些编译器:GNU中的gcc,LLVM中的clang
准备一个c程序的过程:
链接器
把编写的目标代码、系统的标准启动代码和库代码这三个部分合并成一个可执行文件
源代码文件:包含程序员使用的任何编程语言编写的代码
目标代码文件:包含机器语言代码
可执行文件:组成可执行程序的完整机器语言代码
9 函数
9.7 指针简介
指针是一个值为内存地址的变量(或数据对象)
ptr = &pooh; // 把pooh的地址赋给了ptr
对于这条语句,我们说ptr“指向”pooh
ptr和&pooh的区别是ptr是变量,而&pooh是常量
间接运算符*
也称作解引用运算符
ptr = &bah;
然后使用间接运算符*
,可以找出储存在bah中的值
val = *ptr; // 找出ptr指向的值
上面两段代码合起来相当于val = bah;
地址运算符&,*
后跟一个变量名时,&给出该变量的地址
后跟一个指针名或地址时,*给出储存在指针指向地址上的值
nurse = 22;
ptr = &nurse; // ptr为指向nurse地址的指针
val = *ptr; // 把ptr指向的地址上的值赋给val
最终会把22赋给val
声明指针
一些指针操作要求知道操作对象的大小,另外程序必须知道储存在指定地址上的数据类型
所以声明指针的方式如下:
int *pi; // pi是指向int类型变量的指针
char *pc; // pc是指向char类型变量的指针
float *pf,*pg; // pf、pg都是指向float类型变量的指针
注:对于*pc,我们已经知道是char类型,但是pc本身作为一个指向char类型的指针,其值是一个地址,大部分情况下是一个无符号整数,但是指针并不能被认为是整数类型,而是一种新类型,一些处理整数的操作不能用来处理指针
具体声明过程如图所示:
14 结构
14.3 定义结构变量
struct book library;
// 上面的声明是下面的简化
struct book{
char title[MAXTITL];
char author[AXAUTL];
float value;
}library;
在结构变量的声明中,struct book
的作用相当于一般声明中的int或float
初始化结构
int count = 0; // 初始化变量
int fibo[7] = {0,1,1,2,3,5,8} // 初始化数组
// 初始化结构变量
struct book library = {
"The Pious Pirate and the Devious Damsel",
"Renee Vivotte",
1.95
};
访问结构成员
结构成员运算符.
例:library.value
即访问library的value部分
.value
本质上相当于book结构的下标
结构的初始化器
14.11 枚举类型
声明符号名称来表示整型常量
声明:
enum spectrum{red, orange, yellow, green, blue, violet}
把enum spectrum
作为一个类型名使用,枚举了spectrum变量可能有的值
enum spectrum color;
使color作为该类型的变量
14.12 typedef
typedef工具是一个高级数据特性,利用typedef可以为某一类型自定义名称
与#define
类似,但是又有不同:
- typedef创建的符号名只受限于类型,不能用于值
- typedef由编译器解释,不是预处理器
定义BYTE为表示1字节的数组,接下来就能用BYTE定义变量:
typedef unsigned char BYTE;
BYTE x,y[10],*z;
用于结构:
typedef struct complex{
float real;
float imag;
}COMPLEX;
为经常出现的类型创建一个方便、易识别的类型名