C语言,11天扬帆起航!

  1. 云栖社区>
  2. 博客>
  3. 正文

C语言,11天扬帆起航!

科技小能手 2017-11-12 16:27:00 浏览645
展开阅读全文

算法的主要特征:

1.有穷性

2.确定性

3.可行性

4.零个或多个输入

5.一个或多个输出


注释格式:

//     单行注释

/**/   多行注释

VC++6.0快捷键:

F10:单步执行,不进入函数的内部。

F11:单步执行,进入函数的内部。

F5:执行到下一个断点。

Ctrl+F10:运行到光标处中断。

Shift+F5:停止调试。


C语言的数据类型:

基本数据类型:

整型:int

实型:float、double

字符型:char

构造数据类型:

数组:[]

结构体:struct

共用体:union

枚举:enum

指针数据类型:*

空类型:void


常见的转义字符:

'\0'           结束标志,这是八进制的表示方法。

'\n'           输出到屏幕和文本文件是回车或换行,如果输出到二进制文件仅仅是换行。

'\r'           回车,不换行。

'\t'           制表键,占用8个字符。

'\f'           换页。

'\b'           退格。

'\\'           反斜线。

'\''           单引号。

'\"'           双引号。

'\ddd'         1~3位ASCII码对应的字符。

'\xhh'         1~2十六进制的数组对应的字符。


使用const关键字定义常变量。



运算符的优先级:

1.    ()   []   .   ->       圆括号运算符  下标运算符  成员运算符

2.    ! ~ ++ -- + - (数据类型) * & sizeof   逻辑运算符 按位取反运算符 自增、自减运算符 正、负运算符  类型运算符 指针运算符 取地址运算符 求类型长度运算符

3.    *   /   %   乘法运算符  除法运算符  取模运算符

4.    +   -     加减运算符

5.    <<    >>    左移运算符   右移运算符

6.    <   <=   >  >=   关系运算符

7.    ==    !=    关系运算符

8.    &    按位与运算符

9.    ^    按位异或运算符

10.   |    按位或

11.   &&   逻辑与运算符

12.   ||   逻辑或运算符

13.   ?:   条件运算符

14.   =  +=  -=  *=  /=  %= >>=  <<= &=  ^=  |=   赋值及符合运算符

自动数据类型转换法则:

char、short---->int---->unsigned---->long---->double

float---------------------------------------->double


单字符输入输出函数:

putchar(int ch)

如果输出失败,就返回EOF。

int getchar()

接受过程中出现错误返回EOF。

getchar()是一个缓冲输入函数。在输入字符后必须按ENTER键才可以接受数据。

如果接受的是数字,也会当做字符处理。

空格、Tab键、Enter键等都会作为getchar()函数的能接受的有效字符。

如果输入多于一个字符,就只会接受一个字符,如果要接受一个字符串,要结合循环使用。


printf()格式输出函数:

printf(格式控制串,输出列表)

格式说明:

%标志字符 输出最小宽度 .精度 长度 格式字符

格式字符功能:

int:

d       以十进制形式输出带符号的整数,整数不输出符号。

o       以八进制形式输出无符号的整数,不输出前缀0。

x       以十六进制形式输出无符号整数,不输出前缀0x。

u       以十六进制形式输出无符号整数。

char:

c       输出一个字符

s       输出一个字符串

float:

f       以小数形式输出单双精度实数,默认小数位数是6位。

e       以指数的形式输出单双精度的实数。

g       以%f%e中较短的输出宽度输出单双精度实数。

其他:

%       输出百分号。

标志字符功能:

-       输出结果默认右对齐,如果实际位数少于定义的宽度,则左边的使用空格补齐,使用-左对齐的时候,右边填充的空格。

+       输出数据前面使用符号(正号或负号)

#       对c/s/d/u类无任何影响;对于o,在输出时加上前缀0x;对于e/g/f,当有结果存在小数点时i,才会加上小数点。

空格    输出数据为正数的时候前面有空格。

