C语言

计算机考研零基础C语言第一章(1) 数值转换和C语言组成及数据  计算机考研零基础C语言第一章(2) 函数与运算符

 计算机考研零基础C语言第二章(3) 顺序结构  计算机考研零基础C语言第三章(4)选择结构  计算机考研零基础C语言第四章(5) 循环结构

计算机考研零基础C语言第五章(6) 数组与字符串

#include<stdio.h>  #include<stdlib.h>  #include<io.h>  #include<dos.h>  #include<fcntl.h>  #include<process.h>  #include<string.h>  #include<math.h>  #include<ctype.h>
#include<time.h>  #include<dir.h>  #include<malloc.h>  #include <conio.h>

程序 = 数据结构+算法  &取地址 int a=5; int *p; //整型指针  p = a;  printf("%d",&p);

C 程序由各种令牌组成,令牌可以是关键字、标识符、常量、字符串值,或者是一个符号。分号是语句结束符

C 语言有两种注释方式:// 单行注释  /* 块注释 */

关键字:break跳出当前循环 continue结束本次循环 const定义常量  char声明字符变量或函数返回值  float声明浮点型变量或函数返回值  int声明整型变量  static声明静态变量  struct声明结构体

C语言数据类型:基本类型,构造类型,指针类型,空类型。
基本类型:整型、浮点型 int/4B long/8B float/4B double/8B char/1B、enum枚举类型:算术型,被用来定义在程序中只能赋予其一定的离散整数值的变量
void类型:表明没有可用的值
派生类型:指针类型、数组类型、结构体类型和函数类型

printf输出格式:%d整数  %o以八进制输出无符号整数  %u以十进制输出无符号整数  %f以小数形式输出单、双精度实数

%E以指数形式输出单、双精度实数  %g以小数或指数形式输出  %c输出单个字符  %s输出字符串  %x无符号16进制整数
%p 输出指针地址  %lu:32位无符号整数  %llu:64位无符号整数  %6.2f至少6个宽度,只保留2个小数位

输入格式:int scanf("普通/占位符",地址列表);  int a,b; scanf("%d,%d",&a,&b);  scanf函数返回成功读入的数据项数,读入数据时遇到了“文件结束”则返回EOF。

如:scanf("%d %d",&a,&b);函数返回值为int型。如果a和b都被成功读入,那么scanf的返回值就是2;如果只有a被成功读入,返回值为1;如果a和b都未被成功读入,返回值为0;

 putchar('c'); //输出一个字符 char c=getchar();//从键盘接收字符数据

变量:是程序可操作的存储区的名称;  无初值是随机值

变量的命名规则:变量的名称可以由字母、数字和下划线字符组成。它必须以字母或下划线开头。大写字母和小写字母是不同的,因为 C 是大小写敏感的。

变量类型:char int float double void 枚举、指针、数组、结构、共用体等等  char='' 不可为空  char='\\' //输出一个\必需用转移字符  字符串常量:"a1"

单精度:单精度浮点值。单精度是这样的格式,1位符号,8位指数,23位小数。

 

双精度:双精度浮点值。双精度是1位符号,11位指数,52位小数。

 

 

  变量的声明有两种情况:

  • 1、一种是需要建立存储空间的。例如:int a 在声明的时候就已经建立了存储空间。
  • 2、另一种是不需要建立存储空间的,通过使用extern关键字声明变量名而不定义它。 例如:extern int a 其中变量 a 可以在别的文件中定义的。除非有extern关键字,否则都是变量的定义

左值(lvalue):指向内存位置的表达式被称为左值(lvalue)表达式。左值可以出现在赋值号的左边或右边。

右值(rvalue):术语右值(rvalue)指的是存储在内存中某些地址的数值。右值是不能对其进行赋值的表达式,也就是说,右值可以出现在赋值号的右边,但不能出现在赋值号的左边。

常量:是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量

整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,0b表示二进制,不带前缀则默认表示十进制。

整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。30ul  /* 无符号长整数 */

3.14159       /* 合法的 */   314159E-5L    /* 合法的 */

字符常量可以是一个普通的字符(例如 'x')、一个转义序列(例如 '\t'),或一个通用的字符(例如 '\u02C0')

常用的转义字符:\\ \' \" \? \r \t

在 C 中,有两种简单的定义常量的方式:1.使用 #define width 5 预处理器。2.使用 const int width=5关键字。

