C和指针 读书笔记

第一章:快速开始

1.C语言中注释代码用/* 和*/来注释代码。但是由于/*和*/不能嵌套,故在需要对一大段代码注释的时候,内容代码不能含有注释/*,*/。但是可以采用宏命令来完成此功能。

#if  0

   /*需要注释的大段代码 */

#endif

2.EOF是一个整数值,故在一个一个接受字符判断是否结束时,用int变量来存放获得的字符。否则255对应的字符类型转换成int型后等于-1.

int ch;

while ((ch = getchar() )!=EOF  && ch!='\n')

第二章:基本概念

1.C语言从编译到执行的过程,合法标识符,转义序列,特别注意三字符序列的存在。

第三章:数据

1.C语言中四种基本数据类型:整型,浮点型,指针和聚合类型(struct,array).

2.使用typedef而不是#define来给类型命名别名。如下面列子:

#define ptr_to_char char *

ptr_to_char a, b;   // b is char

typedef char * ptr_char;

ptr_char a,b;       //  both a and b are pointers

3.尽量用const修饰变量:不仅程序逻辑清晰,而且代码中尝试修改变量都会报错。

4.static用于定义函数或全局变量时,会将对应的链接属性从external改为internal,存储类型和作用域不变。对应函数和变量只能在声明他们的源文件中访问;  static作用于代码内部变量声明时,会讲变量从局部变量改为静态变量。但是变量的链接属性和作用域不受影响。

第四章:语句

1.C语言中没有bool类型变量(见第三章第1条),用整型变量来代替(0代表false,1代表true)

2.C语言没有内置输入输出功能,I/O通过标准库函数进行实现。

3.goto唯一可以适合使用的场景是跳出多重循环。

第五章:操作符和表达式

1.注意逻辑移位与算术移位的区别.算术右移位时考虑数的正负号。

2.用移位操作对某个数的某一位操作:

value = value | 1<<bit_num;            //置1

value = value & ~(1<<bit_num);  //清零

value & 1<<bit_num;            //测试是否为1

第六章:指针

1.对一个NULL指针进行解引用是非法操作。故在对指针进行解引用操作时,要确保指针不是NULL.

2.对指针进行算术运行的前提是两个指针是指向同一个array,否则结果是undefined.

3.指针指向一个array时,指针可以跟array最后一位的下一位进行比较。但若用指针与array第一位的前一位进行比较,标准未定义即undefined。故要避免此种用法。

3.指针要记得初始化,不用时记得设为NULL.(remember...)

第七章:函数

1.函数进行参数传递时,都是采用传值的方式。(原先参数的一份拷贝)。在传递array参数时,不是讲整个参数传递,而是传递了array的起始地址。

2.尾递归可以比较容易的用迭代实现。

第八章:数组

1.除了优先级外,间接引用可以和下标引用互换。

2. message大小为6.

char * message = "hello";

3.二维数组的传递:

int matrix[3][10];
func2(matrix);

void  func2(int (*mat)[10]);
void  func2(int mat[][10]);

4.指针数组的理解:

int *ptr[10];

ptr是指向整型指针的指针,元素是指向整数的指针。

第九章:字符串,字符和字节

1.strlen的原型为:

size_t strlen(char const * string)

size_t是unsigned int 类型。故 if(strlen(x) >= strlen(y)) 与 if(strlen(x)-strlen(y) >=0) 不同,后者总是为true.

2.strncat函数一般会讲len个字符从src字符串加入到目标字符串,而且strncat总会在末尾加上一个NULL字符。

3.strncpy则总是复制n个字符,若原字符不足n个,则用NULL加到末尾。但是若n个字符最后一个不是NULL,则会出现最后的字符串是非NULL结尾的情形。故使用strncpy函数时,最好按如下方法:

strncpy(buffer, name, size);

buffer[size-1] = '\0';

4.为了提高程序的可移植性,减少对字符的直接操作。如判断一个字符是否是大写字符: if(ch >= 'A' && ch <= 'Z') 改为 if(isupper(ch))

5.对内存操作的几个函数:

// 若内存重叠,则结果undefined

void * memcpy(void *dst. void const * src, size_t length);

//与上一个函数类似,可以内存重叠

void *memmove(void *dst, void const *src, size_t lenth);

void *memcmp(void const *a, void const *b, size_t length);

void *memchr(void const *a, int ch, size_t length);

void *memset(void *a, int ch , size_t length);

第十章:结构和联合

1.Union 与Struct结构类似,只是Unino的所有成员引用的是内存中的相同地址。如果联合的各个成员具有不同的长度,联合的长度就是它最长成员的长度。

2.sizeof(struct X)包括任何由于端对其而浪费的内存。

3.free(NULL) is ok.

第十一章:动态内存分配

1.动态内存的分配与释放:

void *malloc(size_t size);

void free( void *pointer);

2.还有另外两个内存分配函数realloc和calloc:

void *calloc(size_t num_elements, size_t element_size);
void realloc(void *ptr, size_t new_size);

若ptr为NULL,则与malloc一样

第十二章:使用结构和指针

1.在对单链表进行操作时,主要对头结点和尾节点的考虑。

第十三章:高级指针话题

1.函数指针最常见的两个用途是转换表和作为参数传递给另一个函数

2.对函数指针执行间接访问之前必须把它初始化为指向一个函数:

int  (*pf)(int) = &f;

int ans;

ans = f(25);
ans = (*pf)(25);
ans = pf(25);

第十四章:

1.几个基本预处理符号:

(1)__FILE__         // 进行编译的源文件名;

(2)__LINE__        // 文件当前行的行号;

(3)__DATE__        // 文件被编译的日期;

(4)__TIME__        // 文件被编译的时间;

(5)__STDC__       //如果编译器遵循ANSI C,其值为1,否则未定义;

2.#define宏使用时存在很多潜在的危险,如:

   #define max(x,y)  (  (x>y) ? (x) : (y)  )

第十五章:

1.I/O函数以三种基本的形式处理数据:单个字符、文本行和二进制数据。

2.参考相应的手册。

第十六章:标准库函数

1.该部分比较复杂,书上也只是提及了部分的函数。如时间相关函数time,clock.随机数srand(),rand()。

2.fgets会在字符后加一个NULL.

char *fgets(char *buffer, int buffer_size, FILE * stream);

3.fputs可以输出一行或者一行的一部分。

3.gets未指定buffer的大小,故接收一行的多字符时会溢出。

char *gets(char *buffer)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值