0       如果实际位数少于定义的宽度,就会左边用0补齐,但是与“-”一起使用的时候不起作用,此时使用空格填充。


scanf(格式控制串,地址列表)格式化输入函数:

格式说明:

%* 宽度 长度 格式字符

格式字符功能:

int:

d     输入十进制整数

o     输入八进制整数

x     输入十六进制整数

u     输入无符号十进制整数

char:

c     输入一个字符

s     输入一个字符串

float:

f或e  输入实型数(用小数形式或指数形式)

使用scanf()函数的问题:

1.虽然scanf()函数的本质是从键盘输入数据存放到变量锁对应的内存空间中,但是scanf()函数的地址列表中要求给出的是变量的首地址。

2.遇到当前的数据的输入认为是数据的结束:

1.遇到间隔符:空格、Tab、Enter

2.遇到宽度限制

3.遇到非法数据

常用的数学函数math.h:

double sqrt(double x):求平方根

int abs(int x):求整数绝对值

double fabs(double x):求实数绝对值

double pow(double x,double y):幂函数

常用字符函数ctype.h:

int tolower(int c):转换为小写字母

int toupper(int c):转换为大写字母

int isalpha(int c):判断是否为英文字符,A-Z返回为1,a-z返回为2,其他返回0。

常用工具函数:

time_t time(time_t *t):获取当前系统的日历时间如果参数为NULL,返回当前时间。time.h。

int rand():随机数函数,返回0-RAND_MAX之间的随机数。stdlib.h。

void srand(unsigned seed):提供随机数种子,常用系统时间最为随机种子。stdlib.h。

void exit(int status):结束当前程序,参数为1表示正常结束,参数为0表示异常结束。stdlib.h。

选择结构:

if(表达式){

语句;

}else{

语句;

}


if(表达式){

语句;

}


if(表达式){

语句;

}else if(表达式){

语句;

}else{

语句;

}


条件表达式:

表达式?表达式:表达式


switch(表达式){

case 常量表达式 :

语句序列;

break;

...

default:

语句序列;

}


循环结构:


while(表达式){

语句;

}


do{

语句;

}whlie(表达式);


for(循环变量初始化;循环控制条件;变量值改变){

语句;

}


break语句:

结束循环,执行下面的语句。

continue语句:

结束本次循环,执行下一次循环。

return语句:

跳出函数,结束程序。

main()也是函数。

数据类型的转换:

1.若参与运算量的类型不同,则先转换成统一类型,然后进行运算。

2.转换按照数据数据类型长度增加的方向进行,以保证精度不降低。

3.所有浮点数运算都是以双精度进行的,即使是单精度的表达式,也要转换成double类型进行运算。

4.char型和shaort型参与运算时,必须转换成int型。


强制数据类型转换:

(类型说明符)(表达式)


基本的算术运算符:

+        向右结合

- * /    向左结合


自增自减运算符:

++ --


逗号运算符:

间隔多个表达式。


C语言不允许动态定义数组的大小,也就是C语言的数组大小不依赖于运行中变量的值。

数组的初始化赋值是在编译阶段进行的,这样减少运行时间,提高了程序的运行效率。

C语言编译系统会为二维数组分配一片连续的空间,按照行优先原则存储数组中的各个元素值。

数组的初始化可以使用循环代替。


一维数组的定义:

存储类型 数据类型  数组名 [整型常量表达式]

一维数组的使用:

数组名[下标]

一维数组的初始化:

存储类型 类型说明符 数组名 [整型常量表达式] = {初始值列表};


二维数组的定义:

存储类型 数据类型 数组名 [一维数组常量表达式][二维数组整型常量表达式]

二维数组的初始化:

二维数组的初始化可以缺省第一位数组的长度。


使用数组求斐波那契数列(第N个数据和第N+1个数据的和等于第N+2个数据):

#include <stdio.h>

