1_数据的输入输出
1.1_getchar与putchar
- getchar()使用方法
a = getchar()与scanf(“%c”,&a)效果一样
//getchar()使用方法
char a = getchar();
/*
getchar可以接收任何字符,接收完一个字符以回车表示结束
需要注意的是getchar也可以接收回车符号
*/
a = getchar();//点击回车,此时a接收的是回车符
例:
char c = getchar();
printf("输出:%c",c);
printf("输出结束");
1.2_printf与scanf
1.2.1_printf
- printf函数附加格式说明符集
字母 l | d/o/x/u 前,表示长整型数据 printf(“%ld”,a); |
字母 h | d/o/x/u 前,表示短整型数据 printf(“%hd”,a); |
正整数 m | 设置输出数据的宽度 printf(“%2d”,a);//例输出5,效果为" 5",即在5前面加一个空格 |
正整数 .n | 浮点数:n位小数,字符串:前n个字符 int a = 3.1415926;printf(“%.2f”,a);输出为3.14 |
— | 输出左对齐(默认为右对齐) |
1.2.2_scanf
- scanf分隔符问题
问题描述:当进行两个或者多个输入时,在这多个输入之间需要分隔符用来区分
//情景一
scanf("%d%d",&a,&b);
/*
此时进行输入a和b需要注意,输入a之后,需要点击空格或者回车,再进行b的输入
*/
//情景二(其中%*表示这个输入无效)
scanf("%c%c",&a.&b);//若输入为"z c",则a='z' b=' '
scanf("%c %c",&a.&b);//若输入为"z c",则a='z' b='c'
scanf("%c,%c",&a.&b);//若输入为"z,c",则a='z' b='c'
scanf("%c%*c%c",&a,&b);//若输入为"z,c",则a='z' b='c'
1.3_gets与puts
- gets(str)和scanf(“%s”,str);的区别
gets(str)可接收空格,以回车为结束输入标志
scanf(“%s”,str);不可以接收空格,因为其以空格为结束标志
char str[5];
gets(str);//输入字符串
puts(str);//输出字符串
2_分支结构
2.1_switch语句
switch(表达式)
{
case 常量表达式1:语句组;break;
case 常量表达式2:语句组;break;
...
default:语句组;
}
注意事项:
- 常量表达式是一个整形或者字符型常量
- 每个case最后必须要有break,否则执行完此case不会自动结束,而是继续执行其他case
- default的作用:当没有与这种情况匹配时,最后执行default语句
- 语句组无需用大括号括起来
3_数组
3.1_数组
注意事项:
- 数组名
数组名是数组在内存中的首地址
3.2_字符数组
注意事项:
C语言中的字符串类型
在c语言中没有string类型,字符串都是以字符数组的形式进行存储和展示的。转义字符’\0’
①用为字符串的结尾:每个字符串都默认以转义字符’\0’作为结尾的,所以如果一个字符串长度为3,则其真实长度应该为4,所以一个一维数组要想存储字符串"abc",其大小最小应该为4。
②用为空:在C语言中NULL=‘\0’字符串输出(要用&)
printf(“%s”,&str);
3.3_字符串函数
需要include头文件string.h
- strlen(str)获得字符串真实长度(不包括结束符)
- strcpy(str1,str2)将str2的内容复制到str1中
- strupr(str)将所有小写转大写
- strlwr(str)将所有大写转小写
4_函数
4.1_实际参数和形式参数(实参和形参)
#include <stdio.h>
void swap(int *a,int *b){//这里a和b是形参
int t;
t = *a;
*a = *b;
*b = t;
}
int main(){
int a = 1,b = 2;
swap(&a,&b);//这里是实参
printf("%4d%4d\n",a,b);
return 0;
}
4.2_数组作为函数参数
- 值传递方式
将数组的每个值挨个都传过去
- 地址传递方式
此时接收的形参有三种形式,一种是带下标的数组名(如function(int array[10]));一种是不带下标的数组名(如function(int array[]));最后是用指针接收(如function(int *array))
需要注意的是,接收二维数组的时候,形参的形式不能这样表示array[][]、array[3][],即下标最多只能省略第一个下标(如array[3][4]、array[][4])
4.3_内部函数和外部函数
内部函数static(只能在本文件使用)
外部函数extern
当b.c要引用a.c中的文件的时候,必须在a文件中将其声明为extern外部函数,值得注意的是,C语言默认函数是外部函数
5_变量
5.1_变量的存储类型
动态类型和静态类型区别:
- 动态类型:
①没有初值
②其所在的函数调用结束后立即释放其存储空间- 静态类型:
①初值为0
②每次调用时,其值都是上次使用完的值
普通全局变量和静态全局变量的异同
异(多文件中)
①普通全局变量:在其他文件中也能调用并使用
②静态全局变量:只能在本文件中使用同
全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式
5.1.1_动态存储
- 自动类型 auto
变量默认是自动类型
- 寄存器类型 register
直接把变量存储到CPU的通用寄存器
5.1.2_静态存储
- 静态类型static
系统分配永久的存储空间即分配在静态存储区
有全局静态和局部静态,因为用的比较多就不赘述了
- 外部类型 extern
①外部类型的使用场景一:单个文件中
int main(){
extern int a;
printf("%d",a);
}
int a = 10;
输出10
②外部类型的使用场景二:多个文件中
//a.c文件
int a = 0;//定义一个全局变量
//b.c文件
extern int a;//表示在b文件中要使用a
6_编译预处理
6.1_宏定义
#define 标志符 字符串
需要注意的是宏替换时仅以字符串取代宏名
6.2_导入文件格式
- 尖括号include <>格式
系统直接到存放C库函数头文件所在目录搜索- 双引号include ""格式
系统先去当前目录下寻找头文件,若没有再去存放库函数头文件所在目录搜索
7_指针
7.1_指针是什么
- 指针变量:指针变量的值是其指向变量的地址值,而其本身也有地址。
如int a = 0;int *p = &a;
则p的值是a的地址值(即&a),而&p是指针p的地址值。- 指针定义与使用
定义:如int *p;
符号代表定义的是一个指针
使用:如int *p,a = 0;p = &a;printf("%d",*p);
在使用指针时p表示取p指针所指地址存的数据。- 指针作为函数参数
指针作为函数参数时,其值会同步
7.2_指针与数组
- 数组名和指针的区别
在前面提及过,数组名就是此数组的首地址,这样看来数组名和指针并无区别,但是不同的是数组名是常量,而指针是变量,例如int a[5],*p = a;
其中用表示数组中第二个元素有如下表示方法:①数组名表示,a[1]或者*(a+1)
②指针表示p++,*p或者*(p+1)
可见用数组的方法并不能a++,*a
这样表示,因为数组名是常量
- 数组名和指针的相同点
除了1中所提及的数组名是常量,指针是变量外,其余都一样。
- 数组名作为函数参数
实际参数 | 形式参数 |
---|---|
数组名 | 数组 |
数组名 | 指针变量 |
指针变量 | 数组 |
指针变量 | 指针变量 |
7.3_指针与函数
1.指向函数的指针
①定义形式:数据类型 (*名)(参数列表)
②用途:即可作为函数使用,又可以将此函数当做参数进行传递(重要)
以下输出结果均为 2 1
//用途一
#include <stdio.h>
int swap(int *a,int *b){
int t;
t = *a;
*a = *b;
*b = t;
return 1;
}
int main(){
int a = 1,b = 2,(*swapCopy)(int *a,int *b);
*swapCopy = swap;
swapCopy(&a,&b);
printf("%4d%4d\n",a,b);
return 0;
}
//用途二
#include <stdio.h>
int swap(int *a,int *b){
int t;
t = *a;
*a = *b;
*b = t;
return 1;
}
int useSwap(int (*swapCopy)(int *a,int *b),int *a,int *b){
//此时swapCopy接收的是swap函数的首地址,然后把主函数a、b的地址传入
swapCopy(a,b);
return 1;
}
int main(){
int a = 1,b = 2;
//将swap函数作为参数传入,并将a、b地址传入
useSwap(swap,&a,&b);
printf("%4d%4d\n",a,b);
return 0;
}
2.返回指针的函数
形式如下:
类型 *函数名(参数){}
其中类型是返回指针指向的地址所存的数据类型
8_结构体
8.1_结构体基础
1. 结构体的定义如下:
struct 类型名{成员}变量名;
①类型名:由程序员自定义
②成员:成员变量
③变量名:是此结构体类型的变量,可定义多个变量
④后序如果需要再定义变量的话格式如下:struct 类型名 变量名;
其中struct不可省略
#include <stdio.h>
struct person
{
char name[10];
}girl,boy;//可以定义很多个变量
int main(){
struct person adult;//struct不可省略
return 0;
}
2. 不定义结构体类型名,直接定义结构体变量
struct {成员列表}变量名列表;
需要注意的是:由于没有定义类型名,所以也就无法在使用的时候定义此类型的其他变量了
3. 结构体变量的引用
①非指针:直接使用“.”即可,如
person.name
②指针:直接看例子
#include <stdio.h>
struct person
{
char name[10];
}*girl;
int main(){
puts((*girl).name);//*girl要用括号括起来
puts(girl->name);
return 0;
}
4. 同一类型的结构体可以相互赋值
如1中例子的
girl = boy;
将boy中的值全部给girl
8.2_结构体指针
需要注意的是即使结构体变量是指针类型的,因为结构体中的成员变量类型不一样指针不能在结构体中移动。
#include <stdio.h>
struct person
{
char name[10];
}*girl;
int main(){
puts((*girl).name);//*girl要用括号括起来
puts(girl->name);
return 0;
}
8.3_动态分配内存函数
要包含头文件<stdlib.h>
1. malloc函数
使用方法:
(type*)malloc(size);
动态分配一个大小为size,类型为type的内存
注意:返回值是指针
#include <stdio.h>
#include <stdlib.h>
struct person
{
char name[10];
}*girl;
int main(){
struct person *boy = (person *)malloc(sizeof(person));
return 0;
}
2. calloc函数
使用方法:
(type*)calloc(n,size);
动态分配n个大小为size,类型为type的连续内存
注意:返回值是指针
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct person
{
char name[10];
}*girl;
int main(){
struct person *boy = (person *)calloc(2,sizeof(person));
strcpy(boy->name,"name1");
strcpy((boy+1)->name,"name2");
printf("%s\n",boy->name);
printf("%s\n",(boy+1)->name);
return 0;
}
3. realloc函数
使用方法:
(type*)realloc(ptr,newsize);
将指针ptr的内存释放,并重新分配newsize大小的内存,并将原数据保留(前提是新size>旧size)
注意:返回值是指针
4. free函数
free( p );
9_文件操作
流程:
打开文件——>文件操作——>关闭文件
示例代码:
#include <stdio.h>
#include <string.h>
typedef struct person
{
char name[10];
}Person;
//以只读的方式打开文件
FILE* openFileForReadOnly(){
//打开文件,权限为只读
FILE* fp = fopen("C:\\Users\\Administrator\\Desktop\\test.txt","r");
if(fp == NULL){
printf("文件打开失败\n");
return 0;
}
return fp;
}
void readFile(FILE* fp){
//函数fgetc(fp)用于读取文件指针所指向的一个字符,读取完自动后移一位,返回值为所读的字符
char a = fgetc(fp);
printf("%c",a);
//使用fgetc(fp)逐字符的读取整个文件
while(a != EOF){
a = fgetc(fp);
printf("%c",a);
}
}
void readFileLine(FILE* fp){
//fgets(str,maxSize,file)每次读一行,每次读完指针自动后移,返回值也为所读的字符
//等价用法strcpy(str,fgets(str,200,fp));
char str[200];
while(fgets(str,200,fp)){
printf("%s",str);
}
}
void readFileRandom(FILE* fp){
//fread函数指定读取的比特个数为byte*size,返回值为所读取的单位个数
//fread ( void *ptr, size_t size, size_t count, FILE *stream) ;读取,size指明一个单位几个字节,size是几个单位
//但是由于实际运用时将size和count对调一下效率更高,所以经常这样使用fread ( void *ptr, size_t count, size_t size, FILE *stream)
char str[200];
memset(str,0,sizeof(str));//将str清空,否则会有烫
while(fread(str,1,100,fp)){
printf("%s",str);
}
}
//以覆盖写的方式打开文件
FILE* openFileForWriteOnly(){
//打开文件,权限为写,不过第一次写之前会清空整个文本
FILE* fp = fopen("C:\\Users\\Administrator\\Desktop\\test.txt","w");
if(fp == NULL){
printf("文件打开失败\n");
return 0;
}
return fp;
}
void writeFile(FILE* fp){
//函数fputc(c,fp)用于项文件写入一个字符
for(int i = 0; i < 10; i++){
fputc('a',fp);
}
//写入字符串
char s[10] = "texttext";
fputs(s,fp);
//或者
fputs("stringxixixi",fp);
}
void writeFileRandom(FILE* fp){
//fwrite函数指定写的比特个数为byte*size,返回值为所读取的单位个数
//fwrite(void *ptr, size_t size, size_t count, FILE *stream);,size指明一个单位几个字节,size是几个单位
//但是由于实际运用时将size和count对调一下效率更高,所以经常这样使用fwrite(void *ptr, size_t count, size_t size, FILE *stream)
Person person = {"sheshe"};
fwrite(&person,1,sizeof(person),fp);
}
//以读写的方式打开文件
FILE* openFileForWriteOnly(){
//打开文件,权限为可读可写
FILE* fp = fopen("C:\\Users\\Administrator\\Desktop\\test.txt","r+");
if(fp == NULL){
printf("文件打开失败\n");
return 0;
}
return fp;
}
int main(){
FILE* fp = openFileForWriteOnly();
writeFileRandom(fp);
return 0;
}
9.1_打开文件方式
使用方式 | 作用 | 如果文件不存在 |
---|---|---|
“r”(只读) | 为了输入数据,打开一个已经存在的文本文件 | 出错 |
“w”(只写) | 为了输出数据,打开一个文本文件(打开文件之后会清空文件原来的内容) | 建立一个新的文件 |
“a”(追加) | 向文本文件添加数据 | 建立一个新的文件 |
“rb”(只读) | 为了输入数据,打开一个二进制文件 | 出错 |
“wb”(只写) | 为了输出数据,打开一个二进制文件 | 建立一个新的文件 |
“ab”(追加) | 向一个二进制文件尾添加数据 | 出错 |
“r+”(读写) | 为了读和写,打开一个文本文件 | 出错 |
“w+”(读写) | 为了读和写,建立一个新的文本文件 | 建立一个新的文件 |
“a+”(读写) | 打开一个文本文件,在文件尾进行读写 | 建立一个文件 |
9.2_文件操作
文件操作 | 使用方法 | 方法解析 |
---|---|---|
逐字符读 | char fgetc(FILE* fp); | 用于读取文件指针所指向的一个字符, 读取完自动后移一位,返回值为所读的字符 |
逐行读 | char* fgets(char *str,maxSize,FILE *fp); | 每次读一行,每次读完指针自动后移,返回值也为所读的字符 |
读任意字符 | fread(void *ptr, size_t size, size_t count, FILE *fp) | 指定读取的比特个数为byte*size,返回值为所读取的单位个数 |
逐字符写 | fputc(char c,FILE *fp); | 用于文件写入一个字符 |
写字符串 | fputs(char *s,FILE *fp); | 用于文件写入一个字符串 |
写任意字符 | fwrite(void *ptr, size_t size, size_t count, FILE *fp) | 指定写的比特个数为byte*size,返回值为所读取的单位个数 |
9.3_关闭文件
fclose(FILE *fp);