1.基本格式
#include "stdio.h"
...//函数体
int main(){
...//主函数
}
1.1简单实例
#include "stdio.h"
void prinHello(){
printf("Hello World!");
}
int main(){
prinHello();
return 0;
}
1.2具体讲解
(1)#include
意思为导入,stdio
为标准输入和输出,而.h
为头文件,所以#include"stdio.h"
[1]的意思是导入一个标准输入和输出的头文件,这个头文件通常是系统自带的库里的文件,而导入的头文件不同,能使用该文件里的函数就不同
(2)①在函数体中void
表示没有返回值,如需有返回值则将void
改为具体的返回值类型,且在{}
写上retrun 返回值
;
②prinHello
为函数名,函数名只能用字母、下划线、数字表示,不能使用关键字,且必须以字母或下划线开头,不能以数字开头;
③()
里可以写形式参数(简称“形参”),形参用数据类型 声明的变量
表示,也可以不添加形参表示空参,但在调用空参函数时还是需要在函数名后面加上()
;
④函数具体内容写在{}
里面,可以一个{}
内嵌入许多{}
,每一个语句写完都要用;
隔开;
⑤printf()
是系统自带的函数,表示把输入的内容打印在输出窗口,调用时在printf
的()
里添加""
,并在""
里输入想要打印的内容即可
(3)①int main()
是主函数的入口,其{}
写入主函数执行语句,因为C语言从上到下编译的特性,普通函数只能写在主函数上面,且主函数只有一个;
②prinHello()
是一个调用上面已经写好的函数的语句;return 0
表示返回值为0,即退出程序
2.数据类型与格式符
(1)数据类型与它的格式符一一对应,数据类型声明变量,格式符放在输入输出语句中
(2)常见的有:int–%d,double–%lf,float–%f,char–%c,long–%ld,short–%hd,unsigned int–%u …
3.输出对齐与保留小数位数
如print("%10.2lf",a)
中10
表示向右对齐10个位置,同理-10
表示向左对齐10个位置,而.2
表示保留小数后2位
4.非格式化输入和输出
4.1 gets()输入与puts()输出
4.1.1 gets()输入
(1)用法:
int main(){
char arr[10],*s; //声明一个字符数组变量,即字符串和一个字符串指针
gets(arr); //从键盘上输入字符串,直到回车结束
gets(s); //从键盘上输入字符串,直到回车结束
}
(2)特点:
①gets()
是从键盘输入字符串 开始到按下回车 结束,其中直到回车前有空格也行,且回车 不包含在字符串内
②gets(arr)
其中arr
可以是字符串数组名,也可以是字符串指针,如果不是字符串而是单个字符,则编译可能不报错,但 运行会报错
4.1.2 puts()输出
(1)用法:
int main(){
char arr[]="Hello World!"; //声明一个字符串arr并给该字符串赋值
puts(arr); //输出arr内容到屏幕
char* s; //声明一个字符串指针s
s="Hi! World"; //给s赋值
puts(s); //输出s指向的内容到屏幕
puts("Hello China!"); //直接输出括号里的内容
}
(2)特点:
①输出完字符串后会自动换行
②只能输出字符串,不能输出运算结果
③可以直接在puts()
里写入要输出的字符串
4.2 getchar()输入与putchar()输出
4.2.1 getchar()输入
(1)用法:
int main(){
char a; //声明一个单个字符变量a
a=getchar(); //从键盘上读取输入的单个字符赋值给a
}
(2)特点:
①无论从键盘上输入多少个字符,getchar()
只读取输入的第一个字符作为返回值
②从键盘输入字符 开始到按下回车 才结束
(3)解释:
getchar()
是stdio.h
中的库函数,它的作用是从stdio
流中读入一个字符;键盘输入字符是先存入缓冲区,当你按下回车时,getchar
就会进入缓冲区读取字符,一次只读取第一个字符,我们输入的一串字符被读出来是getchar
循环读取的结果,而回车键取代了我们输入的第一个字符,我们输入getchar()
来清除回车键,达到从第一个字符开始读起的目的
4.2.2 putchar()输出
(1)用法:
int main(){
char a; //声明单个字符变量a
a='A'; //把a赋值为A
putchar(a); //输出A
putchar(0x41); //因为A在ASCII码中十六进制为0x41,所以输出A
putchar('\x41'); //因为'\x41'就相当于十六进制的0x41,所以也输出A
}
(2)特点:
①向标准输出设备只输出一个字符
②相当于printf("%c",a)
5.内存分配与释放函数
5.1 malloc函数分配动态内存地址
(1)用法:
#include"stdlib.h"
#include"stdio.h"
int main(){
int* n; //声明一个整数型指针变量n
n = (int*) malloc(2*sizeof(int)); //为变量n分配动态内存空间
*n = 5; //把5这个值转成二进制存放在变量n的内存空间里
printf("变量n地址为: %d\n", n);
printf("变量n的值为: %d\n", *n);
return 0;
}
(2)解释:
①使用malloc
函数分配动态内存空间时要先引入#include<stdlib.h>
头文件
②malloc
函数的函数原型为void* malloc(unsigned int size)
,它根据参数指定的尺寸来分配内存空间,且返回一个void
型指针,指向新分配的内空间的初始地址;但如果内存分配失败(内存不足),则函数返回NULL
③n=(int*)malloc(2*sizeof(int))
这段代码中,sizeof(int)
是分配一个整数类型所占用的字节数的内存空间,通常为4个字节,所以malloc(2*sizeof(int))
表示分配一个大小为2*sizeof(int)
字节的内存空间,即分配了8个字节大小的内存空间
④n=(int*)malloc(2*sizeof(int))
这段代码中,(int*)malloc
这样写的原因是malloc
函数原本返回的是一个void*
类型的指针,但指针变量n
是int*
型的,所以需要将其强制转换为int*
类型,才能够将其赋值给一个int*
型即整型指针变量
5.2 free函数释放动态分配的内存
(1)用法:
#include"stdlib.h"
#include"stdio.h"
int main(){
int* n; //声明一个整数型指针变量n
n = (int*) malloc(2*sizeof(int)); //为变量n分配动态内存空间
*n = 5; //把5这个值转成二进制存放在变量n的内存空间里
printf("变量n地址为: %d\n", n);
printf("变量n的值为: %d\n", *n);
free(n); //释放变量n分配的动态内存
return 0;
}
(2)解释:
①使用free
函数释放动态分配的内存时要先引入#include<stdlib.h>
头文件
②用free
函数去释放要释放的内存的指针为NULL
时,则无事发生;但释放内存后的指针不能再free
一次,否则会导致程序崩溃或者出现错误
③只有使用malloc
、calloc
、realloc
等函数动态分配的内存,才能用free()
函数进行释放
④free
函数的函数原型为void free(void* memblock)
,其中memblock
参数是一个指针,指向要释放的内存空间,以避免内存泄漏;但memblock
指针本身并不会消失,所以一般可以使用free
函数后,memblock=NULL
使memblock
指针变为空指针
6. enum枚举类型
(1)用法:
#include "stdio.h"
enum Weekday { //定义枚举类
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
int main() {
enum Weekday today = Wednesday; //声明enum Weekday类型的today并用Wednesday赋值
printf("今天是星期%d\n", today + 1);
return 0;
}
(2)解释:
①枚举类型使用enum
关键字进行定义
②枚举类型中的常量默认从0开始递增,所以上面的例子中,Monday
的值为0
,Tuesday
的值为1
,以此类推
③如果需要改变枚举类型中常量的值,可以在定义枚举类型时显式指定常量的值,如Monday = 1
7. typedef自定义类型与struct结构体
(1)用法:
typedef struct Book{ //新的数据类型为struct Book
char no[20];//ISBN
char name[20];//名字
float price;//价格
}novel; //别名为novel
struct Book{ //新的数据类型为struct Book
char no[20];//ISBN
char name[20];//名字
float price;//价格
};
(2)解释:
①结构体struct
用于定义一个新的数据类型,这个新的数据类型可以由任意的基本数据类型构成,如int
、char
、float
等
②自定义类型typedef
一般和结构体struct
一起用,只不过在typedef struct Book{};
的;
前多了一个可以添加别名的位置,如上面的novel
,这个别名用于充当新的数据类型struct Book
来声明变量
8. Status用法
(1)用法:
#include "stdio.h"
typedef enum { //自定义枚举类型
SUCCESS, //成功
ERROR //失败
} Status; //别名为Status
Status foo() { //Status类型的foo函数
return SUCCESS;// 函数逻辑
}
int main() {
Status result = foo(); //声明一个Status类型的result,用同样Status类型的foo函数赋值
if (result == SUCCESS) {
printf("函数执行成功\n");
} else {
printf("函数执行失败\n");
}
return 0;
}
(2)解释:
Status通常是一个自定义的类型(typedef
),用于表示函数的返回状态;它通常被定义为一个枚举类型(enum
)或整型类型(int
),用来表示函数执行的结果,例如:成功、失败或其他状态
9. assert函数
(1)用法:
#include "assert.h"
#include "stdio.h"
int main() {
FILE *fp = NULL;
fp = fopen("file.txt", "r");
assert(fp != NULL); //如果文件打开失败,则程序会通过assert断言终止运行
char c = fgetc(fp);
printf("读取字符: %c\n", c);
fclose(fp);
return 0;
}
(2)解释:
①assert
函数使用时需要调用#include<assert.h>
头文件
②assert
函数是一个调试宏,用于判断某个条件是否成立;如果条件不成立,则输出错误信息并调用abort
函数,使程序异常终止;其作用可以在程序开发和调试过程中帮助我们快速定位错误,并且可以避免在错误条件下程序继续执行导致更严重的问题
③在上面的代码中,如果文件打开失败,则fp
指向NULL
,此时assert(fp != NULL)
条件不成立,程序会输出错误信息并终止运行;如果文件成功打开,则会正常读取文件中的字符
调用系统自带的头文件一般是例如#include<stdio.h>用的尖括号,而如果是调用自己写的头文件一般是用的双引号;上面的代码用的双引号是因为尖括号在代码高亮里显示不出来,暂时无法解决 ↩︎