C语言笔记整理(1)

编程风格

 

1: #include ""对非标准库的头文件的引用.

#include < >对标准库的头文件的医用

使用预处理

#ifndef XXX

#define XXX

#endif

防止头文件被重复引用.

 

2:函数体内,逻辑密切相关的语句不加空行;函数定义和声明后加空行.

 

3:关键字const, virtual inline, case后要加空格,if, for, while后加空格;函数名后不加空格,紧跟(

 

4:赋值,比较,算术,逻辑,位域操作符如 =, +=, +, || 等二元运算符后加空格.

一元操作符如 !, ~, ++, --, &(地址运算符)前后不加空格.

 

5:长行拆分,代码行控制在7080个字符,操作符放在新行首.

 

6* 紧靠变量名.

 

7:标志符的长度应符合 “min_length && max_length”

 

8:变量名字使用名词或者形容词+名词

函数名字使用动词或者+名词

 

9:函数无参数或无返回值时,用void代替:void fun(void);

 

10:变量和参数用小写字母开头的单词组成:int drawMode;

常量用大写,用下划线分割单词:const int MAX_LENGTH = 100;

 

11:除加减乘除,其余预算符如果不确定都加括号确定优先级.

 

12:复合表达式不要写得太复杂:

if (a < b < c); //错误

if ((a < b) && (b < c)); //正确

 

13:对于main函数,最好使用int main(void)或者int main(int argc, char *argv[])

 

14:不可将浮点数用 ==, !=, 与任何数字比较,可以这样使用:

float x;

if ((x >= 0.3) && (x <= 0.3));

0.0比较时:if ((x >= EPSION) && (x <= EPSION));

指针变量与NULL比较,不要与0比较.

 

15switch语句,不要忘了break,否则导致多个分支重叠,最好加上default处理.

 

16:用#define定义宏常量,C++中使用const

 

17:即使if, while, for后面只跟一句,也用{ }括起来.

 

18:函数中,如果参数为指针类型且只做输入作用,应用const修饰,防止改写.

 

数据和C

 

printf: x,o,l,u可以结合使用,printf中值是由右向左,先计算最右边的值.但是只是在某些系统中,所以最好不要下列这样:

int a = 1;

printf("%d %d", a, ++a); // 2 2

 

%x 16进制

%#x 带前缀0x的十六进制

%#X 带前缀0X的十六进制

%o 八进制

%#o 带前缀o八进制

%#O 带前缀O的八进制

%ld long int

%p 指针存储的地址

%z size_t(sizeof返回类型)

%f float,double //C自动将float转换为double处理

%u unsigned int //不可使用%d,会有溢出

%hd short int //short会转换成int, int类型计算机处理快速

%+-a.bf 打印出字段宽为a(如果小于原始值字宽,则为原始值字宽),精度为b,+=>带加号(如果打印的数为负数,则带减号), - =>左对齐,字段从左侧开始

double a = -123.456;

printf("*%+-10.2f*", a) // *-123.46    * 注意,会四舍五入.

 

转义字符:\八进制ASCII  \x十六进制ASCII 可以表示字符

 

float: 32位,有效小数6, 后缀为f, float f = 3.14f;

double: 64位,有效小数10位,C语言默认浮点常量为double

long double: 64位,有效小数10, 后缀为l

 

fflush() //刷新缓冲区

 

字符串和格式化输入/输出

 

完全缓冲(fully buffered)I/O:缓冲区满时才清空,一般实在文件输入中,缓冲区大小取决于系统,一般为512b4096b

行缓冲(line buffered)I/O:遇到换行符才清空缓冲区,键盘输入是标准的行缓冲.

scanf:

int x;

scanf(“%d”, &x);

 

double a ;

scanf("%lf", &a);

 

对于字符%c

char c;

scantf("%c", &c); //读取第一个字符

scanf(" %c", &c); //读取第一个非空白字符

 

char buf[32] = {0};

scanf("%s", buf); //末尾自动添加\0,小心溢出喔.

 

string s;

scanf("%s", &s); //注意要加&

string s2;

scanf("%s,%s", &s, &s2); //中间如果以,分隔,则输入两个字符串也要以,分隔,如果以空格分隔,输入字串也要以空格分隔.

 

除字符外,其余跳过空白字符,一直到非所取的类型,字符串到换行和空白为止.读取错误时返回-1,成功时返回读入的项目个数.没有读取任何值(比如期望一个数字却键入字符,注意:此时输入的值仍然在缓冲区中并未清掉,下次还会读到,scanf将换行符也留在输入队列中)返回0

long num;

int status = 0;

while(status == 0)

{

         status = scanf("%ld", &num);

}//第一次输入a之后,无论之后是否输入数字,都跳不出循环,因为scanf永远得到a

 

int n;

char c;

while ((c = getchar()) != '\n')

{

         scanf("%d", &n);

         while ((c = getchar()) != '\n') //scanf输入的换行符和空格等

         {

                   continue;

         }

         printf("Enter a newline to quit");

}

 

printf*修饰符

int width = 2;

double number = 123.456;

printf("%*.*f", width, width, number); //123.46

 

scanf*修饰符

int n;

scanf("%*d  %*d  %d", &n); //输入1 2 3,n3,跳过前两个输入. 

 

右值类型;

short a = 1;

a+=1; //编译OK,在+=中,靠左值,1转换为short型.

a = a+1; //编译不能通过,因为类型不同.其实在VS2005里可以编译通过.

 

运算符,表达式,语句,跳转,循环

 

ifwhile, for括号中可以有表达式,用逗号隔开,以最右边表达式为准.

int n = 2;

if (++n, n != 2 )

{

         ; //跳入,while

}

while (++n, n = 1)

{

         ; //跳入, n = 1的左值为准

}

int n = 1;

for ( ; ; )

{

} //跳不出去啦,如果中间为空被认为是真.Java比较简单.for (:){ }

 

break跳出最内圈循环,else和最近的if配对,continue只跳出单次循环,switch()只能是int型.

 

函数

 

只要注意:被调函数使用的形参是从调用函数中复制而来的临时变量,无论对参数做什么动作,调用函数的原始值不会有影响(当然,除了引用).对于指针,虽然指针地址不会有影响,但是指向的内容可能会有影响喔.数组是已指针形式传入的.

旧式函数声明:int max();

定义int max(int n)

{

} //可以编译过,但是编译器无法检查调用max时是否正确.

不过有趣的是,函数可以这样定义:

int max(n, m)

int n, m;

{

} //我在VS2005中已经无法使用了.

 

不确定参数函数:

int printf(char *, …);

数组和指针

 

数组在函数外会默认初始化为0,但是在函数内不会初始化,int等基本类型同.

如果初始化部分数组,则剩余元素默认初始化为0

int arr[6] = {[5] = 1}; //C99特性,我在我的VS2005中无法编译.

指针可以使用++,--,而数组不可,可+1

const指针地址不可赋值给非const指针,防止修改.

int a = 1;

int* const p = &a;

int b = 2;

p = &b; //无法编译,pconst

int a = 1;

const int *p = &a; //或者int const *p = &a;

int b = 2;

p = &b; //可以编译

*p = 1; //无法编译,指向const int

 

变长数组(C99特性)

int func(int arr[][4], int rows) //如果传入的是指向数组的指针,最好加入数组大小的参数,或者参数为pfirst, pend

{

}

int main(int argc, _TCHAR* argv[])

{

int array[5][4] = {0};

func(array, 5);

         return 0;

}

 

C99标准引入变长数组:

int func(int rows, int cols, int arr[rows][cols]) //rows,cols的声明必须早于arr

{

}

int main(int argc, _TCHAR* argv[])

{

         int row = 3;

         int column = 2;

         int array[r][c]; //必须在函数内部或作为函数参量声明,且声明时不可初始化

         func(row, column, array);

         return 0;

}

 

void func(char buf[])

{

         int i = sizeof(buf); //4,为指针buf的大小

}

int main(int argc, _TCHAR* argv[])

{

         char buf[64] = {0};

         int i = sizeof(buf); //64

         func(buf);

         return 0;

}

 

复合文字(C99特性):

没有名字的变量:

int *p;

p = (int [2]) {1, 2);

原文地址:https://www.cnblogs.com/zengyou/p/2195569.html