为什么阅读《C Primer Plus》第六版
准备好好研究下redis源码,但是很久没用c语言写代码了,平时工作主要用java和js。
所以准备重新阅读学习下c语言经典书籍:C Primer Plus。
更好地阅读redis源码。
第10章 数组和指针
数组
int powers[4]={1,2,3,4};
- 只读数组 const int days[12] 只获取数据,不能把新值写入。
- 使用数组前必须先初始化它。
- 如果部分初始化数组,剩余会初始化为0.
多维数组
- float rain[5][12] //rain是一个内含5个元素的数组
- 初始化多维数组
const float rain[5][12]=
{
{4.3,1.1,3.2,4.3,1.5}
};
指针和数组
- 数组名是数组首元素的地址 dates == &dates[0] // true
- c语言的灵活
dates+2 == &dates[2];
*(dates+2) == dates[2];
函数、数组和指针
- 只有在函数原型或函数定义中,才可以用int ar[] 代替int* ar;
指针操作
- 赋值:可以把地址赋给指针。
- 解引用:*运算符给出指针指向地址上存储的值
- 取址: &运算符给出指针本身的地址。
- 支持递减递增指针
- 可以计算两个指针的差值
- 千万不要解引用未初始化的指针
- 比较:前提两个指针都指向相同类型的对象。
第十一章 字符串和字符串函数
const char * pt1 = "Somethings";
const char ar1[] = "Somethings";
pt1指针通过 *(pt1) == ‘\0’ 来判断是否到字符串结尾。
字符串输入
- gets()函数读取一行输入。输入的内容容易超过给定的大小,C99不建议使用。
- fgets()函数第2个参数指明了读入字符的最大数量,第3个参数指明要读入的文件。
- gets_s()函数与fgets()类型,但是只从标准输入中读取数据,所以不需要第3个参数。
字符串输出
- puts(),只需把字符串的地址作为参数传递给它,就能输出信息。遇到空字符时停止输出。
- fputs(),第2个参数指明要写入数据的文件。
- 与puts不同,fputs不会在输出的末尾添加换行符。
- printf()可以格式化不同的数据类型。
字符串函数
- strlen()函数统计字符串的长度。
- strcat()函数把第2个字符串的备份附加在第1个字符末尾。新的字符串作为第一个字符串。
- strncat()
strncat(bugs,addon,13)
- strcmp()比较字符串是否相等。while(strcmp(str1,str2)!=0)。相等是0,比较"A"和"B"返回-1,比较"B"和"A"返回1.
- strncmp()比较字符串中的字符,第3个参数可以指定比较的字符数。
- strcpy()拷贝整个字符串。第2个参数指向的字符串被拷贝至第一个参数指向的数组中。程序员确保足够空间容纳。
- strncpy()相对更安全,第3个参数指明可拷贝的最大字符数。
- sprintf() 声明在stdio.h
- sprintf() 把数据写入字符串中。
命令行参数
- int main(int argc,char **argv)
- char **argv 与 char *argv[] 等价。
字符串转数字
- atoi()函数把字母数字转换成整数,可以把"42regular"转换为42
- strtoul() 把字符串转换成unsigned long类型的值
- strtod() 把字符串转换成double类型的值。
第12章 存储类别、链接和内存管理
作用域
作用域描述程序中可访问标识符的区域。一个c变量的作用域可以是块作用域、函数作用域、函数原型作用域或文件作用域。
链接
c变量有3种链接属性:外部链接、内部链接或无链接。
存储期
c对象有4种存储期:
静态存储期、线程存储期、自动存储期、动态分配存储期。
寄存器变量
- register 可声明寄存器变量。但是只是一种请求,编译器做判断,可能不会如你所愿。
块作用域的静态变量
- 具有文件作用域的变量自动具有静态存储期。
- 计算机在多次函数调用之间会记录他们的值
- 以存储类别说明符static声明这种变量。
- 不能在函数的形参中使用static
外部链接的静态变量
- 为了指出该函数使用了外部变量,可以在函数中用关键字extern再次声明。
extern char coal;
如果省略掉extern关键字,相当于创建了一个自动变量。
存储类别和函数
- 一般函数声明都默认为extern
- static dobule beta(int,int)以static存储类别说明符创建的函数属于特定模块私有。
分配内存:malloc()和free()
- malloc()接受一个参数:所需的内存字节数。该函数会找到合适的空闲内存块,返回内存块的首字节地址。
double * ptd;
ptd = (double *) malloc(30 * sizeof(double));
以上代码为30个double类型的值请求内存空间,并设置ptd指向该位置。
- free() 释放malloc()申请的内存
- calloc()函数分配内存,返回指向void的指针。还有一个特性:块中的所有位都设置为0
- free()也可以释放calloc()分配的内存