void main() {

int fibs[20] = { };

fibs[0] = 1;

fibs[1] = 1;

for (int i = 1; i < 20; i++) {

fibs[i + 1] = fibs[i - 1] + fibs[i];

}

for (int i = 0; i < 20; i++) {

printf("%d", fibs[i]);

printf("\t");

}

}

实现数组的冒泡排序:

#include <stdio.h>

void main() {

int arr[] = {12,45,7,24,57,58,4};

int i;

for(i = 0; i < 7; i++) {

printf("%d",arr[i]);

printf(" ");

}


int temp = 0;

int j;

for(j = 0; j < 6; j++) {

for(i = 0; 6 - i; i++) {

if(arr[i+1] > arr[i]) {

temp = arr[i];

arr[i] = arr[i+1];

arr[i+1] = temp;

}

}

}


printf("\n");

for(i = 0; i < 7; i++) {

printf("%d",arr[i]);

printf(" ");

}

}


字符串常量:

C语言中没有专门存储字符串的变量,如果要存储字符串变量需要使用字符数组。

字符数组的末尾使用'\0'表示结束。

可以使用字符串输入函数char *gets(char *str)来输入字符,使用回车符作为结束标志,并将回车符转换为'\0'存储到数组。

使用函数int puts( char *str )输出字符串。


char

字符常量使用单引号,字符串常量使用双引号。

字符常量只可以是单个字符,字符串常量可以是多个字符。

字符常量占一个内存空间。

字符串常量占的字符数加1.

增加的一个字节中存放字符"\0",表示字符串结束。


求字符串长度函数:unsigned int strlen(const char *str)函数.

字符串复制函数:char * strcpy(char *str1,const char *str2)包含结束标志复制str2到str1中。函数返回str1的地址。

字符串连接函数:char *strcat(char *str1,const char *str2),函数返回str1的地址。str1追加到尾部,str2不变。

字符串比较函数:int strcmp(const char *str1,const char *str2),如果str1小于str2返回-1,如果str1大于str2返回1,相同返回0。

注意:

1.strcmp()功能是比较两个字符串的大小而不是长短,按照ASCII值逐个进行比较。

2.只是比较字符串的大小,不会改变字符串。

3.比较两个不可以直接使用关系运算符。

一个源文件有N个函数组成。

一个源文件是一个编译单位。

在程序编译的时候是以源文件为单位进行编译的。

C从main函数开始执行。

函数从用户的角度进行分类:标准函数(库函数)、用户自定义函数。

函数从形式上分为:无参函数、有参函数。

在定义的函数中指定的形式参数,在未出现函数的调用时,并不会占用内存空间。

在发生函数的调用的时候,函数中的形式参数才会占用内存空间。

函数一旦调用完毕,形式参数占用的内存单元会被释放。

在C语言中,实参向形参的传递是值传递。

在内存中实参与形参分配到不同的内存单元。

在C语言中凡是不加数据类型说明的,编译器都会按照整型处理。

C++要求所有函数必须都指定函数类型。

如果函数的数据类型与return返回的数据类型不一致,将会进行数据类型转换。

函数的数据类型将会决定返回值的数据类型。

如果实参列表包括多个实参,对实参求值的顺序并不是确定的。

有的系统按照自左到右的顺序进行实参的传值。

有的系统按照自右到左的顺序进行实参的传值。

函数的声明和定义并不是一回事:

函数的定义是指对函数功能的确定,包括制定函数名,函数值类型,形参及其类型,函数体等等。

它是一个完整的、独立的函数单位。

函数的声明作用是把函数的名字,函数类型以及形参的类型、个数、顺序通知编译系统。

以便于在调用函数的时候按照对此进行对照检查。

变量的存储方式:

1.所谓静态存储方式是指在程序运行期间有系统分配固定的存储空间的方式。

2.动态存储方式是在程序运行期间根据需要进行动态分配存储空间的方式。


函数定义:

函数返回值类型  函数名(形参列表){

函数功能语句;

}


函数调用:

函数名(实参列表);

用户存储空间:

1.程序区

2.动态存储区

3.静态存储区


