C语言学习

| C语言基础

|| 未知细节

#include // 是一个预处理命令,用来引入头文件
return 0; // 语句用于表示退出程序
所有的 C 语言程序都需要包含 main() 函数。 代码从 main() 函数开始执

|| 存储类

链接:Runoob_存储类
四类存储类↓
1)auto

  • auto 存储类是所有局部变量默认的存储类
  • 在函数开始时被创建,在函数结束时被销毁

2)register

  • register 存储类定义存储在寄存器上的变量
  • 因为它不是存储在 RAM 中的,因此它不能直接取地址(&)
  • 特点:访问速度很快

3)static

  • static 存储类用于在程序的生命周期内保持局部变量,在函数调用之间保持局部变量的值
  • static的作用
    • 在文件内,使变量成为全局变量,可以在函数内使用
    • 在函数内,使变量不会在每次调用时重置

4)extern

  • extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的
  • 可以在其他文件中使用 extern 来得到已定义的变量或函数的引用
  • extern 修饰符通常用于当有两个或多个文件共享相同的全局变量或函数的时候

|| 数组

链接:Runoob_数组
数组声明↓

  • 数组的声明并不是声明一个个单独的变量,而是声明一个数组变量,比如 runoob,然后使用 runoob[0]、runoob[1]、…、runoob[99] 来代表一个个单独的变量。
double balance[10];
// 现在 balance 是一个可用的数组,可以容纳 10 个类型为 double 的数字。

数组初始化↓

// 方式1
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
// 方式2
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};

访问数组↓

double salary = balance[9];

|| enum枚举

链接:Runoob_枚举

枚举概念↓

  • 一种基本数据类型,用于定义一组具有离散值的常量。它可以让数据更简洁,更易读

不用枚举↓

// 如果不用枚举,用define,代码过多
#define MON  1
#define TUE  2
#define WED  3
#define THU  4
#define FRI  5
#define SAT  6
#define SUN  7

使用枚举↓

  • 第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1
  • 在这个实例中把第一个枚举成员的值定义为 1,那么第二个就为 2,以此类推
enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};
  • 定义时改变枚举的值,没有指定值的枚举元素,其值为前一元素加 1
enum season {spring, summer=3, autumn, winter};
结果为:spring是0,而从summer开始逐渐递增:345

枚举变量定义↓

1、先定义枚举类型,再定义枚举变量
enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
};
enum DAY day;

2、定义枚举类型的同时定义枚举变量
enum DAY
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

3、省略枚举名称
enum
{
      MON=1, TUE, WED, THU, FRI, SAT, SUN
} day;

枚举实例↓

  • 如何理解枚举用于定义具有离散值的常量
// 代码部分
#include <stdio.h>
enum DAY
{
	MON=1, TUE, WED, THU, FRI, SAT, SUN
};
 
int main()
{
    enum DAY day;
    day = WED;
    printf("%d",day);
    return 0;
}

//输出结果
3
  • 整数转换为枚举
// 代码部分
#include <stdio.h>
#include <stdlib.h>
int main()
{
   enum day
   {
       saturday,
       sunday,
       monday,
       tuesday,
       wednesday,
       thursday,
       friday
    } workday;
int num = 1;
enum day weekend;
weekend = (enum day) num;
printf("转换的结果为weekend:%d",weekend);
return 0;
}

// 运行结果
转换的结果为weekend:1

|| C 指针

链接:runoob_指针

|| 字符串

链接:runoob_字符串

|| 结构体

链接:runoob_结构体

结构体 vs 数组↓

  • 数组:可存储相同类型的数据项

  • 结构体:一种用户自定义的可用的数据类型,可存储不同类型的数据项

  • 结构体数据成员

    • 基本数据类型(int、float、char…)
    • 其他结构体类型、指针类型

结构体定义↓

struct Books  // 1.结构体标签
{
   char  title[50];  // 2.成员变量
   char  author[50];
   char  subject[100];
   int   book_id;
} book1;book2; // 3.结构变量
// 可以指定多个,注意结束用分号“;”

用typedef创建新类型↓
😀

  • 用typedef创建新类型new_type后,用new_type声明结构变量
typedef struct
{
    int a;
    char b;
    double c; 
} new_type;
new_type u1, u2[20], *u3;
// 结构变量可以是:自身类型,数组类型,指针类型

结构体互相包含↓

  • 结构体互相包含,则需要对其中一个结构体进行不完整声明
struct B;    //对结构体B进行不完整声明
struct A
{
    struct B *partner;
    //...
};
struct B
{
    struct A *partner;
    //...
};

结构体初始化-访问-作参数↓

#include <stdio.h>
// 结构体初始化方法 1
struct Books
{
   char  title[50];
   char  author[50];
   char  subject[100];
   int   book_id;
} book1 = {"C 语言", "RUNOOB", "编程语言", 123456};

// 结构体初始化方法 2
struct Books book2;
strcpy(book2.title,"C Programming");
printf("book2的title是:%s",book2.title);

