C语言

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;

原文地址:https://www.cnblogs.com/RitaLee/p/6072382.html