变量的存储类别:

在C语言中每一个变量和函数有两个属性:数据类型和数据的存储类别。

存储类别指的是数据在内存中存储方式。


存储方式分为两大类:

静态存储类和动态存储类。

自动的:auto

函数中局部变量,如果不专门声明为static存储类别,都是动态的分配存储空间的(栈),数据存储在动态存储区中。

函数中的形式参数和在函数中定义的变量(包括在复合语句中定义的变量),都属于此类变量。

在函数调用结束时,就会自动释放这些存储变量。

auto关键字可以省略。默认就是auto类型。

静态的:static

有时候希望函数中的局部变量的值在函数调用结束后不希望消失。

就是函数调用结束后保留这个值。

这就要指定问静态局部变量。

虽然静态局部变量在函数调用结束后仍然存在,但是其他函数不能引用它的。

寄存器的:register

为了执行效率,C语言允许将局部变量的值放在CPU中的寄存器中,需要时直接取出参数参加运算。

不需要再到内存中读取。

外部的:extern

外部变量就是全局变量,它的作用域是从变量的定义处开始的,到本程序文件的末尾。

在此作用域内,全局变量可以为程序中的各个函数锁引用。编译的时候外部变量分配在静态存储区。

有时候需要使用extern来声明外部变量的作用域。


有时候在程序设计中希望某些外部变量只限于被本文件引用,而不是被其他文件引用。

这时候可以定义外部变量是加一个static声明。


关于变量的声明和定义:

对于变量而言,声明与定义的关系稍微有点复杂,在声明部分出现的变量有两种情况:

1.需要建立存储空间的

2.不需要建立存储空间的


前者成为定义性声明,叫做定义。

广义的说,声明包括定义,但是所有的声明都是定义。

对于int a;既是声明也是定义,对于extern a;仅仅是声明。


一般为了叙述方便,把建立存储空间的声明称为定义,把不需要建立存储空间的声明叫做声明。

内存区的每一个字节都有编号,这就是地址。

如果在程序中定义了一个变量,在程序编译的时候,系统就会给这个变量分配内存单元。

在C语言中,对变量的访问有两种方式:直接访问,间接访问。

* :取值操作符

& :取址操作符


知道了变量的地址,就可以通过这个地址访问这个变量,因此又把变量的地址称为这个变量的指针。

C语言中可以定义一类特殊的变量,这个变量专门用来存放变量的地址,叫做指针变量。

不要把一个任何非地址类型的数据赋值给指针变量,否则编译器会当做一个地址来处理。


&和*的优先级是相同的,但是自右向左结合。


需要说明的:C语言中调用函数时虚实结合的方法都是采用"值传递"方式。

当用变量名作为函数参数时传递的是变量的值。

当用数组名作为函数参数时。

由于组名代表的是数组的首元素地址,因此传递的值是地址,所以要求形式参数是指针变量。


多维数组与指针:

用指针变量可以指向一维数组中的元素,也可以执行多维数组中的元素。


字符数组用来存放一个字符串,然后输出该字符串。


可以使用指针变量指向整型变量、字符串、数组、函数。

一个函数在编译的时候被分配给一个入口地址。这个函数的入口地址就成为函数的指针。


指针数组:一个数组中的元素都是指针类型数据,指针数组中的每一个元素都是一个指针变量。


指针数组作为main函数的形参:

void main()

int main()使用return语句返回0.


void指针:

void *p表示指针变量p不指向一个确定的类型数据,他仅仅是用来存放一个地址。

void指针它可以指向任何数据类型。

也就是说,可以用任何类型的指针直接给void指针赋值。

但是,如果需要将void指针的值赋值给其他类型指针,则需要进行强制类型转换。

无参数宏定义:

#define   标识符  字符串

凡是使用#开头的代码都是一条预处理命令。

define是宏定义命令。

标识符是定义的宏名。

字符串可以是常数、表达式、格式串。


在编译源程序的时候都需要先由预处理命令进行宏代换,然后再进行编译。