// 结构体作为函数参数
void printBook( struct Books book )
{
   printf( "Book title : %s\n", book.title);
   printf( "Book author : %s\n", book.author);
   printf( "Book subject : %s\n", book.subject);
   printf( "Book book_id : %d\n", book.book_id);
}

int mian(){
	// 访问
	printf("书的标题:%s \n书的作者:%s \n编程语言:%s \n书籍编号:%s",
		book1.title,book1.auther,book1.subject,book1.book_id);
	// 函数参数传递
	printBook(book1)
}

指向结构体的指针↓

|| typedef

typedef 定义结构变量↓

  • typedef 是关键字,可以使用它来为类型取一个新的名字xxx,再使用xxx来定义结构变量
  • 参见结构体章节中的描述Jump→

typedef vs #define↓

  • typedef 只能为类型定义符号名称
  • #define 不仅可以为类型定义别名,也能为数值定义别名,比如您可以定义 1 为 ONE。

实例↓
关注点:为数值定义别名!!!

// 代码部分
#include <stdio.h>
#define TRUE  1
#define FALSE 0
int main( )
{
   printf( "TRUE 的值: %d\n", TRUE);
   printf( "FALSE 的值: %d\n", FALSE);
   return 0;
}

// 输出结果
TRUE 的值: 1
FALSE 的值: 0

|| 输入and输出

概念↓

  • C 语言提供了一系列内置的函数来输出数据到计算机屏幕上和保存数据到文本文件或二进制文件中
  • 文件指针 *fp 是访问文件的方式
  • C 语言中的 I/O 通常使用 printf() 和 scanf() 两个函数
  • 函数在"stdio.h" 头文件中声明
  • scanf() 函数用于从标准输入(键盘)读取并格式化
  • printf() 函数发送格式化输出到标准输出(屏幕)

在这里插入图片描述
scanf()

  • int scanf(const char *format, …)
  • 函数从标准输入流 stdin 读取输入,并根据提供的 format 来浏览输入
  • scanf() 期待输入的格式与您给出的 format 相同,否则报错
  • 只要遇到一个空格,scanf() 就会停止读取
  • “this is test” 对 scanf() 来说是三个字符串
常用 fomat对应类型
%s字符串
%d整型
%c字符
%f浮点数

printf()

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

getchar()

  • int getchar(void)
  • getchar() 函数从屏幕读取下一个可用的字符,并把它返回为一个整数
  • getchar() 函数同一时间只读取一个字符,或利用循环多次读取
// 代码部分
// 代码被编译和执行时,它会等待您输入一些文本
// 当您输入一个文本(含n个字符)并按下回车键时,程序会继续并只会读取一个单一的字符
#include <stdio.h>
int main( )
{
   int c;
   printf( "Enter a value :");
   c = getchar( );
   printf( "\nYou entered: ");
   putchar( c );
   printf( "\n");
   return 0;
}

// 输出结果
Enter a value :runoob
You entered: r

putchar()

  • int putchar(int c)
  • 函数把字符输出到屏幕上,并返回相同的字符
  • putchar() 函数同一时间只读取一个字符,或利用循环多次输出

gets()

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

puts()

  • int puts(const char *s)
  • 函数把字符串 s 和一个尾随的换行符写入到 stdout
#include <stdio.h>
int main( )
{
   char str[100];
   printf( "Enter a value :");
   gets( str );
   printf( "You entered: ");
   puts( str );
   return 0;
}

// 输出结果
Enter a value :runoob
You entered: runoob

|| 文件读写

链接:runoob_文件读写

打开文件 fopen()↓

  • 使用 fopen( ) 函数来创建一个新的文件或者打开一个已有的文件
  • 这个调用会初始化类型 FILE 的一个对象
  • 类型 FILE 包含了所有用来控制流的必要的信息
// 函数原型
FILE *fopen( const char *filename, const char *mode );
  • mode选择

在这里插入图片描述
关闭文件 fclose()↓

  • 如果成功关闭文件,fclose( ) 函数返回零
  • 如果关闭文件时发生错误,函数返回 EOF
  • 这个函数实际上,会清空缓冲区中的数据,关闭文件,并释放用于该文件的所有内存。
  • EOF 是一个定义在头文件 stdio.h 中的常量。
int fclose( FILE *fp );

写入文件↓

  1. 写入字符
int fputc( int c, FILE *fp );
  • 函数 fputc() 把参数 c 的字符值写入到 fp 所指向的输出流中
  • 如果写入成功,它会返回写入的字符
  • 如果发生错误,则会返回 EOF
  1. 写入字符串
// 把一个以 null 结尾的字符串写入到流中
int fputs( const char *s, FILE *fp );
  • 函数 fputs() 把字符串 s 写入到 fp 所指向的输出流中
  • 如果写入成功,它会返回一个非负值
  • 如果发生错误,则会返回 EOF。
  1. 对比两种字符串写入方式
fprintf(fp, "This is testing for fprintf...\n");
fputs("This is testing for fputs...\n", fp);

读取文件↓

  1. 读取字符