C 存储类: auto register static extern
auto 存储类是所有局部变量默认的存储类。auto 只能用在函数内,即 auto 只能修饰局部变量。
register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小(通常是一个词),且不能对它应用一元的 '&' 运算符(因为它没有内存位置)。寄存器只用于需要快速访问的变量,比如计数器。还应注意的是,定义 'register' 并不意味着变量将被存储在寄存器中,它意味着变量可能存储在寄存器中,这取决于硬件和实现的限制。
static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值。
static 修饰符也可以应用于全局变量。当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。
全局声明的一个 static 变量或方法可以被任何函数或方法调用,只要这些方法出现在跟 static 变量或方法同一个文件中。
extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的。当您使用 extern 时,对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置。

C运算符:运算符是一种告诉编译器执行特定的数学或逻辑操作的符号
算术运算符:+ - * / % ++ --
关系运算符:== != > < >= <=
逻辑运算符:与&& 或|| 非!
位运算符:与1&1=1 或0|0=0 异或1^0=1 取反~0=1 左移<<左丢右补0 60<<=240 右移>>正左补0,负左补1,右丢弃 60>>2=15
赋值运算符:= += -= *= /= %= <<= >>= &= ^= |=
其他运算符:sizeof(int):返回变量的大小   &a返回变量的地址   *指向一个变量   三目运算符: a>b?1:0

判断结构要求程序员指定一个或多个要评估或测试的条件,以及条件为真时要执行的语句(必需的)和条件为假时要执行的语句(可选的)。

执行语句:控制语句(顺序、选择、循环)、函数调用语句、表达式语句、空语句、复合语句
C 语言把任何非零和非空的值假定为 true,把零或 null 假定为 false。

if(){}else{}    if(){}else if(){} else{}  switch(整型/枚举){case 1:;break;case 2:;break;default:}

C 语言提供了以下几种循环类型:while(){}  do{}while();  for(int i=1; i<=n; i++){}  //ctrl+z为EOF

break:跳出循环体  continue:结束一次循环   goto:loop;loop:...

函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即主函数 main() 

函数声明告诉编译器函数的名称返回类型参数。函数定义提供了函数的实际主体。

传值调用:该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。
引用调用:通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。

C 作用域规则
1.在函数或块内部的局部变量  2.在所有函数外部的全局变量  3.在形式参数的函数参数定义中
全局变量保存在内存的全局存储区中,占用静态的存储单元;局部变量保存在栈中,只有在所在函数被调用时才动态地为变量分配存储单元。

静态存储:在变量定义的时候就分配好了存储单元,一直保持不变;全局变量  static extern
动态存储:程序执行的时候才动态分配存储空间,使用完毕立即释放。局部变量:函数参数,栈空间 auto、register、static

数组:double balance[5]={5,4,2,1,3};  double balance[] ={12,3,5,9,4};  int a[3][4]={ {1,3,5,2},{6,2,7,8},{4,6,2,1}};

char ch1[]="abdfc";    char ch2[] = {"abdfc"};    char ch3[]={'a','b','d','f','c','\0'};

数组元素遍历  int i ; for(i=0, i<5; i++){ printf("%d\t",balance[i]); }

数组下标不能使用变量;数组名即为地址值;

枚举是 C 语言中的一种基本数据类型,它可以让数据更简洁,更易读。
注意:第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。我们在这个实例中把第一个枚举成员的值定义为 1,第二个就为 2,以此类推

enum DAY{  MON=1, TUE, WED, THU, FRI, SAT, SUN  };  enum DAY day;
enum DAY{  MON=1, TUE, WED, THU, FRI, SAT, SUN  } day;

指针:是一个变量,存储了另一个变量的地址值。每一个变量都有一个内存位置,每一个内存位置都定义了可使用 & 运算符访问的地址,它表示了在内存中的一个地址。 int a = 10; int *p =NULL;p = &a; 

指针类型两个最基本的操作:&取地址操作 *去引用操作(间接寻址运算)

指针与函数:int *getmin(int *a, int *b){
return *a<*b?a:b;//返回值是地址
}

 int func(int a, int b, int(*p)(int,int)){

return (*p)(a,b);//指针指向的函数可以是参数传递过来的函数体
}

指针与数组:int *p=a[0]; //指针可以指向二维数组的行

int (*p)[2]; //p+i指向a[i]的地址
p=a; //*(p+i)等价于a[i];  *(p+i)+j等价于a[i][j]的地址;   *(*(p+i)+j)等同于访问a[i][j];

指针数组:数组的元素是指针:int *a[2];  数组指针:int (*p)[2];//数组指针,p是指向数组的指针

指向指针的指针:int **p; //  

void m3(){
int i,j,a[3][3]={{1,2,3},{5,6,4},{9,8,7}};
int *ap[]={a[0],a[1],a[2]};
int **p=NULL;
p=ap;
for(i=0; i<3;i++){
for(j=0; j<3; j++){
printf("%d ",*(*p+j));
}
p++;
printf("\n");
}
}