宏定义是用宏名表示一个字符串,在宏展开的时候又以字符串取代宏名。

这是一个简单的替换,字符串可以包含任何字符,可以是常数可以是表达式。

预处理程序对它不做任何检查。

如果有错误,只可以在编译的时候宏展开后的源程序时发现。

宏定义不是说明或者是语句。在行末不必加入分号。如果加上了分号就会连分号也会置换。

宏定义必须写在函数之外,其作用域是宏定义命令起到源程序结束。

如果过要终止其作用域可以使用#undef命令。

宏名在源程序中若用括号括起来,则预处理了程序不多其做宏替换。

宏定义允许嵌套,在宏定义的字符串中可以使用已经定义的宏名。在宏展开的时候由预处理程序层代换。

习惯上,宏名的定义使用大写字母。

可以使用宏定义表示数据类型。

宏定义只是简单的字符串替换,是在预处理的时候完成的。

而typeof是在编译的时候完后完成的。

typeof不会是简单的替换,而是对类型说明符重新命名,被命名的标识符具有类型定义说明的功能。

带参数宏定义:

C语言允许带参数宏定义,在宏定义中的参数叫做形式参数,在宏调用中的参数叫做实际参数。

对带参的宏,在调用中,不仅会宏展开,而且要用实参去代换形参。

带参宏定义的一般形式:

define 宏名(形参表) 字符串

带参宏定义中,宏名和形参列表之间不可以有空格出现。

在带参宏定义中,形式参数不分配内存单元,因此不需要做类型定义。

而调用中的实参有具体的值,要用它们去代换形参,因此必须要有类型说明。

这是与函数不同的情况。在函数的定义中,形式参数和实参是两个不同的量,各自有自己的作用域。

调用时需要把实参值赋值给形参,进行值传递。

在带参宏中,只是符号的代换,不存在值的传递。

宏定义中形参是标识符,而宏调用中的实参可以是表达式。

宏定义中,字符串内的形参通常是要用括号括起来的,避免出错。

宏定义也可以用来定义多个语句。


文件包含:

一个include指令只可以包含一个文件。

文件的包含允许嵌套。

包含命令中的文件名可以使用尖括号或双引号修饰。

使用尖括号,首先查找系统预定义的文件。

使用双引号,首先查找用户自定义的文件。

预处理程序提供了条件编译的功能。可以按照不同的条件去编译不同的程序部分,因而产生不同的目标代码文件。

这是对于程序的移植和调试很有用的。

1.控制条件为常量表达式的条件编译:

#if 常量表达式

程序段

#endif

或:

#if 常量表达式

程序段

#else

程序段

#endif

2.控制条件是定义标识符的条件编译:

#ifdef 标识符

程序段

#endif

或:

#ifdef 标识符

程序段

#else

程序段

#endif

或:

#endif   标识符

程序段

#else

程序段

#endif


结构体和共用体:

定义结构体:

struct 结构名{

成员列表

};


成员列表:

成员数据类型 成员名;

使用 结构体名.成员名; 调用。


定义并初始化结构体:

struct 结构体名{

成员数据类型 成员名;

}变量名1,变量名2={值初始化列表};


指向结构体类型的数据:

(*结构指针变量).成员名

或:

结构指针变量->成员名


动态存储分配:

C语言提供了一些内存管理函数,这些内存管理函数可以按需动态的分配内存空间。

可以把不在使用的空间回收,有效的利用内存资源。

分配内存空间函数:malloc、calloc

释放内存空间函数:free


void *malloc(unsigned size)函数:

其作用是在内存的动态存储区分配一个长度为size的连续空间。

此函数的返回值是一个指向分配域起始地址的指针。类型是void。

如果此函数没有成功的执行,则返回空指针NULL。


void *calloc(unsigned n,unsigned size)函数:

其作用是在内存的动态存储区中分配N个长度为size的连续空间。

函数返回一个指向分配域起始地址的指针。

如果分配不成功,返回NULL。

