C程序操作记录
一些问题的记录
1.遇到常量,记得用宏定义(#define),方便修改;
2.变量(常量)的命名不能取无意义的名字;
3.函数参数最好别用常用的一些临时变量,如i,j等;
4.函数声明应该放在最前面,函数内部不能声明函数;
5.打开文件 fopen中,要指定打开方式,如,“rt”表明十进制方式打开,“rb”表明二进制方式打开文件;
6.了解编码的基础知识;
7.\0和0区别:意义不一样,但是其值都为0。《c程序设计语言》P169:\0表示NULL
8.printf函数参数包含未知的转义字符序列(eg. \c),编译会有警告,执行的话则会打印反斜杠“\”后面的字符;
9.scanf()、getchar()、gets()的区别:
1)scanf():输入函数,声明在stdio.h头文件中,使用时候要包含stdio.h头文件。是格式输入函数,即是按照用户指定的格式从键盘上把数据输入到指定的变量当中。函数返回成功读入的数据项数(如scanf(“%d %d”, &a, &b);返回值为int型,若a,b的值被成功输入,则返回2,只有一个被成功,则返回1,都未成功则返回0,遇到错误返回EOF),读入数据遇到文件皆为则返回EOF。若scanf中%d之间是连着(“%d%d%d”)的,则在输入数据时,只能用空白字符(Space,Enter,Tab键)分隔。若是“%d,%d;%d”,则在输入时“2,3;4”才有效。%c只读一个字符。会跳过空白字符。
scanf的\n问题:“\n”在scanf中很特别,会过滤掉(忽略)所有的空白符(Space,Enter,Tab)输入,也就是说“scanf(“%d\n”, &i);printf(“%d\n”,i);”当输入一个数字,敲下回车后,程序还在阻塞着的,不会立即显示,要等到再接收一个非空白字符(空格,回车,制表)的输入scanf语句才会结束。但这时候注意,最后输入的非空白字符的东西不会被scanf读取,而是会留在输入流(缓存中)。
2) getchar():输入函数,从标准输入里读取下一个字符,相当于getc(stdin)。返回值为int型,为用户输入的字符的ASCII码或EOF。该函数声明在stdio.h头文件中,使用的时候要包含stdio.h头文件。**调用一次,只接收一个字符!**在键盘键入信息时候,并不是在键盘上敲一个字符,该字符就会立即送到计算机中,这些字符暂存在键盘的缓冲区中,只有按了Enter键才会把这些字符一起送入计算机中。然后按照顺序赋值给相应的变量。(只有Enter键和EOF可以结束输入)。获取一个字符。但是打印显示时候,可以指定打印格式如%c或%d等等。
3) Gets():
10.读取字符数入,慎用gets()函数,会有警告。一般有空格输入的话,采用getchar()接收。
11.if 语句的作用范围
If语句不加大括号“{}”限定其作用范围,默认只有if语句后面紧跟着的一条语句(带分号的语句)。如这里的第二个if后面只有“state = OUT;”在其作用范围内,而“putchar(‘\n’);”已经不受第二个if约束(这与最初的编码思路有出入)。
总结:if后跟多条语句(多个分号“;”)或者后面还有else if的情况,一定要用大括号限定if语句的作用范围(用大括号将多条语句组成一个程序块)。否则会影响程序运行逻辑,将近一下午时间都耗在这个问题了!
改正如下:
if (c == ’ ’ || c == ‘\t’ || c == ‘\n’){
if (state == IN){
state = OUT;
putchar(’\n’);
}
}
}
12.typedef
1)typedef:
重定义类型的标识符,解决用户自定义数据类型名称的需求,从而丰富数据类型包含的属性信息。
2)typedef语法描述:
typedef 类型名称 类型标识符;
typedef为系统保留字,“类型名称”为已知数据类型名称,包括基本数据类型和用户自定义数据类型,“类型标识符”为新的类型名称。例如:
typedef double length;
typedef unsigned int COUNT;
COUNT b; //b为unsigned int 型
3)typedef主要应用形式:
①为基本数据类型定义新的类型名称;
目的:丰富数据类型包含的属性信息、系统移植。如“typedef unsigned int COUNT; tpedef double AREAR;”。
②为自定义数据类型定(结构体、公用体和枚举类型)义简洁的类型名称;
目的:简化—如,typedef struct{……}Point;
③维数组定义简洁的名称;
C语言中可以将长度为10(n)的数组看作为一个新的数据类型,再利用typedef重新定义一个新的名称。如:
typedef int INT_ARRAY_10[10];
typedef int INT_ARRAY_20[20];
INT_ARRAY_10 a, b,c;
INT_ARRAY_20 d, e;
④为指针定义简洁的名称。
维数组定义简洁(新)的名称。如,
typedef char * STRING;
STRING csName = {“Jhon”};
为函数指针定义新的名称,如
typedef int (*MyFUN)(int a, int b);
定义一种MyFUN的类型,并定义这种类型为指向某种函数的指针,这种函数以两个int为参数并返回char类型。后面就可以像使用int,char一样使用MyFUN了。MyFUN代表指向函数的指针类型的新名称。例如:
typedef int (*MyFUN)(int a, int b);
int Max(int a, int b);
MyFUN pMyFUN;
pMyFUN = Max;
(*pMyFUN)(2, 3);
数组名、函数名都是指针(地址)。
14.const
//const,修饰限定指针变量:
① const int *p1;
② int const *p2;
③ int * const p3;
最后一种情况③,指针是只读的,也就是p3本身的值不能被修改;前两种情况,指针所指向的数据是只读的,也就是p1、p2本身的值可以修改(指向不同的数据的地址),但是他们指向的数据不能被修改。
④ const int * const p4;
⑤ int const * const p5;
这两种情况指针本身和他所指向的数据都是只读的。
总结:const离变量名近就是用来修饰指针变量的,离变量名远就是修饰指针指向的数据,如果远近都有const,则同时修饰指针和数据。
//const,函数形参、指针:
C语言单独定义const变量没有优势,因为完全可以用#define代替。通常用在函数形参中。如果形参是一个指针,为了防止在函数内部修改指针指向的数据,就可以用const来限定。
15.【标志位】《C程序设计语言》P15—练习1-12:以每行一个单词的形式打印其输入。
思路:每一个单词结束则换行;单词开始(非空白字符)则输出。
打印换行符的前提条件是:1)本次单词状态为“在单词中”;2)且单词中出现空白字符(空格、制表、回车)。
输出(下一个单词开始)条件:1)上一个单词结束,状态为“不在单词中”;2)且输出为非空白字符。
17.运算符优先级
eg. while ( (c = getchar( ) ) != EOF)
式中,(c = getchar())需要加上括号,因为赋值运算符“=”的优先级等于不等于运算符“!=”
18.打开core文件:gdb [可执行文件] [core文件]
20.遍历两个字符串:比较S1和S2两个字符串,若S1中包含任何S2中的字符,则删除。
实现方法:①for/for空循环;②for/while;③for/if(continue、break)
squeeze_N.c squeeze_New.c squeeze_3.c
21.制表符特性公式:nb = TABINC - (pos - 1)%TABINC
22.进制转换公式:
字符串转成十进制整型数:n = 10n + (s[i] -’0’)
十六进制转成十进制整型数:n = 16n + (s[i] - ‘a’)或’A’或 ‘0’
23.几条笔记
(1) | C语言scanf不能打印二进制 |
(2) | scanf不能输入’\t’,字符串处理时’\t’要分开处理,’\’ 和 ‘t’ |
(3) | switch语句的每一个case后都要加入break,defalut后也应该加break |
(4) | 字符串操作完成,要加上结束符’\0’ |
(5) | if for while seitch等后面跟多条语句时候最好加上大括号 |
(6) | 进制之间的转换,公式 |
(7) | 善于使用 ++ |
位运算符小记:<习题2-6~2-8>
~ 取反,即0变为1,1变为0
& 与(AND),一般通过屏蔽某些二进制位,从而来提取部分位。常使用0及~0
| 或(OR),一般用来设置某些二进制位,如某字符串的某些位替换,便可用|
^ 异或,不同为1,相同为0,一个数和0异或还是自身,所以常用~0进行,。如将一个数的某些二进制位取反,只需要将这个数和一个异或码进行异或即可。习题2-8
<< >> 左移右移,注意一下循环移位习题2-8
25.atof函数:
ascii to float:将ASCII码字符转换成浮点型(字符char 转成 浮点型float/double)
#include <stdlib.h>
double atof(const char *str)
功能:跳过空白符,直到遇到数字或正负号,若字符串不能被转换成double,返回0.0。
26.ASCII码、十进制、十六进制与二进制的关系
ASCII码:可见的字符,可以被打印出来的字符。为字符类型char
十进制:人类经常使用的数字格式
十六进制:
二进制:计算机存储的数据格式。<这个不会变,变的是解析数据的方式>
27.isdigit()函数
包含在#include <ctype.h>中
28.int _vnsprintf();
#include <stdarg.h>
int _vsnprintf(char *str, size_t size, const char *format, va_list ap);
char *str[out]: 把生成的格式化的字符串存在这里;
size_t size[in]: str可接受的最大字符数,防止数组越界-----非字节数组
const char *format[in]: 指定输出格式的字符串,决定了可变参数类型、个数、顺序
va_list: ap[in]: va_list类型变量
功能:将可变参数格式化输出到一个字符数组。
返回值:成功,返回保存的字符数组;失败,返回-1。