数组元素的保护:const int  *p;//指针指向的地址可以改变,*p不能改变地址的内容。*p+2等同于*(p+2);

指针与字符串

*p++等价于*(p++)指针移动指向下一个元素,表达式返回指针移动前所指的数据
(*p)++则是取得指针所指向的数据,并让其加1.

在 C 语言中,字符串实际上是使用 null 字符 '\0' 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。

char greeting[6]={'H','e','l','l','o','\0'}; == char greeting[]="Hello";
strcpy(s1, s2);//复制字符串 s2 到字符串 s1。
strcat(s1, s2);//连接字符串 s2 到字符串 s1 的末尾。
strlen(s1);//返回字符串 s1 的长度
strcmp(s1, s2);//如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回小于 0;如果 s1>s2 则返回大于 0。
strchr(s1, ch);//返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
strstr(s1, s2);//返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。

结构体是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。定义结构体时不分配内存。结构体可以构成嵌套

struct Books { char title[50]; char author[50]; char subject[100]; int book_id; } book;

void declareEmbedStructure(){
struct date{
int month;
int day;
int year;
};
struct student{
int num;
char name[20];
char gender;
struct date birthday;
float score;
};
}

定义结构体变量:结构变量名.成员名;

struct{成员变量列表}变量名列表;
struct 结构名 变量名列表;
struct 结构名{成员列表}变量名列表;

结构数组:数组元素类型是结构体
方式一:struct{int num; char *name; char sex; float score;}stu[30];
方式二:struct student{int num; char *name; char sex; float score;}stu[30];
方式三:struct student{int num; char *name; char sex; float score;};  struct student stu[30];

指向结构的指针:指针指向结构体:struct Books *struct_pointer;   struct_pointer = &Book1;   struct_pointer->title;   结构指针做参数

使用结构指针访问结构体成员
(*结构体指针变量).成员名;
结构指针变量->成员名;

"位域/位段"是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。

struct bs{ int a:8;   int b:2;   int c:6; }data;  说明 data 为 bs 变量,共占两个字节。其中位域 a 占 8 位,位域 b 占 2 位,位域 c 占 6 位。

位域的使用和结构成员的使用相同,其一般形式为:位域变量名.位域名   或者   位域变量名->位域名

共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。共用体占用的内存应足够存储共用体中最大的成员。

union Data { int i; float f; char str[20]; };

 

C 语言中的 I/O (输入/输出) 通常使用 printf() 和 scanf() 两个函数。

printf() 用于格式化输出到屏幕。printf() 函数在 "stdio.h" 头文件中声明。  scanf() 函数用于从标准输入(键盘)读取并格式化

int scanf(const char *format, ...) 函数从标准输入流 stdin 读取输入,并根据提供的 format 来浏览输入。

int printf(const char *format, ...) 函数把输出写入到标准输出流 stdout ,并根据提供的格式产生输出。

int getchar(void) 函数从屏幕读取下一个可用的字符,并把它返回为一个整数

int putchar(int c) 函数把字符输出到屏幕上,并返回相同的字符

char *gets(char *s) 函数从 stdin 读取一行到 s 所指向的缓冲区,直到一个终止符或 EOF。

int puts(const char *s) 函数把字符串 s 和一个尾随的换行符写入到 stdout

C文件: fopen( ) 函数来创建一个新的文件或者打开一个已有的文件,这个调用会初始化类型 FILE 的一个对象

FILE *fopen( const char * filename, const char * mode );

关闭文件:int fclose( FILE *fp ); 成功关闭文件,fclose( ) 函数返回零,如果关闭文件时发生错误,函数返回 EOF

写入文件:int fputc( int c, FILE *fp );函数 fputc() 把参数 c 的字符值写入到 fp 所指向的输出流中。如果写入成功,它会返回写入的字符,如果发生错误,则会返回 EOF
int fputs( const char *s, FILE *fp );函数 fputs() 把字符串 s 写入到 fp 所指向的输出流中。如果写入成功,它会返回一个非负值,如果发生错误,则会返回 EOF
int fprintf(FILE *fp,const char *format, ...) 函数来写把一个字符串写入到文件中。

文件指针:FILE *fp = NULL;  
打开文件:fp = fopen("f:/coding/ab.txt","a+");  //FILE* fopen(const char*,const char*); // r只读;w只写;a追加内容;t文本文件,默认,可省略;b二进制文件;+同时可读可写

fprintf(fp,"\nThis is testing for fprintf...\n");
fputs("This is testing for fputs...\n",fp);
fclose(fp);

字符读写函数:fgetc() fputc() 以字符/字节为单位读写文本或二进制文件
字符串读写函数:fgets() fputs() 一次读写一个字符串
数据块读写函数:fread() fwrite() 读写一个数据块
格式化读写函数:fscanf() fprintf() 按指定格式读写数据