使用calloc函数可以为一维数组开辟动态存储空间,n为数组的元素,每个元素的长度问size。


void free(void *p)函数:

其作用是释放由调用calloc函数或malloc 函数返回的值。


链表:

链表是一种动态的进行存储分配的一种结构。

头指针:存放一个地址,改地址指向第一个元素。

结点:用户需要的实际数据和链表节点的指针。


动态链表:

是指在程序执行过程中从无到右的建立一个链表。

也就是一个一个的开辟结点和输入各个结点的数据,并建立起前后相互链接的关系。


使用typeof定义类型:


共用体:

使用几个不同变量工占用一段内存的结构成为共用体结构。

共用体的结构形式:

union 共用体名{

成员列表;

}变量列表;


结构体和共用体的比较:

1.结构体变量所占内存长度是各自成员占的内存长度之和。每个成员分别占有其自己的内存单元。

2.共用体变量所占的内存长度等于最长的成员的长度。


只有先定义了共用体变量才能引用它,而且不能引用共用体变量,而只能引用共用体变量中的成员。


共用体数据类型的特点:

同一个内存段可以用来存放几种不同的类型的成员,但是每一瞬间只能存放一种,而不是同时存放几种。

共用体变量中起作用的成员是最后一次存放的成员,存入一个新的成员后原有的成员就会消失作用。

共用体变量的地址和它的歌成员的地址都是同一个地址。

不能对共用体变量名赋值,也不能企图引用变量名来得到一个值,又不能在定义共用体变量是对它初始化。

不能把共用体变量作为函数参数,也不能是函数带回共用体变量,但是可以使用指向共用体变量的指针。

共用体类型可以出现在结构体类型定义中,也可以定义共用体数组。

结构体也可以出现在共用体的类型定义中,数组也可以作为共用体的成员。


枚举类型:

在枚举类型的定义中累出所有可能的取值。被说明的枚举类型的变量的取值不可以超出定义的范围。

枚举是一种基本的数据类型,而不是一种构造类型,因为它不能再分解为任何基本类型。

在枚举值列表中列出所有可用的值。这些值成为枚举元素。

文件操作:

文件:是指一组相关数据的有序集合。

这个数据集有一个名称,叫做文件名。

从用户的角度分为普通文件和设备文件。

文件驻留在外部介质上,在使用的时候才会调入内存。

操作系统是以文件为单位对数据进行管理的。


ASCII文件和二进制文件的比较:

ASCII文件便于对字符进行逐个处理,也便于输出字符。

但是ASCII文件占用存储空间比较多,而且要花费转换时间。

二进制文件可以节省外存空间和转换时间,但是一个字节并不对应一个字符,不能直接输出字符形式。

一般中间结果数据要暂时保存在外存上,以后需要输入内存的,常用二进制文件保存。

C语言对文件的处理方法:

缓冲文件系统:

系统自动的在内存区为每一个正在使用的文件开辟一个缓冲区。

用缓冲文件系统进行输入输出又叫做高级磁盘输入输出。

非缓冲文件系统:

系统不自动开辟确定大小的缓冲区,而是由程序为每个文件设定缓冲区。

用非文件系统进行的输入输出叫做低级输入输出系统。

在UNIX中,用缓冲文件系统来处理文本文件,用非缓冲文件系统来处理二进制文件。

ANSI C标准值采用缓冲文件系统来处理文本文件和二进制文件。

C语言中对文件的读写都是用库函数来实现的。

文件型指针变量:

FILE *fp;

fp是一个指向FILE类型结构体的指针变量。

使fp指向某一个文件的结构体变量,从而通过该结构体变量中的文件信息能够访问该文件。


文件的打开:

fopen(文件名,使用文件方式)函数。

fp = fopen(FileName,Operation);

文件的使用方式:

r   只读文本文件,文件必须存在。

w   只写文本文件,如果不存在就创建,存在就删除重新创建。

a   追加文本数据,文件必须存在。

rb  只读二进制文件

wb  只写二进制文件