int fgetc( FILE * fp );

  • 函数从 fp 所指向的输入文件中读取一个字符
  1. 读取n-1个字符

char *fgets( char *buf, int n, FILE *fp );

  • 函数 fgets() 从 fp 所指向的输入流中读取 n - 1 个字符
  • 它会把读取的字符串复制到缓冲区 buf
  • 并在最后追加一个 null 字符来终止字符串

|| 预处理

链接:runoob_预处理

|| 头文件

链接:runoob_头文件

头文件概念↓

  • 头文件是扩展名为 .h 的文件,包含了 C 函数声明和宏定义,被多个源文件中引用共享
  • 程序员编写 or 编辑器自带
#include <file>
// 这种形式用于引用系统头文件
// 它在编译器的类库路径中搜索名为 file 的文件

#include "file"
// 这种形式用于引用用户头文件
// 它在包含当前文件的目录中搜索名为 file 的文件,如果没有找到
// 则到编译器的类库路径的目录下找该文件

头文件只引用一次↓

  • 如果一个头文件被引用两次,编译器会处理两次头文件的内容,这将产生错误
  • 标准的解决办法如下:把文件的整个内容放在条件编译语句中
  • 当再次引用头文件时,条件为假,因为 HEADER_FILE 已定义。此时,预处理器会跳过文件的整个内容,编译器会忽略它
// 代码展示
#ifndef HEADER_FILE   // 包装器 #ifndef
#define HEADER_FILE
the entire header file file
#endif

条件引用↓

  • 1)原方法
  • 从多个不同的头文件中,选择一个引入到系统中,可以通过条件来实现
  • 如果头文件比较多的时候,这么做是很不妥当的
// 1)
#if SYSTEM_1
   # include "system_1.h"
#elif SYSTEM_2
   # include "system_2.h"
#elif SYSTEM_3
   ...
#endif
  • 2)改进方法
  • 用一个 global.h 的头文件来包括所有的 .h 文件,然后在除 global.h 文件外的头文件中包含 global.h 就可以实现所有头文件的包含
// global.h
#ifndef _GLOBAL_H
#define _GLOBAL_H
#include <fstream>
#include <iostream>
#include <math.h>
#include <Config.h>
  • 3)条件引用方法
  • 条件引用:预处理器使用宏来定义头文件的名称
  • 它不是用头文件的名称作为 #include 的直接参数,而是使用宏名称替代
  • SYSTEM_H 会扩展,预处理器会查找 system_1.h,就像 #include 最初编写的那样。SYSTEM_H 可通过 -D 选项被您的 Makefile 定义
// 2)
 #define SYSTEM_H "system_1.h"
 ...
 #include SYSTEM_H

|| 强制类型转换

链接:runoob_强制类型转换

强制转换 ↓

  • 强制类型转换运算符的优先级大于除法,因此 sum 的值首先被转换为 double 型,然后除以 count,得到一个类型为 double 的值
  • 类型转换可以是隐式的,由编译器自动执行,也可以是显式的,通过使用强制类型转换运算符来指定
#include <stdio.h>
int main()
{
   int sum = 17, count = 5;
   double mean;
   mean = (double) sum / count;  // 先将sum转换为double类型
   printf("Value of mean : %f\n", mean );
}

整数提升 ↓

  • 整数提升是指把小于 int 或 unsigned int 的整数类型转换为 int 或 unsigned int 的过程
// 代码部分
#include <stdio.h>
int main()
{
   int  i = 17;
   char c = 'c'; // ascii 值是 99
   int sum;
   sum = i + c;
   printf("Value of sum : %d\n", sum );
}
// 运行结果
Value of sum : 116
// 说明:sum 是 int 类型的,编译器在执行实际加法运算时,进行了整数提升,把 'c' 的值转换为对应的 ascii 值

算数转换 ↓

  • 常用的算术转换不适用于赋值运算符、逻辑运算符 && 和 ||

常用的算数转换 ↓
在这里插入图片描述

// 代码部分
#include <stdio.h>
int main()
{
   int  i = 17;
   char c = 'c'; /* ascii 值是 99 */
   float sum;
   sum = i + c;
   printf("Value of sum : %f\n", sum );
}

/*
c 首先被转换为整数;
但是由于变量 sum 是 float 型的,所以会应用常用的算术转换;
编译器会把 i 和 c 转换为浮点型,并把它们相加得到一个浮点数;
*/

// 运算结果
Value of sum : 116.000000

|| 错误处理

链接:runoob_错误处理

|| C 递归

链接:runoob_递归

|| 可变参数

链接:runoob_可变参数

| C语言排序

链接:runoob_排序算法

常见算法一览↓

  • 冒泡排序
  • 选择排序
  • 插入排序
  • 希尔排序
  • 归并排序
    • 迭代法
    • 递归法
  • 快速排序
    • 迭代法
    • 递归法

|| C语言实例

链接:runoob_C语言实例

|| 经典100例

链接:runoib_经典100例

| 标准库

|| <stdio.h>

链接:runoob_stdio.h

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值