读取文件:int fgetc( FILE * fp ); 从 fp 所指向的输入文件中读取一个字符;返回值是读取的字符,如果发生错误则返回 EOF

函数 fgets() 从 fp 所指向的输入流中读取 n - 1 个字符。它会把读取的字符串复制到缓冲区 buf,并在最后追加一个 null 字符来终止字符串。这个函数在读取最后一个字符之前就遇到一个换行符 '\n' 或文件的末尾 EOF,则只会返回读取到的字符,包括换行符;

while(!feof(fp)) //判断文件是否结束

int fscanf(FILE *fp, const char *format, ...) 函数来从文件中读取字符串,但是在遇到第一个空格和换行符时,它会停止读取。

fscanf(fp,"%s",buff);//遇到空白即停止
printf("1:%s\n",buff);

fgets(buff,255,(FILE*)fp);//读取一行
printf("2:%s\n",buff);

文件定位:主要有3个函数
void rewind(FILE *fp);//用于将文件读写位置移到文件开始
int fseek(FILE* fp,long offset,int startpos);//读写位置移动到文件内部指定位置
long ftell(FILE*);//获取文件当前位置

void m7(){//小写转换为大写
FILE *fp; char str[100]; int i=0;
if((fp=fopen("f:/wwweb/aa.txt","w+"))==NULL){
printf("can't open this file.\n"); exit(0);
}
printf("input a string:\n");
gets(str);
while(str[i]){
if(str[i]>='a'&&str[i]<='z')str[i]=str[i]+'A'-'a';
fputc(str[i],fp); i++;
}
fclose(fp);
fp=fopen("f:/wwweb/aa.txt","r+");
fgets(str,100,fp);
printf("%s\n",str);
fclose(fp);
}

#define 是 C 指令,用于为各种数据类型定义别名,与 typedef 类似,但是它们有以下几点不同:
typedef 仅限于为类型定义符号名称,#define 不仅可以为类型定义别名,也能为数值定义别名,比如您可以定义 1 为 ONE。
typedef 是由编译器执行解释的,#define 语句是由预编译器进行处理的。

自定义类型声明typedef 原类型名 新类型名;
typedef int Integer; typedef char* String;

C 预处理器(C Preprocessor)简写为 CPP;所有的预处理器命令都是以井号(#)开头

#define定义宏;#undef取消已定义的宏;#include包含一个源代码文件 "自定义.h"文件;

printf("File :%s\n", __FILE__ );  //File :F:\coding\a20201113.c  这会包含当前文件名,一个字符串常量。
printf("Date :%s\n", __DATE__ );  //Date :Nov 13 2020  当前日期,一个以 "MMM DD YYYY" 格式表示的字符常量。
printf("Time :%s\n", __TIME__ );  //Time :19:29:30  当前时间,一个以 "HH:MM:SS" 格式表示的字符常量。
printf("Line :%d\n", __LINE__ );  //Line :32  这会包含当前行号,一个十进制常量。
printf("ANSI :%d\n", __STDC__ );  //ANSI :1  当编译器以 ANSI 标准编译时,则定义为 1

一个宏通常写在一个单行上。但是如果宏太长,一个单行容纳不下,则使用宏延续运算符(\)

头文件是扩展名为 .h 的文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享;有两种类型的头文件:程序员编写的头文件和编译器自带的头文件。

使用头文件,需要使用 C 预处理指令 #include 来引用它;建议把所有的常量、宏、系统全局变量和函数原型写在头文件中,在需要的时候随时引用这些头文件。

C 语言提供了 perror() 和 strerror() 函数来显示与 errno 相关的文本消息。

perror() 函数显示您传给它的字符串,后跟一个冒号、一个空格和当前 errno 值的文本表示形式。

strerror() 函数,返回一个指针,指针指向当前 errno 值的文本表示形式。

stderr 文件流来输出所有的错误

C内存管理 <stdlib.h>
void *calloc(int num, int size);在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0。所以它的结果是分配了 num*size 个字节长度的内存空间,并且每个字节的值都是0
void free(void *address); 该函数释放 address 所指向的内存块,释放的是动态分配的内存空间。
void *malloc(int num); 在堆区分配一块指定大小的内存空间,用来存放数据。这块内存空间在函数执行完成后不会被初始化,它们的值是未知的。
void *realloc(void *address, int newsize); 该函数重新分配内存,把内存扩展到 newsize。

void * 类型表示未确定类型的指针;C、C++ 规定 void * 类型可以通过类型转换强制转换为任何其它类型的指针。

posted @ 2021-02-21 15:27  geryhz  阅读(220)  评论(0)    收藏  举报