ab  追加二进制数据

r+  读写文本文件,打开

w+  读写文本文件,新建

a+  读写文本文件,打开

rb+ 读写二进制文件,打开

wb+ 读写二进制文件,新建

ab+ 打开二进制文件

文件的关闭:

fclose(文件指针)函数。

使文件的指针变量不指向该文件,也就是文件指针变量与文件脱钩,此后不能通过该指针对原来与其联系的文件进行读写操作。

返回值:

关闭成功返回值为0,否则返回为EOF(-1)。


对文件的读或写是最常用的文件操作。

在C语言中提供了多种文件的读写操作。

字符读写函数:fgetc()和fputc()。

fputc(ch,fp)函数调用:

函数功能:将字符输出到fp所指向的文件中。

用写或读的方式打开一个已存在的文件时,将清除原有的文件内容。

写入字符从文件头开始。

如果需要保留文件内容,希望写入字符从文件末尾开始,必须以追加的方式打开文件。

被写入的文件不存在就会创建该文件。

每写入一个字符,文件内部位置指针想后移动一个字符。

fputs()函数有一个返回值,若果写入成功就返回写入的字符,否则返回一个EOF。

fgetc(ch,fp)函数调用:

在fgetc()函数的调用中,读取的文件必须是以读或读写的方式打开。

在文件内部有一个位置指针,用来指向文件的当前读写的字节。

在文件的打开的时候,该指针总是指向文件的第一个字节。

使用fgetc()函数后,该位置指针将会向后移动一个字节。

因此可以连续多次使用该函数读取多个字符。

应该注意文件指针和文件内部的位置指针不是一回事。

文件指针是指向整个文件的,必须在程序中定义说明,只要不重新赋值,文件指针的值是不变的。

文件内部的位置指针用以指示文件内部的当前读写位置。

每读写一次,该指针都会向后移动。

它不需要在程序中定义说明,而是由系统自动设置的。

EOF不是可输出字符,因此不能再屏幕上显示。

由于字符的ASCII码不可能出现-1.

因此EOF定义为-1是合适的。

当读入的字符值等于-1时,表示读入的已不是正常的字符而是文件结束字符。

ANSIC提供一个feof()函数来判断文件是否真的结束。

如果是文件结束,函数feof()的返回值是1,否则是0。

文件合成器:

字符串读写函数:fgets()和fputs()。

fgets(str,len,fp)函数:

从fp所指的文件中读出len-1个字符送入字符数组str中,并在最后加上一个\0。

fputs("字符串",fp)函数:

其意义是把字符串写入fp所指的文件之中。

输出成功返回0,输出失败返回EOF。


数据块读写函数:fread()和fwrite()。

fread(buffer,size,count ,fp)函数:

fwrite(buffer,size,count,fp)函数:

buffer是一个指针,对于fread()说,它是数据的存放起始地址;对于fwrite()来说,它是输出数据的起始地址。

size是要读写的字节数。

count是要读写多少个字节的数据项。

fp是文件型指针。

格式化读写函数:fscanf()和fprintf()。

fscanf(文件指针,格式字符串,输入列表)

fprintf(文件指针,格式字符串,输出列表)

从磁盘文件中按照格式输入输出字符。

顺序读写:

位置指针按字节位置顺序移动。

随机读写:

读写完成上一个字符(字节)后,并不一定要读写其后续的字符(字节),而可以读些文件中的任意位置上所需的字符。

fseek()函数一般用于二进制文件,作用是改变文件的位置指针。

函数的调用形式:

fseek(文件类型指针,位移量,起始点)

文件开头   SEEK_SET

文件当前位置   SEEK_CUR

文件末尾    SEEK_END

位移量:以起始点为基点,向前移动的字节数。

ftell()函数:

得到流式文件的当前位置,用相对于文件开头的位移量来表示。

返回当前的位置,出错返回-1。

ferror()函数:

出错检测。

调用形式:

feeror(fp)

返回0,表示未出错

