1,数据类型:
1)基本类型:整型(int,short,long, unsignd int ,unsigned short,unsigned long ),实型(单精度float,双精度double,长双精度long double),字符型,枚举类型
2)构造类型:数组类型,结构类型(struct),共用类型(union)
3)指针类型
4)空类型
2,注意:以0开头的是八进制数据,如023(转化成10进制是19),以0x开头的是16进制数据,0x23(相当于10进制的35)
3,C语言中,不同种类的整型数据可以进行算术运算:
int a,b,c,d;
unsigned u;
a=12;b=-24;u=10;
c=a+u;d=b+u;
printf("a+u=%d,b+u=%d ",c,d); /*输出结果为 a+u=22,b+u=-14*/
4,int 4字节 unsigned int 4字节 float 4字节
short 2字节 unsigned short 2字节 double 8字节
long 4字节 unsigned long 4字节 long double 16字节
5,C语言中的类型转换:
数据由低级向高级转换,(char,short)->int ->unsigned->double,float->double
Java语言中的类型转换,只能是高级向低级转换,如double->int,
6,类型转换的格式:(类型名)(表达式)
(float)5/2 /*先将5转换为实型,再除以2*/
(float)(5/2) /*将5整除2的结果转换成实型*/
7,字符数据的输入和输出:(一次只能输入或输出一个字符)
putchar():从屏幕输出字符
getchar();从设备输入字符
8,C语言输出格式:(包括格式说明和要输出的字符)
printf("%d ", radius); /* 是换行符*/
printf("radius=%d ",radius);
printf("a=%d b=%d",a,b); /* 是制表符*/
9,格式字符:
1,%d:以十进制整数形式输出数据
1)%d:以整型数据的实际宽度输出
2)%md:m是正整数,指定输出数据所占的宽度,如果位数小于m,则右对齐,
3)%-md:m是正整数,如果位数小于m,则左对齐,
4)%ld:输出长整型数据
2,%c:用来输出字符,
3,%s:用来输出字符串
1)%ms:输出的字符串占m列,若字符串本身长度小于m,则右对齐,否则正常输出
2)%-ms:同上,,若串长小于m,则左对齐
3)%m.ns:输出占m列,但只取左端n个字符,这n个字符输出在m列的右侧
4)%-m.ns:同上,,这n个字符输出在m列的左侧
4,%f:用来输出实数
1)%f:只输出6位小数,整数部分全部输出
2)%m.nf:数据共占m列,其中n位小数,右对齐,左补空格
3)%-m.nf:同上,只是左对齐,右补空格
5,%e:以指数形式输出实数,不常见
10,输入函数scanf("%d",&a): /*注意地址符*/
11,break和continue:
break : 终止循环,不再执行其宇部分
continue:终止当前循环,继续下一层循环,(当不满足xxxx条件时利用continue语句,但是语句中要写当满足条件时执行 continue,否则执行目的语句)
当是循环嵌套时,break和continue都只影响内层循环,不对外层循环影响
12,冒泡排序法:
原理:先将相邻的元素进行比较交换,将最小的数排到最前面,然后再排其他元素,
#include "stdio.h";
main(){
int a[10];
int i,j,temp;
printf("Input 10 numbers:");
for(i=0;i<10;i++){
scanf("%d",&a[i]);
}
for(i=0;i<9;i++){
for(j=9;j>i;j--){
if(a[j]>a[j-1]){
temp=a[j];
a[j]=a[j-1];
a[j-1]=temp;
}
}
}
}
13,C语言定义二维数组时:
行下标可以省略,但列下标不能省略
14,矩阵的下标是从零开始计数的,所以二维数组中,要找一个元素a[i][j]的位置,应该是i+1行,j+1列
15,字符数组:
一维字符数组用于处理一个字符串,二维字符数组用于处理多个字符串;
一维字符数组的定义:char 数组名[常量表达式];
二维字符数组定义:char 数组名[常量表达式1][常量表达式2];
char a[5]={'h','e','l','l','o'}; char a[6]={"hello"}; /*字符串末尾有结束标志 */
16,scanf()函数中的输入项是字符数组名的时候,不需要加&,如char str[13]; scanf(%s,str); /*而不是&str*/
17,字符串输入输出函数:gets(str)和puts(str);
用法类似于scanf()和printf();
char s[100];
int i,j,n=0;
printf("Input the sentence:");
gets(s);
gets();:从终端输入字符串(字符串可以包括空格),直到遇到回车符为止,
puts();:从数组指定的位置开始,依次输出字符,直到遇到第一个 为止;
18,利用数组元素作为函数参数,实现统计字符串中字母的个数:
#include "stdio.h"
int isalp(char c){
if(c<'z'&&c>'a' || c>'A' && c<'Z')
return 1;
else return 0;
}
main(){
int i,num=0;
char str[255];
printf("Input a string: ");
gets(str);
for(i=0;str[i]!=' ';i++)
if(isalp(str[i]))num++;
puts(str);
printf("num=%d ",num);
}
但要注意数组做实参时,数组类型要和函数的形参类型相同;
数组做函数参数有两种形式:一种是数组元素作为实参,另一种是数组名作为实参;
利用数组名作为实参:
#include "stdio.h";
float aver(float a[]){
int i;
float av,s=a[0];
for(i=0;i<a.length;i++){
s+=a[i];
}
av=s/a.length;
return av;
}
main(){
float sco[5],av;
int i;
printf(" input 5 scores: ");
for(i=0;i<5;i++)
scanf("%d",&sco[i]);
av=aver(sco);
printf("average score is %5.2f ",av);
}
注意:将数组名作为函数参数时,在调用函数和被调用函数中分别定义数组且数据类型要一致,否则易出错;
19,静态变量和自动变量(正常声明的变量)
静态变量声明格式:static 数据类型 变量;
自动变量声明格式:[auto] 数据类型 变量;
注意:静态变量:只初始化一次,自动变量:每次调用都初始化
void f(){
int a=;
static int b=0;
printf("a=%d,b=%d ",a,b);
++a;
++b;
}
main(){
int i;
for(i=0;i<4;i++) f();
} /* 运行结果是:a=0,b=0 a=0,b=1 a=0,b=2 a=0,b=3*/
20,寄存器变量:
一般情况下,变量都是存在内存中的,但是为了提高效率,C语言允许将局部变量存到寄存器中,该变量就成为寄存器变量。
register 数据类型 变量;
注意:只有局部变量可以存到寄存器中
21,编译预处理命令:以#开头的命令
C语言主要包括3种编译预处理命令:
宏定义,文件包含,条件编译
22,宏定义:分为无参宏定义和有参宏定义
无参的:#define 宏名 字符串
有参的:#define 宏名(形参表) 字符串
宏名一般用大写字母表示;宏定义语句末尾不加分号!!!
宏名的有效范围只在本文件有效。
定义有参宏时,宏名与左圆括号间不能有空格。
23,文件包含:诸如 #include "stdio.h"
24,条件编译:
1)#ifdef 标识符
程序段
#endif
表示如果标识符已经被定义过,则程序段参加编译,否则程序段不参加编译。
程序段内可包含任意条语句,不需要花括号,但#ifdef和#endif一定要配合使用。
2)#ifndef
程序段
#endif
表示如果标识符没有被定义过,则程序段参加编译,否则不参加编译。
3)#if #endif同理
4)#undef 标识符 :将已经定义过的标识符变为未定义的.
25,指针:
指针就是地址,一个变量的地址就是该变量的指针,通过变量的指针能够找到该变量。
指针变量是存储其他变量地址的变量。指针与指针变量的区别就是变量值和变量的区别。
指针变量的定义:数据类型 *指针变量名
26,指针运算符:
1)取地址运算符&:格式:&标识符
&是单目运算符,结合性从右至左,它给出运算对象的地址,利用取地址运算符可以把一个变量的地址赋给指针变量
int a,*pa; /*定义变量a和指针变量pa,且pa指向的数据类型为整型*/
pa= &a; /*把变量a的地址赋给指针变量pa,指针变量pa就指向了a*/
2)间接访问运算符*: 格式:*地址
*也是单目运算符,结合性从右至左,当它用作指针时,用来间接访问所指的对象,即用来访问指定地址的数据。
int a=2,b,*p;
p=&a; /* p指向a */
b=*p; /*把p所指向变量a的值赋给b*/
注意:*运算符若出现在变量定义中,就说明其后的变量为指针变量,若出现在非变量定义的语句中,*运算符是间接访问指针变量所指向的对象。
27,这两种定义并初始化指针变量的效果相同:
方式一:int *p; p=&a;
方式二:int *p=&a;
28,指针变量作为函数参数:指针变量既可以做形参,也可以做实参
void exchange(int *p1,int *p2){
int temp;
temp=*p1;
p1=p2;
p2=temp;
}
main(){
int num1,num2;
int *num1_p=&num1,*num2_p=&num2;
scanf("%d%d",num1_p,num2_p);
printf("num1=%d,num2=%d",num1,num2);
if(*num1_p > *num2_p) /*如果num1>num2*/
exchange(num1_p,num2_p); /*指针变量作实参,调用exchange()函数*/
printf("min=%d,max=%d ",num1,num2);
}
30,使用变量指针作为实参:
void exchange(int *p1,int *p2,int *p3){
int temp;
temp=*p1;*p1=*p2;*p2=temp;
}
main(){
int num1,num2,num3;
scanf("%d%d%d",&num1,&num2,&num3);
if(num1<num2) exchange(&num1,&num2); /变量地址作为实参*/
if(num1<num3) exchange(&num1,&num3);
if(num2<num3) exchange(&num2,&num3);
printf("%d,%d,%d ",num1,num2,num3);
}
31,数组的指针和指向数组的指针变量:
数组的指针变量:定义一个指针变量,使他指向一个数组。
int array[10],*pointer=array; 或者
int array[10],*pointer=&array[0]; 或者
int array[10],*pointer; pointer=array;
如果有int array[10],*pointer=array; 则:pointer+i 和 array+i 都是数组元素array[i]的地址;*(pointer+i) 和 *(array+i) 就是数组元素array[i];
指向数组的指针变量也可看作是数组名,可按下标法来使用。如:pointer[i] 等价于*(pointer+i);
pointer+1:指向数组的下一个元素;0
32,对指向数组的指针变量进行算术运算和关系运算:
1,算术运算:只有px+n / px-n ,px++/++px,px--/--px,px-py;
2,关系运算:px<py,px==py,px>py;
指针的关系运算表示两个指针所指地址之间位置的前后关系:前者为小,后者为大,
33,结构体:
结构体类型定义格式:
struct 结构体类型名{ /*struct是结构体类型关键字*/
数据类型 数据项1;
数据类型 数据项2;...............
}; /*此行分号不能少*/
结构体的命名规则与变量名相同,成员的数据类型可以是基本数据类型;
注意:
结构体中的数据项可以逐个,逐行定义,也可以合并成一行定义。若数据类型相同,则可合并定义。
结构体中的数据项可以是基本数据类型,也可以是另一个已经定义完的结构体类型。
34,结构体类型变量定义:
1)间接定义法
struct 结构体类型名
{
};
struct 结构体类型名 结构体变量表;
例:struct std_info
{
char no[7];
char name[9];
char sex[3];
struct date birthday;
};
struct std_info student1,student2,student3;
2)直接定义法:在定义结构体类型的同时定义结构体变量
struct 结构体类型名
{............
}结构体变量表;
例:struct std_info
{...........
}student1,student2,student3;
3)一次性定义:吸纳定义无名结构体类型,再定义结构体类型变量
struct
{...........
}student1,student2,student3;
35,结构体变量的引用:
结构体变量表名.成员名
36,结构体变量的初始化:
结构体变量={初值表};
例:struct student
{
int num;
char name[20];
float score;
}st={1000,"张三", 98};
36,结构体数组:
定义:如果数组的每个元素都是结构体类型数据,均包含结构体类型的所有成员,则该数组称为结构体数组。与普通数组一样,结构体数组也可在定义时进行初始化。
结构体数组初始化格式:
结构体数组[n] = { {初值表1} , {初值表2 } , {初值表3}};
例:
struct student
{ int num;
char name[20];
float score;
}st[3]={ {100,"张三",89} , {102,"李斯",90} , {105,"王五",89} };
就是在结构体的后边加了一个数组。
38,指向结构体类型数据的指针:
1.指向结构体变量的指针:
结构体变量的指针:就是结构体变量在内存中的起始地址;通过指向结构体变量的指针即可访问结构体变量的成员。
pointer-->成员 或者 (*pointer).成员 /*括号不能省*/
一般来说,以下三种形式等价:
结构体变量名.成员 pointer->成员 (*pointer).成员
例:struct student
{ int num;
char name[20];
float score;
}st = { 1102, "张三" 89} , *p=&st; /*注意此处声明指针变量时,因为st是普通变量,所以前边要加地址符&*/
printf("%6d", p->num);
printf("%s",p->name);
printf("%.0f",p->score); /*运行结果是 1102张三 89*/
2,指向结构体数组的指针:
struct student
{ int num;
char name[20];
flota score;
}st[3]= { { 1102,"张三", 89}, { 1105,"李斯", 89}, { 1107,"王五", 99}} ,*p=st; /*注意此处因为st是数组,所以不用加&*/
int i=0;
for(i=0;i<3;i++;p++) /*p++表示指向下一个*/
{ printf("%6d",p->num);
printf("%s",p->name);
printf("%.0f",p->score);
}
40,链表:是一种能实现动态存储分配的数据结构。是用指针将各个结点连接在一起。
1)头指针变量指向链表的首地址
2)其他每个借点由2个域组成:
指针域:指向后继结点的指针,存放后继结点的地址。
数据域:存储结点本身的数据信息。
3)尾结点的指针位置为"NULL",作为链表结束的标志。
链表中各元素在内存中,可以不连续存放。因此要访问链表中的一个元素,必须要知道其上一个元素,由上一个元素提供地址才能访问。所以要不知道一个链表的头结点的地址,就不能访问该链表。
42,链表分为:动态链表和静态链表
1)静态链表:链表结点在程序中定义,不是临时开辟,这种方法生成的链表就是静态链表
例:建立一个简单链表,它由3个学生数据(学号和成绩)的结点组成,然后输出各个结点的数据。
#include "stdio.h"
struct node
{ int num;
float socre;
struct node *next; /*指向struct node类型的指针变量*/
}
main(){
struct node a,b,c, *head, *p;
a.num=100;
a.score = 95.9;
b.num=102;
b.score = 86.5;
c.num=106;
c.score = 92.5;
head = &a; /*头指针head存放首结点a的地址*/
a.next= &b;
b.next=&c;
c.next=NULL;
p=head;
do{
printf("学号:%d 成绩:%5.2f ",p->num,p->score);
p=p->next;
}while(p!=NULL);
}
char 类型:占内存单元1个字节
2,动态链表:
1)为建立动态链表,有一些内存管理函数,可以按需要动态分配内存空间,也可以把不再使用的空间回收待用。
常用的内存管理函数有3个:分配内存空间函数malloc(),分配内存空间函数calloc(),释放内存空间函数free();
调用形式:(类型说明符*)malloc(size)
功能:在内存动态存储区内分配一块长度为size字节的连续区域。函数的返回值为该区域的首地址。
"类型说明符"表示该区域用于存储何种数据类型。"(类型说明符*)"表示把返回值强制转换为该类型指针。"size"是无符号数。
例:pc=(char*)malloc(sizeof(char)); 表示分配一个字节的内存空间,并强制转成char类型,函数返回值为指向该字节的指针,
把该指针赋予指针变量pc。
2)分配内存空间函数calloc():
调用形式:(类型说明符*)calloc(n,size);
功能:在内存动态存储区内分配 n块长度为size字节的连续区域。函数返回值为该区域的首地址。
说明:(类型说明符*)用于强制转换,calloc()和malloc()函数的区别仅在于一次可以分配n块区域。
例:ps=(struct stu*)calloc(2,sizeof(struct stu)); 表示按stu的长度在内存中分配2块连续的区域,强制转换为stu类型,并把首地址赋予指针变量ps
3)释放内存空间函数free():
调用格式:free(void *ptr);
功能:释放 ptr所指向的内存空间,ptr是任意类型的指针变量,它指向被释放区域的首地址。被释放区是由malloc()或calloc()函数所分配的区域
44,共用体类型:
union 共用体类型名
1,间接定义 :先定义类型,再定义变量
union data
{ int i;
char ch;
float f;
};
union u1,u2,u3;
2,直接定义-定义类型的同时定义变量
union [data]
{ int i;
char ch;
float f;
}u1,u2,u3;
共用体变量占用的内存空间,等于最长成员的长度,而不是各成员长度之和。如上,u1,u2,u3占用的内存空间为4字节,而不是2+1+4=7字节。
C语言各类型占内存的字节数:
char 1字节
int 2字节
short 2字节
long 4字节
float 4字节
double 8字节
44,枚举类型:enum
enum 枚举类型名 {取值表};
enum weekdays{Sun ,Mon, Tue, Wed , Thu , Fri , Sat};
枚举类型变量的定义与结构体类似:
enum weekdays{ Sun , Mon ,Tue , Wed , Thu , Fri , Sat} workday;
注意:枚举类型仅用于取值有限的数据。
45,文件:
分类:
根据文件内容分为:程序文件和数据文件
根据存储形式分为:ASCII码文件和二进制文件
根据文件组织形式分为:顺序存取文件和随机存取文件
46,文件的打开---fopen()函数:
FILE *fopen("文件名","操作方式");
1)文件名如果是使用字符数组或字符指针,则不时用引号;
2)操作方式包括:读(r/rb),写(w/wb),读写(r+/rb+),写读(w+/wb+,即先写再读),追加读写方式(a+/ab+);
其中 不带b的是文本文件的操作方式,带b的是二进制文件的操作方式,
fopen()功能:返回一个指向文件的指针;
如果不能实现打开一个文件的操作,则会返回一个空指针NULL;
fputc(ch ,fp); //将字符存储到文件中;
47,文件的关闭--fclose()函数:
fclose(文件指针); /*fclose(fp)*/
功能:关闭文件指针指向的文件。如果正常关闭了文件,则函数返回值为0,否则,返回值为非0;
48,读写字符:
1,写字符:fputc()函数
调用格式:fputc(字符数据,文件指针);
功能:将 "字符数据"输出到 "文件指针"所指向的文件中。如果输出成功,则函数返回值就是输出的字符数据,否则返回一个符号常量EOF(该值在头文件stdio.h中被定义为-1);
2,读字符:fgetc()函数
调用格式:fgetc(文件指针)
功能:从"文件指针"所指向的文件中读入一个字符并将其作为返回值。如果在读字符时遇到文件结束符,函数返回一个文件结束标志EOF(即-1);
例:
ch=fgetc(fp); //从文件指针fp所指向的文件中读一个字符赋给ch
50,读写字符串:
1,写字符串----fputs()函数
调用格式:fputs(字符串,文件指针);
参数说明:"字符串"可以是一个字符串常量或字符数组。
功能:向指定文件输出一个字符串。如果输出成功,则函数返回值为0,否则为EOF(-1).
2,读字符串----fgets()函数
调用格式:char *fgets(字符指针,串长度,文件指针);
参数说明:“字符指针”是读入字符串存放的位置,"串长度"是指一次从源文件读出字符的个数,如果串长度为n,那么从源文件独处的字符数是n-1,因为要包括字符串结束符' ';
功能:从指定文件中读入一个字符串,存入'字符指针'中,并在尾端自动加一个结束标志' ',同时,将读写位置指针向前移动字符串长度个字节。如果在读入规定长度之前遇到EOF或换行符,读入即结束。
exit():关闭打开的文件,结束程序运行。
51,读写数据块:
1,写数据块:fwrite()函数:
调用格式:fwrite(void *buffer , int size ,int count ,FILE *fp);
参数说明:buffer是一个指针,是输出数据的起始地址,size是要输出的字节数,count是要进行输出的size字节的次数,fp是要写入的文件指针。
功能:从buffer开始,一次读出size个字节,重复count次,并将输出的数据放到fp所指向的文件中。
2,读数据块:fread()函数:
调用格式:fread(void *buffer, int size ,int count , FILE *fp);
参数说明:buffer是一个指针,是读入数据的起始地址,size是要读入的字节数,count是要进行读出size字节的次数,fp是要读出的文件指针。
功能:从fp指向的文件的当前位置开始,一次读出size个字节,重复count次,并将读出的数据放到从buffer开始的内存中。
52,对文件进行格式化读写:
1,格式化输出函数:fprintf(),
格式化输入函数:fscanf()
与scanf(),printf()功能相同,只不过操作对象是文件,不像scanf()和printf()操作的对象是标准输入,标准输出而已。
fprintf()调用格式:
fprintf(文件指针,"格式符",输出参量表);
参数说明:文件指针,是指将输出参量表的内容输出到文件指针所指向的文件中,"格式符"与"输出参量表"的定义与printf()函数相同。
功能:将输出参量表的内容按照"格式符"的要求输出到指定的文件中。
fscanf()函数同理。
52,位置指针复位--rewind()函数
调用格式:rewind(文件指针);
功能:使文件的位置指针回到文件头。
53,随机读写---fseek()函数
54,返回文件当前位置--ftell()函数
ftell(文件指针):返回文件位置指针的当前位置,若返回值为-1L,则表明调用出错。
55,出错检测:
ferror(文件指针):若返回值为0,表示未出错,若非0,表示出错。
对同一文件,每次调用输入/输出函数都会产生一个新的ferror()函数值;
在执行fopen()函数时,系统将ferror()的值自动置为0.
clearerr(文件指针);将文件错误标志置为0;