——————————————————————————————
条件编译是为了实现 C 程序跨平台而设计的语法格式
条件编译时使用 #if, #ifdef, #endif 等这样的语法进行判断是否进行编译的
// 一个案例
在 类Unix 操作系统中, 主函数是 main 函数
在 WIndows 操作系统中, 主函数有 main 和 WinMain 两种
if(如果当前是 windows) {
定义 WinMain 函数
} else {
定义 main 函数
}
#ifdef 标记
int WinMain(int argc, char **argv) {
return mainRun(argc, argv);
}
#else
int main(int argc, ...) {
return mainRun(...);
}
#endif
条件编译允许精简代码
如果在编译的时候, 使用条件编译, 如果不满足条件的 代码,
不会编译到可执行文件中
如果采用的是 if else 结构, 那么无论写多少代码, 都会被编译到可执行文件中
条件编译可以排除引入头文件中的重复定义
#import <Foundation/...>
*/
#include <stdio.h>
#include "test.h"
#include "Header1.h"
#include "Header2.h"
#define NUM 10
int main(int argc, const char *argv[]) {
// size_t
int num = 10;
// 执行两批代码
if (num > 0) {
// #if NUM > 0
printf("1111111111111111\n");
printf("2222222222222222\n");
printf("3333333333333333\n");
printf("4444444444444444\n");
printf("5555555555555555\n");
printf("6666666666666666\n");
printf("7777777777777777\n");
printf("8888888888888888\n");
printf("9999999999999999\n");
printf("0000000000000000\n");
} else {
// #else
printf("aaaaaaaaaaaaaaaa\n");
printf("ssssssssssssssss\n");
printf("bbbbbbbbbbbbbbbb\n");
printf("ccccccccccccccc\n");
printf("ddddddddddddddd\n");
printf("wwwwwwwwwwwwwww\n");
printf("fffffffffffffff\n");
printf("eeeeeeeeeeeeeee\n");
printf("gggggggggggggggg\n");
printf("hhhhhhhhhhhhhhhh\n");
}
// #endif
// 在编译的时候, 会将两批代码都编译到可执行文件中
// 如果采用条件编译, 那么不满足的代码就不会被编译到文件中
return 0;
————————变量四个修饰——————————————————————
const
static
extern
auto
register
auto 就是自动变量, 其含义是由系统维护变量的创建与销毁, 局部变量
register 寄存器变量
这两个修饰符只用在局部变量中, 函数中
extern 外部的, 这个关键字只用在函数外, 全局中
一个C语言程序, 编译以后, 所有的全局变量:
1, 共享
2, 私有
对于 共享的全局变量, 只允许在一个文件中赋值,
其他文件中声明这个变量就可以使用这个变量了
赋值的这个地方叫做定义, 其他的地方就是声明
定义变量的时候, 直接使用
类型 变量名 = 值;
声明变量的时候使用
extern 类型 变量名;
static 静态的
1, static 如果用在全局作用域上, 可以用来修饰变量与函数, 表示它使私有的,
只允许在本c文件中使用
2, static 在局部作用域上的使用, 定义在函数中, 函数结束后, 变量不会被销毁
*/
#include <stdio.h>
// int numTest;
int num; // 声明
// void test1();
void func() {
int num = 0;
// 因为函数的内存是"固定", 每次对 num 做++运算的时候访问的刚好是这一段内存
// 添加 static 关键字以后, 这个变量会在程序最开始的时候初始化,
// 每次调用函数的时候进行运算, 直到
// 整个程序结束, 才会释放这个变量的内存
printf("%d\n", num--);
}
——————————————————————————————
const 就是常量
基本类型
int const num;
const int num;
与指针合用
const int *p;
int const *p; *p 不可变, p 可变
int * const p; *p 可变, p 不可变
const int * const p; *p, p 都不可变
*/
———————文件———————————————————————
文件的分类
文件在用户看来就是一个文档
程序员, 是在硬盘中的一块数据区
文件的分类描述了数据的存储规则
1, 文本文本 存储都是ascii码, utf-8码, ... 存 123 => 49 50 51
2, 二进制文件 存储是二进制数据 123 ->
二进制结构存储到文件中
文件操作的相关概念
输入流
输出流
流 -> 类比, 很多东西在一起移动
硬盘存储模型, 一次性读取一个数据片段, 或者一次性写入一个数据片段
以应用程序为中心
输出, 经过应用程序处理后得到的内容
输入, 原始数据加载到应用程序中
流操作
如果将数据读取出来, 就是将数据流从硬盘中取出来, 放到内存里, 供程序使用
如果是将数据写入到硬盘中, 是在内存里先保存一部分数据,
到达一定量以后一次性再写入硬盘
————————————步骤——————————————————
#include <stdio.h>
int main(int argc, const char *argv[]) {
// C 语言使用文件指针来操作文件
// FILE 表示文件指针的类型
// 使用函数 fopen() 来获得文件的种指针
// 语法: fopen("文件名", "文件操作模式")
// 如果获得了文件的指针, 返回指针值
// 如果没有获得, 返回 NULL
// 文件指针的释放, 使用 fclose(文件指针) 来回收文件指针
// FILE *fp = NULL; // fp -> file pointer
// fp = fopen("/Users/apple/Desktop/1.txt", "r");
//
// if(fp == NULL) {
// printf("未获得文件\n");
// } else {
// printf("获得了文件\n");
// }
// fclose(fp);
// 文件操作, 结论: 凡是文件操作的函数, 否是用 f 开头
// int fgetc(fp); // getchar()
FILE *fp = NULL; // fp -> file pointer
fp = fopen("/Users/apple/Desktop/2.txt", "r");
if (fp == NULL)
return 1;
// 打开文件
int ch;
// ch = fgetc(fp);
// ch = fgetc(fp);
// ch = fgetc(fp);
// ch = fgetc(fp);
// ch = fgetc(fp);
// ch = fgetc(fp);
while ((ch = fgetc(fp)) != -1) {
printf("%c", ch);
}
fclose(fp);
return 0;
}
—————————模式—————————————————————
文件打开模式是指以什么样的方式进行文件操作
fopen("文件名", "文件操作模式")
模式:
r 读取 read
如果文件不存在, 返回 NULL
如果文件存在, 打开文件, 并且将"光标"放到文件开头
w 写入 write
如果文件不存在, 创建一个文件
如果文件存在, 则删除文件, 再创建一个
光标总是在文件开始的位置
a 追加 append
如果文件不存在, 创建一个文件, 光标放到文件的开头
如果文件存在, 就打开文件, 光标放到文件结尾
int fgetc(文件指针)
文件的打开模式, 与到底是进行读取还是进行写入, 没有直接关系(猜测)
文件的打开模式决定了如何操作文件, 最好使用指定模式做指定的操作
fputc
除了上述的方式, 还有:
r+ 以读写方式进行打开(打开原文件, 如果文件不存在, 则返回 NULL)
w+ 以读写方式进行打开(打开新文件, 如果原文件存在, 则删除)
a+ 以读写方式进行打开(如果原来文件不存在, 则新建, 如果存在则打开)
*/
#include <stdio.h>
int main(int argc, const char *argv[]) {
FILE *fp = NULL;
fp = fopen("/Users/apple/Desktop/0.txt", "r");
// fp = fopen("/Users/apple/Desktop/0.txt", "w");
// fp = fopen("/Users/apple/Desktop/0.txt", "a");
printf("%s\n", fp == NULL ? "文件不存在" : "文件存在");
// int result = fgetc(fp);
// printf("%d\n", result);
int res = fputc(98, fp);
printf("%d\n", res);
fclose(fp);
return 0;
}
——————————————————————————————
/*
除了上述的方式, 还有:
r+ 以读写方式进行打开(打开原文件, 如果文件不存在, 则返回 NULL)
w+ 以读写方式进行打开(打开新文件, 如果原文件存在, 则删除)
a+ 以读写方式进行打开(如果原来文件不存在, 则新建, 如果存在则打开)
*/
#include <stdio.h>
int main(int argc, const char *argv[]) {
FILE *fp = fopen("/Users/apple/Desktop/1.txt", "r+");
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "w+");
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "a+");
if (fp == NULL) {
printf("不存在\n");
return 0;
}
int res1 = fgetc(fp);
printf("%c\n", res1);
int res2 = fputc(97, fp); // '0'
printf("%d\n", res2);
// int res1 = fgetc(fp);
// printf("%c\n", res1);
// r+, 如果先读后写, 会得到追加的效果, 所以如果同时操作文件的读和写,
// 需要控制文件中的指针的位置
// w+, 会先删除文件, 再创建文件, 所以如果同时操作文件的读和写,
// 需要控制文件中的指针的位置
fclose(fp);
return 0;
}
——————————控制文件指针的位置————————————————————
*
fseek(文件指针, 偏移量, 位置坐标);
位置坐标:
SEEK_SET 文件开头
SEEK_CUR 文件当前位置
SEEK_END 文件结尾
使用 a+ 打开文件, 光标会指向末尾, 就无法读取数据
*/
#include <stdio.h>
int main1(int argc, const char *argv[]) {
FILE *fp = fopen("/Users/apple/Desktop/1.txt", "a+");
// 由于文件都是可以打开的, 因此不在这里做判断了
// fseek(fp, 0, SEEK_SET); // 时光标移到文件的开始
// int res = fgetc(fp);
// printf("%c", res);
// res = fgetc(fp);
// printf("%c", res);
// res = fgetc(fp);
// printf("%c", res);
// res = fgetc(fp);
// printf("%c", res);
// res = fgetc(fp);
// printf("%c", res);
// res = fgetc(fp);
// printf("%c", res);
// res = fgetc(fp);
// printf("%c", res);
// fseek(fp, 1, SEEK_SET);
fseek(fp, -1, SEEK_END); // abcdef
int res = fgetc(fp);
printf("%c", res);
fclose(fp);
return 0;
}
int main(int argc, const char *argv[]) {
// /
// 文件里全是字符a,现在要将a全部替换成A, 那么如何处理
FILE *fp = fopen("/Users/apple/Desktop/1.txt", "r+");
char ch;
while ((ch = fgetc(fp)) != -1) {
// 读取每一个字符字节
if (ch == 'a') {
fseek(fp, -sizeof(char), SEEK_CUR);
fputc('A', fp);
}
}
fclose(fp);
return 0;
}
————————————————————————————
fread() 函数用于读取文件中的数据, 其读取方式是以字节块的形式
int fread(地址, 单位字节大小, 读取的块数, 文件指针);
int fwrite(地址, 单位字节大小, 读取的块数, 文件指针);
*/
#include <stdio.h>
struct Rectangle {
int X;
int Y;
int width;
int height;
};
int main(int argc, const char *argv[]) {
//
// char str[] = "你好, 今天很热!";
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "w");
// fwrite(str, sizeof(str), 1, fp);
// fclose(fp);
// char str[100];
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "r");
//
// long count = fread(str, sizeof(str), 1, fp);
//
// printf("%ld\n", count);
//
// printf("%s\n", str);
//
// fclose(fp);
// struct Rectangle rec = { 100, 100, 200, 100 };
// 100,100,200,100
// fwrite(&rec, sizeof(...), 1, fp);
return 0;
}
—————————————————————————
#include <stdio.h>
#include <string.h>
typedef struct {
char name[10];
char gender;
int age;
} Person;
int main(int argc, const char *argv[]) {
// 1, 读写一个数字
// short num = 97;
//
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "w");
//
// fwrite(&num, sizeof(short), 1, fp);
//
// fclose(fp);
// int num ;
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "r");
// if(fp == NULL) return 0;
// fread(&num, sizeof(int), 1, fp);
// fclose(fp);
// printf("%d\n", num);
// 2, 读写一个数组
// int nums[10] = {1,2,3,4,5,6,7,8,9,0};
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "w");
// fwrite(nums, sizeof(nums), 1, fp);
//
// fclose(fp);
// int nums[10];
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "r");
// fread(nums, sizeof(int), 10, fp);
// fclose(fp);
// 3, 读写一个英文的字符串
// char *str = "abcdefg";
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "w");
// fwrite(str, sizeof(char), strlen(str), fp);
//
// fclose(fp);
// char strs[10]; // char *str
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "r");
// fread(strs, sizeof(char), sizeof(strs), fp);
// fclose(fp);
//
// 4, 读写一个结构体
// Person p = {"张三", 'm', 19};
//
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "w");
//
// fwrite(&p, sizeof(Person), 1, fp);
//
// fclose(fp);
Person p;
FILE *fp = fopen("/Users/apple/Desktop/1.txt", "r");
fread(&p, sizeof(Person), 1, fp);
fclose(fp);
printf("成功\n");
return 0;
}
int main(int argc, const char *argv[]) {
// fgets(字符数组, 个数, 文件流);
// 从文件流 fp 中读取 指定个数 个字符, 构成一个字符数组(字符串);
// fputs(字符串, 文件流)
// 将字符串写入到文件流
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "w");
// fputs("今天天气很好\n123", fp);
// fclose(fp);
// char str[24];
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "r");
// fgets(str, 22, fp); // 中文一个字代表三个字节
// printf("%s\n", str);
//
// fgets(str, 22, fp);
// printf("%s\n", str);
//
// fclose(fp);
// fscanf(文件指针, 格式控制字符串); %s %d%c%c%c%d
// fprintf(文件指针, 格式控制字符串, 值列表)
// FILE *fp = fopen("/Users/apple/Desktop/1.txt", "w");
// fprintf(fp, "%d %c %d = %d\n", 1, '+', 2, 1 + 2);
// fclose(fp);
FILE *fp = fopen("/Users/apple/Desktop/1.txt", "r");
int num1, num2, res;
char ch;
fscanf(fp, "%d %c %d = %d", &num1, &ch, &num2, &res);
fclose(fp);
printf("OK\n");
return 0;
}
————————————————————
文件打开的模式
w a r
w+ a+ r+
t text
b binay
rb 以二进制的形式打开
r 或 rt 以文本的形式打开
wb wt w+t w+b wt+ wb+
*/
#include <stdio.h>
int main(int argc, const char *argv[]) {
int ch = 97;
FILE *fp = fopen("/Users/apple/Desktop/1.txt", "r");
// fputc(ch, fp);
// fflush(fp);
// feof(FILE *) // end of file
// while((ch = fgetc(fp)) != -1) { }
// do {
// ch = fgetc(fp);
//
// printf("%c", ch);
//
// } while(!feof(fp));
// EOF end of file
while ((ch = fgetc(fp)) != EOF) {
printf("%c", ch);
}
fclose(fp);
return 0;
——————————————————————————————
——————————————————————————————
——————————————————————————————
——————————————————————————————
——————————————————————————————