返回非0,表示出错。

注意在调用一个输入输出函数后立即检查ferror()函数的值,否则信息会丢失。

在执行fopen()函数的时候,ferror()函数的初始值自动为0。

clearerr()函数:

调用形式:

clearerr(fp);

函数的作用:

是文件错误标识和文件结束标志置为0。

只要出现错误标志,就会一直保留,知道对同一文件调用clearerr()函数或rewind()函数,或任何其他一个输出输入函数。

以上函数包含在stdio.h文件中。

位运算:位运算是指按照二进制位进行的运算。

因为系统软件中,经常要处理二进制问题。

C语言提供位运算的功能,与其他高级语言相比,具有很大的优越性。


符号:

& 按位与

| 按位或

^ 按位异或

~ 取反

<< 左移

>> 右移


运算符只能是整型或者是字符型数据。


清零操作:

如果想对一个存储单元进行清零,即使全部二进制位为0,只要找一个二进制数,其中各个位符合以下条件:

原来的数中为1的位,新数中相应位为0.然后使二者进行& 运算即可可达到清零的目的。


左移一位相当于这个数乘2,但是只适用于左移时被溢出的高位不含1的情况。

对于无符号数,右移时左边高位移入0;

对于有符号数,如果原来符号位为0(这个数为正数),则左边也是移入0;如果是原来的位为1(这个数是负数)要取决于所用的计算机系统。

有的系统移入0,有的系统移入1。移入0叫做逻辑右移,也叫做简单右移;移入1叫做算术右移。


位段:

位段也叫作位域,是把一个字节中的二进制位划分为几个不同的区域,并说明每个区域的位数。

每个域有个域名,允许在程序中按照域名进行操作,这样就可以把几个不同的对象用一个字节的二进制位段来表示。

位段实际上是数据的一种压缩方式,每个位段是一种特殊形式的结构体成员。

信息的存储一般以字节为单位。实际上有时候一个信息不必用一个或多个字节。

在计算机用于过程控制、参数检测或数据通信领域时,控制信息往往只占用一个字节中的一个或几个二进制位。

常常在一个字节中放几个信息。

C语言允许在一个结构体中以位为单位来指定其成员所占用内存的长度。

这种以位为单位的成员叫做位段或位域。

利用位段能够用较少的位数存储数据。


位段的定义与引用:

位段成员的类型必须指定为unsigned或int类型。

如果某一位段要从另一个字开始存放,可用一下形式定义:

unsigned a:1;

unsigned b:2;

unsigned :0;

unsigned c:3;

本来a b c 应该连续存放在一个存储单元,由于用了长度为0的位段,其作用是使下一个位段从下一个存储单元开始存放。

因此,只将a b存储在一个存储单元中,c存放在下一个存储单元(存储单元可能是一个字节,也可能是两个字节,视编译系统不同而定)。


一个位段必须存储在同一个存储单元中,不能跨两个单元。如果第一个单元空间不能容纳下一个位段,则空间不用。

而从下一个单元起存放该位段。


可以定义无名位段。

位段的长度不可以大于存储单元的长度,也不能定义位段数组。

位段可以用整数格式符输出。

位段可以在数值表达式中引用,它会被系统自动的转换成整型数据。


位段的定义:

struct 位段名{位段列表};

位段列表的表示方式:

类型说明符  位段名 : 位段长度;

位段长度就是每个域所占的二进制位数。

一个位段必须存储在同一个存储单元,不可以跨两个单元,如果一个存储单元所剩余的空间不够存放另一个位段时,应该从下一个存储单元存放该位段。

可以有意使某位段从下一个单元开始。

位段的类型通常为征税或无符号整数类型。

在位段结构体定义中,也可以定义非位段成员。


位段的使用形式和结构体成员的使用相同:

位段变量名.位段名



 本文转自 棋帅小七 51CTO博客,原文链接:http://blog.51cto.com/xvjunjie/2058200


网友评论

登录后评论
0/500
评论
科技小能手
+ 关注