C语言基础查漏补缺

1_数据的输入输出

1.1_getchar与putchar

  1. 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

  1. printf函数附加格式说明符集
字母 ld/o/x/u 前,表示长整型数据
printf(“%ld”,a);
字母 hd/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

  1. 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

  1. 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:语句组;
	}

注意事项:

  1. 常量表达式是一个整形或者字符型常量
  2. 每个case最后必须要有break,否则执行完此case不会自动结束,而是继续执行其他case
  3. default的作用:当没有与这种情况匹配时,最后执行default语句
  4. 语句组无需用大括号括起来

3_数组

3.1_数组

注意事项:

  1. 数组名
    数组名是数组在内存中的首地址

函数传数组参数问题

3.2_字符数组

注意事项:

  1. C语言中的字符串类型
    在c语言中没有string类型,字符串都是以字符数组的形式进行存储和展示的。

  2. 转义字符’\0’
    ①用为字符串的结尾:每个字符串都默认以转义字符’\0’作为结尾的,所以如果一个字符串长度为3,则其真实长度应该为4,所以一个一维数组要想存储字符串"abc",其大小最小应该为4。
    ②用为空:在C语言中NULL=‘\0’

  3. 字符串输出(要用&)
    printf(“%s”,&str);

3.3_字符串函数

需要include头文件string.h

  1. strlen(str)获得字符串真实长度(不包括结束符)
  1. strcpy(str1,str2)将str2的内容复制到str1中
  1. strupr(str)将所有小写转大写
  1. 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_数组作为函数参数

  1. 值传递方式
    将数组的每个值挨个都传过去
  1. 地址传递方式
    此时接收的形参有三种形式,一种是带下标的数组名(如function(int array[10]));一种是不带下标的数组名(如function(int array[]));最后是用指针接收(如function(int *array))

需要注意的是,接收二维数组的时候,形参的形式不能这样表示array[][]、array[3][],即下标最多只能省略第一个下标(如array[3][4]、array[][4])

4.3_内部函数和外部函数

  1. 内部函数static(只能在本文件使用)

  2. 外部函数extern
    当b.c要引用a.c中的文件的时候,必须在a文件中将其声明为extern外部函数,值得注意的是,C语言默认函数是外部函数

5_变量

5.1_变量的存储类型

动态类型和静态类型区别:

  1. 动态类型:
    ①没有初值
    ②其所在的函数调用结束后立即释放其存储空间
  2. 静态类型:
    ①初值为0
    ②每次调用时,其值都是上次使用完的值
    在这里插入图片描述

普通全局变量和静态全局变量的异同

  1. 异(多文件中)
    ①普通全局变量:在其他文件中也能调用并使用
    ②静态全局变量:只能在本文件中使用


  2. 全局变量本身就是静态存储方式,静态全局变量当然也是静态存储方式

5.1.1_动态存储

  1. 自动类型 auto
    变量默认是自动类型

  1. 寄存器类型 register
    直接把变量存储到CPU的通用寄存器

5.1.2_静态存储

  1. 静态类型static
    系统分配永久的存储空间即分配在静态存储区
    有全局静态和局部静态,因为用的比较多就不赘述了
  1. 外部类型 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_导入文件格式

  1. 尖括号include <>格式
    系统直接到存放C库函数头文件所在目录搜索
  2. 双引号include ""格式
    系统先去当前目录下寻找头文件,若没有再去存放库函数头文件所在目录搜索

7_指针

7.1_指针是什么

  1. 指针变量:指针变量的值是其指向变量的地址值,而其本身也有地址。
    int a = 0;int *p = &a;则p的值是a的地址值(即&a),而&p是指针p的地址值。
  2. 指针定义与使用
    定义:如int *p;符号代表定义的是一个指针
    使用:如int *p,a = 0;p = &a;printf("%d",*p);在使用指针时
    p表示取p指针所指地址存的数据。
  3. 指针作为函数参数
    指针作为函数参数时,其值会同步

7.2_指针与数组

  1. 数组名和指针的区别
    在前面提及过,数组名就是此数组的首地址,这样看来数组名和指针并无区别,但是不同的是数组名是常量,而指针是变量,例如int a[5],*p = a;其中用表示数组中第二个元素有如下表示方法:①数组名表示,a[1]或者*(a+1)②指针表示p++,*p或者*(p+1)可见用数组的方法并不能a++,*a这样表示,因为数组名是常量
  1. 数组名和指针的相同点
    除了1中所提及的数组名是常量,指针是变量外,其余都一样。
  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);

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值