当前位置:网站首页>C 语言进阶
C 语言进阶
2022-07-01 14:13:00 【A-L-Kun】
文章目录
C 语言进阶
一、 数据类型
1、枚举
枚举是C中的一种基本数据类型,它可以让数据更语言,更易读。
#include <stdio.h>
#include <stdlib.h>
typedef enum
{
MON = 1, TUE, WED, THU, FRI, SAT, SUN
}Day;
/* 也可以这样定义 enum Day {} day; typedef enum Day {} day; enum {} day; */
int main() {
Day day;
day = MON;
printf_s("%d\n", day); // 访问枚举类型数据
for (day = MON; day <= SUN; day++)
{
// 遍历枚举类型数据
printf_s("%d\n", day);
}
system("pause");
return 0;
}
注意:
第一个枚举成员的默认值为整型的 0,后续枚举成员的值在前一个成员上加 1。我们在这个实例中把第一个枚举成员的值定义为 1,第二个就为 2,以此类推。
可以在定义的时候改变枚举的值,后续成员的值在前一个成员的基础上加1
2、 结构体
C 数组允许定义可存储相同类型数据项的变量,结构体是 C 编程中另一种用户自定义的可用的数据类型,它允许您存储不同类型的数据项。
基本使用:
#include <stdio.h>
#include <stdlib.h>
struct Stu
{
char* name; // 名字
unsigned int id; // 学号
unsigned int age; // 年龄
void(*play)(); // 行为
};
void play_(struct Stu* stu) {
printf_s("%s小盆友在玩游戏\n", stu->name); // 通过地址访问成员里面的内容
}
int main() {
struct Stu stu = {
"李华", 01, 18, play_ }; // 创建一个成员
stu.play(stu); // 访问成员里面的行为
system("pause");
return 0;
}
创建结构体的其他方法:
struct Stu { char* name; unsigned int id; unsigned int age; void(*play)(); }stu={ "李华", 01, 18, play_ }; // 创建的同时也创建一个成员 typedef struct Stu { char* name; unsigned int id; unsigned int age; void(*play)(); }stu; typedef struct { char* name; unsigned int id; unsigned int age; void(*play)(); }Stu;
3、 共用体
共用体是一种特殊的数据类型,允许您在相同的内存位置存储不同的数据类型。您可以定义一个带有多成员的共用体,但是任何时候只能有一个成员带有值。共用体提供了一种使用相同的内存位置的有效方式。
共用体的定义和访问方法和结构体类似
#include <stdio.h>
#include <stdlib.h>
union Data
{
int i;
float f;
char str[20];
};
int main() {
union Data data1;
// 同时赋值时,发现有数据损失
data1.i = 10;
data1.f = 20;
printf("%d\n%f\n", data1.i, data1.f);
// 分开赋值时,没有精度的额损失
union Data data;
data.i = 20;
printf("%d\n", data.i);
data.f = 10;
printf("%f\n", data.f);
system("pause");
return 0;
}
现在,Data类型的变量可以存储一个整数、一个浮点数,或者一个字符串。这意味着一个变量(相同的内存位置)可以存储多个多种类型的数据。可以根据需要在一个共用体内使用任何内置的或者用户自定义的数据类型。
共用体占用的内存应足够存储共用体中最大的成员。例如,在上面的实例中,Data 将占用 20 个字节的内存空间,因为在各个成员中,字符串所占用的空间是最大的。
4、 别名
C 语言提供了typedef关键字,您可以使用它来为类型取一个新的名字。下面的实例为单字节数字定义了一个术语 BYTE:
typedef unsigned char BYTE;
typedef unsigned int size_t;
也可以使用 typedef 来为用户自定义的数据类型取一个新的名字
typedef struct
{
char* name;
unsigned int id;
unsigned int age;
void(*play)();
} Stu;
二、 C语言预处理器
1、 概念
C 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理。我们将把 C 预处理器(C Preprocessor)简写为 CPP。
所有的预处理器命令都是以井号(#)开头。它必须是第一个非空字符,为了增强可读性,预处理器指令应从第一列开始。下面列出了所有重要的预处理器指令:
| 指令 | 描述 |
|---|---|
| #define | 定义宏 |
| #include | 包含一个源代码文件 |
| #undef | 取消已定义的宏 |
| #ifdef | 如果宏已经定义,则返回真 |
| #ifndef | 如果宏没有定义,则返回真 |
| #if | 如果给定条件为真,则编译下面代码 |
| #else | #if 的替代方案 |
| #elif | 如果前面的 #if 给定条件不为真,当前条件为真,则编译下面代码 |
| #endif | 结束一个 #if……#else 条件编译块 |
| #error | 当遇到标准错误时,输出错误消息 |
| #pragma | 使用标准化方法,向编译器发布特殊的命令到编译器中 |
实例,定义bool数据类型:
#include <stdlib.h>
#include <stdio.h> // 引入输入输出流的头文件
#ifndef bool
typedef int bool;
#define true 1
#define false 0
#endif
2、 预处理器运算符
宏延续运算符(\)
一个宏通常写在一个单行上。但是如果宏太长,一个单行容纳不下,则使用宏延续运算符(\)。例如:
#define message_for(a, b) \ printf(#a " and " #b ": We love you!\n")字符串常量化运算符(#)
在宏定义中,当需要把一个宏的参数转换为字符串常量时,则使用字符串常量化运算符(#)。在宏中使用的该运算符有一个特定的参数或参数列表。例如:
#include <stdio.h> #define message_for(a, b) \ printf(#a " and " #b ": We love you!\n") int main(void) { message_for(Carole, Debra); return 0; }标记粘贴运算符(##)
宏定义内的标记粘贴运算符(##)会合并两个参数。它允许在宏定义中两个独立的标记被合并为一个标记。例如:
#include <stdio.h> #define tokenpaster(n) printf ("token" #n " = %d", token##n) int main(void) { int token34 = 40; tokenpaster(34); return 0; }
3、参数化的宏
#include <stdlib.h>
#include <stdio.h>
#define MAX(x,y) (x>y?x:y) // 获取最大值的函数
int main() {
int ret = MAX(1, 2);
printf("%d\n", ret);
system("pause");
return 0;
}
三、 文件读写
1、 打开文件
您可以使用 fopen( ) 函数来创建一个新的文件或者打开一个已有的文件,这个调用会初始化类型 FILE 的一个对象,类型 FILE 包含了所有用来控制流的必要的信息。下面是这个函数调用的原型:
FILE *fopen_s(FILE** fp, const char *filename, const char *mode);
| 模式 | 描述 |
|---|---|
| r | 打开一个已有的文本文件,允许读取文件。 |
| w | 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,则该会被截断为零长度,重新写入。 |
| a | 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。 |
| r+ | 打开一个文本文件,允许读写文件。 |
| w+ | 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件。 |
| a+ | 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。 |
如果处理的是二进制文件,则需使用下面的访问模式来取代上面的访问模式:
"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"
2、关闭文件
int fclose(FILE *fp);
3、 写入文件
int fputc( int c, FILE *fp ); // 把字符写入文件中
int fputs( const char *s, FILE *fp ); // 把字符串写入文件中
int fprintf_s(FILE *fp,const char *format, ...) // 也可以使用这个将格式化字符串写入文件中
4、 读取文件
int fgetc(FILE * fp); // 从文档中读取一个字符
char *fgets( char *buf, int n, FILE *fp ); // 从 fp 所指向的输入流中读取 n - 1 个字符。它会把读取的字符串复制到缓冲区 buf,并在最后追加一个 null 字符来终止字符串
int fscanf_s(FILE *fp, const char *format, ...) //函数来从文件中读取字符串,但是在遇到第一个空格和换行符时,它会停止读取
5、 实例
#include <stdio.h>
int main(void)
{
FILE* fp;
fopen_s(&fp, "a.txt", "w"); // 以写入的形式打开文件
fprintf_s(fp, "%d+%d=%d", 1, 2, 3); // 将内容写入文件中
fclose(fp); // 关闭文件
fopen_s(&fp, "a.txt", "r"); // 以只读的形式打开文件
char p[255];
// fgets(p, 255, fp);
fscanf_s(fp, "%s", p, 255); // 主要,要输入最大接收的符号数
printf_s("%s\n", p);
fclose(fp); // 关闭文件
return 0;
}
6、 二进制数据
size_t fread(void *ptr, size_t size_of_elements,
size_t number_of_elements, FILE *a_file); // 输出
size_t fwrite(const void *ptr, size_t size_of_elements,
size_t number_of_elements, FILE *a_file); // 写入
参数说明:
ptr:要将内容读取或写入的指针首地址size_of_elements:允许输入或输出的元素的大小,bitnumber_of_elements:允许输入或输出的元素的个数
#include<stdio.h>
int main()
{
// 文件指针fp
FILE* fp = NULL;
unsigned __int8 a[10];
unsigned __int8 b[10];
int i;
for (i = 0; i < 10; i++)
{
a[i] = 0xff;
}
// 写入二进制文件
// 文件名:"test.bin", 访问方式:"wb"
fopen_s(&fp, "test.bin", "wb");
// 数据块首地址: "&a",元素大小: "sizeof(unsigned __int8)", 元素个数: "10", 文件指针:"pd"
fwrite(&a, sizeof(unsigned __int8), 10, fp);
fclose(fp);
// 读取二进制文件
// 文件名:"test.bin", 访问方式:"rb"
fopen_s(&fp, "test.bin", "rb");
// 数据块首地址: "&b",元素大小: "sizeof(unsigned __int8)", 元素个数: "10", 文件指针:"pd"
fread(&b, sizeof(unsigned __int8), 10, fp);
for (i = 0; i < 10; i++)
{
printf("b[%d] = 0x%x\n", i, b[i]);
}
fclose(fp);
}
边栏推荐
- Force deduction solution summary 241- design priority for operation expression
- 微服务大行其道的今天,Service Mesh是怎样一种存在?
- C language ordering management system
- Fiori applications are shared through the enhancement of adaptation project
- Après avoir été licencié pendant trois mois, l'entrevue s'est effondrée et l'état d'esprit a commencé à s'effondrer.
- Go整合Logrus实现日志打印
- 6年技术迭代,阿里全球化出海&合规的挑战和探索
- Research Report on the development trend and competitive strategy of the global chemical glassware industry
- AnimeSR:可学习的降质算子与新的真实世界动漫VSR数据集
- 【剑指 Offer】55 - II. 平衡二叉树
猜你喜欢

Six years of technology iteration, challenges and exploration of Alibaba's globalization and compliance

sqlilabs less10

Self cultivation of open source programmers who contributed tens of millions of lines of code to shardingsphere and later became CEO

TexStudio使用教程

Kongsong (Xintong Institute) - cloud security capacity building and trend in the digital era

sqlilabs less-11~12

sqlilabs less-8

Realize queue with stack and stack with queue (C language \leetcode\u 232+225)

Admire, Ali female program undercover more than 500 black production groups

Etcd summary mechanism and usage scenarios
随机推荐
[anwangbei 2021] Rev WP
el-form-item 正则验证
Force deduction solution summary 241- design priority for operation expression
Self cultivation of open source programmers who contributed tens of millions of lines of code to shardingsphere and later became CEO
Etcd 概要 机制 和使用场景
建立自己的网站(21)
Yan Rong looks at how to formulate a multi cloud strategy in the era of hybrid cloud
Go integrates logrus to realize log printing
Provincial election + noi Part 10 probability statistics and polynomials
Research Report on the development trend and competitive strategy of the global indexable milling cutter industry
【修复版】仿我爱看电影网站模板/海洋CMS影视系统模板
当主程架构游戏的时候,防止到处调用减少耦合性,怎么开放接口给其他人调用呢?
Interpretation of R & D effectiveness measurement framework
This paper introduces an implementation scheme to enhance the favorite transaction code management tool in SAP GUI
C language course design topic
Liu Dui (fire line safety) - risk discovery in cloudy environment
使用 Lambda 函数URL + CloudFront 实现S3镜像回源
Etcd summary mechanism and usage scenarios
用栈实现队列、用队列实现栈(C语言_leetcode_232+225)
QT学习管理系统