首页 技术 正文
技术 2022年11月21日
0 收藏 749 点赞 2,181 浏览 41447 个字

Day07

笔记

指针和函数:栈 帧:
当函数调用时,系统会在 stack 空间上申请一块内存区域,用来供函数调用,主要存放 形参 和 局部变量(定义在函数内部)。当函数调用结束,这块内存区域自动被释放(消失)。传值和传址:传值:函数调用期间,实参将自己的值,拷贝一份给形参。 传址:函数调用期间,实参将地址值,拷贝一份给形参。 【重点】(地址值 --》 在swap函数栈帧内部,修改了main函数栈帧内部的局部变量值)指针做函数参数:int swap2(int *a, int *b);int swap2(char *a, char *b);调用时,传有效的地址值。数组做函数参数:void BubbleSort(int arr[10]) == void BubbleSort(int arr[]) == void BubbleSort(int *arr) 传递不再是整个数组,而是数组的首地址(一个指针)。所以,当整型数组做函数参数时,我们通常在函数定义中,封装2个参数。一个表数组首地址,一个表元素个数。指针做函数返回值:int *test_func(int a, int b);指针做函数返回值,不能返回【局部变量的地址值】。数组做函数返回值:C语言,不允许!!!! 只能写成指针形式。指针和字符串:1)
char str1[] = {'h', 'i', '\0'};变量,可读可写char str2[] = "hi";变量,可读可写char *str3 = "hi";常量,只读str3变量中,存储的是字符串常量“hi”中首个字符‘h’的地址值。str3[1] = 'H';// 错误!!char *str4 = {'h', 'i', '\0'}; // 错误!!!2)
当字符串(字符数组), 做函数参数时, 不需要提供2个参数。 因为每个字符串都有 '\0'。练习:比较两个字符串: strcmp();实现比较 str1 和 str2, 如果相同返回0, 不同则依次比较ASCII码,str1 > str2 返回1,否则返回-1数组方式:int mystrcmp(char *str1, char *str2)
{
int i = 0;while (str1[i] == str2[i]) // *(str1+i) == *(str2+i)
{
if (str1[i] == '\0')
{
return 0;// 2字符串一样。
}
i++;
}
return str1[i] > str2[i] ? 1 : -1;
}指针方式:int mystrcmp2(char *str1, char *str2)
{
while (*str1 == *str2) // *(str1+i) == *(str2+i)
{
if (*str1 == '\0')
{
return 0;// 2字符串一样。
}
str1++;
str2++;
}
return *str1 > *str2 ? 1 : -1;
}练习:字符串拷贝://数组版本
void mystrcpy(char *src, char *dst)
{
int i = 0;
while (src[i] != 0) // src[i] == *(src+i)
{
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}//指针版
void mystrcpy2(char *src, char *dst)
{
while (*src != '\0') // src[i] == *(src+i)
{
*dst = *src;
src++;
dst++;
}
*dst = '\0';
}练习:在字符串中查找字符出现的位置:char *myStrch(char *str, char ch)
{
while (*str)
{
if (*str == ch)
{
return str;
}
str++;
}
return NULL;
}
// hellowrld --- 'o'
char *myStrch2(char *str, char ch)
{
int i = 0;
while (str[i])
{
if (str[i] == ch)
{
return &str[i];
}
i++;
}
return NULL;
}练 习:字符串去空格。void str_no_space(char *src, char *dst)
{
int i = 0; // 遍历字符串src
int j = 0; // 记录dst存储位置
while (src[i] != 0)
{
if (src[i] != ' ')
{
dst[j] = src[i];
j++;
}
i++;
}
dst[j] = '\0';
}
// 指针版
void str_no_space2(char *src, char *dst)
{
while (*src != 0)
{
if (*src != ' ')
{
*dst = *src;
dst++;
}
src++;
}
*dst = '\0';
}带参数的main函数:无参main函数: int main(void) == int main()带参数的main函数: int main(int argc, char *argv[]) == int main(int argc, char **argv)参1:表示给main函数传递的参数的总个数。参2:是一个数组!数组的每一个元素都是字符串 char * 测试1:
命令行中的中,使用gcc编译生成 可执行文件,如: test.exetest.exe abc xyz zhangsan nichousha -->argc --- 5
test.exe -- argv[0]
abc -- argv[1]
xyz -- argv[2]
zhangsan -- argv[3]
nichousha -- argv[4]测试2:在VS中。项目名称上 --》右键--》属性--》调试--》命令行参数 --》将 test.exe abc xyz zhangsan nichousha 写入。-->argc --- 5
test.exe -- argv[0]
abc -- argv[1]
xyz -- argv[2]
zhangsan -- argv[3]
nichousha -- argv[4]str 中 substr 出现次数:strstr函数: 在 str中,找substr出现的位置。char *strstr(char *str, char *substr) -- #include <string.h>参1: 原串参2: 子串返回值: 子串在原串中的位置。(地址值); 如果没有: NULL实 现:
int str_times(char *str, char *substr)
{
int count = 0;
char *p = strstr(str, substr); // "llollollo"while (p != NULL)
{
count++;
p += strlen(substr);// p = p+strlen(substr) --> "llollo"
p = strstr(p, substr);// 返回: "llo"
}
return count;
}求非空字符串元素个数:字符串逆置: str_inverse判断字符串是回文:字符串处理函数:字符串拷贝:字符串拼接:字符串比较:字符串格式化输入、输出:sprintf():sscanf():字符串查找字符、子串:strchr()strrchr()strstr()字符串分割:strtok()atoi/atof/atol:

Code

  • 01-传值和传址.c
int swap(int, int);  // 函数声明
int swap2(int *, int *);int main0101(void)
{
int m = 23;
int n = 57;printf("--before-- m = %d, n = %d\n", m, n);
// 函数调用
//swap(m, n); // m/n 实参swap2(&m, &n);printf("--after-- m = %d, n = %d\n", m, n);system("pause");
return EXIT_SUCCESS;
}int swap2(int *a, int *b)// 形参a、b, 需传地址值
{
int tmp = 0;
tmp = *a;
*a = *b;
*b = tmp;
return 0;
}// 函数定义
int swap(int a, int b)// a/b 形参
{
int tmp = 0;tmp = a;
a = b;
b = tmp;return 0;
}
  • 02-数组做函数参数.c
//void BubbleSort(int arr[])  // void BubbleSort(int *arr)void BubbleSort(int *arr, int n)
{
for (int i = 0; i < n - 1; i++)
{
for (int j = 0; j < n - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}int main0202(void)
{
int arr[] = {5, 89, 3, 22, 40, 31, 9, 22, 67, 28, 45, 78};printf("main: sizeof(arr) = %d\n", sizeof(arr));int n = sizeof(arr) / sizeof(arr[0]);BubbleSort(arr, n);for (size_t i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
printf("\n");system("pause");
return EXIT_SUCCESS;
}
  • 03-数组做函数参数测试.c
void test_func(int arr[])
{
printf("size 2 = %u\n", sizeof(arr)); // 整个数组大小printf("%d\n", arr[0]);
}int main0301(void)
{
int arr[] = { 4, 5, 5, 6, 7 };printf("size 1 = %u\n", sizeof(arr)); // 整个数组大小test_func(arr);system("pause");
return EXIT_SUCCESS;
}
  • 04-指针做函数返回值.c
int m = 100;   // 全局变量 对应空间消失 ==> 程序结束。int *test_func2(int a, int b)
{
int p = 1234; // 局部变量
//return &m;return &p;
}int main0401(void)
{
int *ret = NULL; // NULL == 0ret = test_func2(10, 20);printf("ret = %d\n", *ret);system("pause");
return EXIT_SUCCESS;
}
  • 05-指针和字符串.c
int main(void)
{
char str1[] = "hello";// {'h',, 'e', 'l', 'l', 'o', '\0'}
char m[] = "hello";char *str2 = "hello";// "hello" 是一个字符串常量, 不能修改。
char *n = "hello";str1[0] = 'R';
str2[0] = 'R';printf("str1 = %p\n", str1);
printf("m = %p\n", m);printf("str2 = %p\n", str2);
printf("n = %p\n", n);system("pause");
return EXIT_SUCCESS;
}
  • 06-字符串比较.c
// str1 和 str2  == -->0  str1 > str2 --> 1, str1<str2 --> -1
int mystrcmp(char *str1, char *str2)
{
int i = 0;while (str1[i] == str2[i]) // *(str1+i) == *(str2+i)
{
if (str1[i] == '\0')
{
return 0;// 2字符串一样。
}
i++;
}
return str1[i] > str2[i] ? 1 : -1;
}int mystrcmp2(char *str1, char *str2)
{
while (*str1 == *str2) // *(str1+i) == *(str2+i)
{
if (*str1 == '\0')
{
return 0;// 2字符串一样。
}
str1++;
str2++;
}
return *str1 > *str2 ? 1 : -1;
}int main0601(void)
{
char *str1 = "helloz";
char *str2 = "helloz";//int ret = mystrcmp(str1, str2);
int ret = mystrcmp2(str1, str2);if (ret == 0)
printf("相同\n");
else if (ret == 1)
printf("str1 > str2\n");
else if (ret == -1)
printf("str1 < str2\n");
else
printf("异常\n");system("pause");
return EXIT_SUCCESS;
}
  • 07-字符串拷贝.c
// src: 源  dst: 目标
//数组版本
void mystrcpy(char *src, char *dst)
{
int i = 0;
while (src[i] != 0) // src[i] == *(src+i)
{
dst[i] = src[i];
i++;
}
dst[i] = '\0';
}
//指针版
void mystrcpy2(char *src, char *dst)
{
while (*src != '\0') // src[i] == *(src+i)
{
*dst = *src;
src++;
dst++;
}
*dst = '\0';
}int main0701(void)
{
char *src = "helloworldfuoie11ll";char dst[100];mystrcpy2(src, dst);printf("dst = %s\n", dst);system("pause");
return EXIT_SUCCESS;
}
  • 08-在字符串中找字符.c
// hellowrld --- 'm'
char *myStrch(char *str, char ch)
{
while (*str)
{
if (*str == ch)
{
return str;
}
str++;
}
return NULL;
}// hellowrld --- 'o'
char *myStrch2(char *str, char ch)
{
int i = 0;
while (str[i])
{
if (str[i] == ch)
{
return &str[i];
}
i++;
}
return NULL;
}int main0801(void)
{
char str[] = "hello world";
char ch = ' ';char *ret = NULL; ret = myStrch2(str, ch);printf("ret = %s\n", ret);system("pause");
return EXIT_SUCCESS;
}
  • 09-字符串去空格.c
// src : 有空格字符串, dst:没有空格的字符串
void str_no_space(char *src, char *dst)
{
int i = 0; // 遍历字符串src
int j = 0; // 记录dst存储位置
while (src[i] != 0)
{
if (src[i] != ' ')
{
dst[j] = src[i];
j++;
}
i++;
}
dst[j] = '\0';
}
// 指针版
void str_no_space2(char *src, char *dst)
{
while (*src != 0)
{
if (*src != ' ')
{
*dst = *src;
dst++;
}
src++;
}
*dst = '\0';
}int main0901(void)
{
char str[] = "ni chou sha chou ni za di";
char dst[100] = {0};str_no_space2(str, dst);printf("dst = %s\n", dst);system("pause");
return EXIT_SUCCESS;
}
  • 10-带参数的main.c
int main1001(int argc, char *argv[])
{
int i;for (i = 0; i < argc; i++)
{
printf("argv[%d] = %s\n", i, argv[i]);
}system("pause");
return EXIT_SUCCESS;
}
  • 11-字符串中找子串.c
//strstr函数测试
int main1101(void)
{
char *ret = strstr("hellollollo", "llo");printf("ret = %s\n", ret);system("pause");
return EXIT_SUCCESS;
}int str_times(char *str, char *substr)
{
int count = 0;
char *p = strstr(str, substr); // "llollollo"while (p != NULL)
{
count++;
p += strlen(substr);// p = p+strlen(substr) --> "llollo"
p = strstr(p, substr);// 返回: "llo"
}
return count;
}
// 统计字符串中,子串出现的次数。
int main1102(void)
{
char str[] = "helloabclloxyzllo";
char substr[] = "llo";int ret = str_times(str, substr);printf("出现%d次\n", ret);system("pause");
return EXIT_SUCCESS;
}

Day08

笔记

求非空字符串元素个数:“ni chou sha chou ni za di”  字符串逆置: str_inversehello -- olleh void str_inserse(char *str)
{
char *start = str;// 记录首元素地址
char *end = str + strlen(str) - 1;// 记录最后一个元素地址。while (start < end)// 首元素地址是否 < 最后一个元素地址
{
char tmp = *start;// 三杯水 char 元素交换
*start = *end;
*end = tmp;
start++;// 首元素对应指针后移
end--;// 尾元素对应指针前移
}
}判断字符串是回文:int str_abcbb(char *str)
{
char *start = str;// 记录首元素地址
char *end = str + strlen(str) - 1;// 记录最后一个元素地址。while (start < end)// 首元素地址是否 < 最后一个元素地址
{
if (*start != *end)// 判断字符是否一致。
{
return 0; // 0 表示非 回文
}
start++;
end--;
}
return 1;// 1 表示 回文
}字符串处理函数: #include <string.h>字符串拷贝: strcpy: 将 src 的内容,拷贝给 dest。 返回 dest。 保证dest空间足够大。【不安全】char *strcpy(char *dest, const char *src);函数调用结束 返回值和 dest参数结果一致。strncpy:将 src 的内容,拷贝给 dest。只拷贝 n 个字节。 通常 n 与dest对应的空间一致。 默认 不添加 ‘\0’char *strncpy(char *dest, const char *src, size_t n);特性: n > src: 只拷贝 src 的大小 n < src: 只拷贝 n 字节大小。 不添加 ‘\0’字符串拼接:strcat:将 src 的内容,拼接到 dest 后。 返回拼接后的字符串。保证 dest 空间足够大。char *strcat(char *dest, const char *src);strncat:将 src 的前 n 个字符,拼接到 dest 后。 形成一个新的字符串。保证 dest 空间足够大。char *strncat(char *dest, const char *src, size_t n);函数调用结束 返回值和 dest 参数结果一致。字符串比较:不能使用 > < >= <= == != strcmp:比较s1和s2两个字符串,如果相等 返回0.如果不相等,进一步表 s1 和 s2 对应位 ASCII码值。s1 > s2 返回1s1 < s2 返回-1int strcmp(const char *s1, const char *s2);strncmp:int strncmp(const char *s1, const char *s2, size_t n);比较s1和s2两个字符串的前n个字符,如果相等 返回0。如果不相等,进一步表 s1 和 s2 对应位 ASCII码值。(不比字符串ASCII码的和)s1 > s2 返回1s1 < s2 返回-1字符串格式化输入、输出:sprintf(): s -- stringint sprintf(char *str, const char *format, ...);对应printf,将原来写到屏幕的“格式化字符串”,写到 参数1 str中。printf("%d+%d=%d\n", 10, 24, 10+24);---》
char str[100];sprintf(str, "%d+%d=%d\n", 10, 24, 10+24); 格式串写入str数组中。sscanf():int sscanf(const char *str, const char *format, ...);对应scanf, 将原来从屏幕获取的“格式化字符串”, 从 参数1 str中 获取。scanf("%d+%d=%d", &a, &b, &c);---》char str[]= "10+24=45";sscanf(str, "%d+%d=%d", &a, &b, &c); a --> 10, b --> 24, c --> 45字符串查找字符、子串:strchr():在字符串str中 找一个字符出现的位置。 返回字符在字符串中的地址。char *strchr(const char *s, int c);printf("%s\n" strchr("hehehahahoho", 'a')); --> "ahahoho"strrchr():自右向左,在字符串str中 找一个字符出现的位置。 返回字符在字符串中的地址。char *strrchr(const char *s, int c);printf("%s\n" strrchr("hehehahahoho", 'a')); --> "ahoho"strstr():在字符串str中,找子串substr第一次出现的位置。返回地址。char *strstr(const char *str, const char *substr);在字符串中找子串的位置。 printf("%s\n" strrchr("hehehahahoho", "ho")); --> "hoho"printf("%s\n" strrchr("hehehahahoho", "xixi")); --> NULLscanf("%s", str);scanf("%[^\n]", str);字符串分割:strtok(): 按照既定的分割符,来拆分字符串。“www.baidu.com” --> "www\0baidu.com"char *strtok(char *str, const char *delim);参1: 待拆分字符串参2: 分割符组成的“分割串”返回:字符串拆分后的首地址。 “拆分”:将分割字符用 '\0'替换。特性:
1)strtok拆分字符串是直接在 原串 上操作,所以要求参1必须,可读可写(char *str = "www.baidu.com" 不行!!!)2)第一次拆分,参1 传待拆分的原串。第1+ 次拆分时,参1传 NULL.练习: 拆分 ".itcast.cn$This is a strtok$test"char str[] = "www.itcast.cn$This is a strtok$test";char *p = strtok(str, "$ .");while (p != NULL)
{
p = strtok(NULL, " .$");
printf("p = %s\n", p);
}atoi/atof/atol:使用这类函数进行转换,要求,原串必须是可转换的字符串。错误使用:"abc123" --> 0;"12abc345" ---> 12; "123xyz" -->123atoi:字符串 转 整数。int atoi(const char *nptr);atof:字符串 转 浮点数atol:字符串 转 长整数----------------------------------------------------------------------------------------------局部变量:概念:定义在函数 内 部的变量。作用域:从定义位置开始,到包裹该变量的第一个右大括号结束。全局变量:概念:定义在函数 外 部的变量。作用域:从定义位置开始,默认到本文件内部。 其他文件如果想使用,可以通过声明方式将作用域导出。static全局变量:定义语法: 在全局变量定义之前添加 static 关键字。static int a = 10;作用域:被限制在本文件内部,不允许通过声明导出到其他文件。static局部变量:定义语法: 在局部变量定义之前添加 static 关键字。特性: 静态局部变量只定义一次。在全局位置。 通常用来做计数器。作用域:从定义位置开始,到包裹该变量的第一个右大括号结束。全局函数: 函数定义语法: 函数原型 + 函数体static函数:定义语法:static + 函数原型 + 函数体static 函数 只能在 本文件内部使用。 其他文件即使声明也无效。生命周期:局部变量:从变量定义开始,函数调用完成。 --- 函数内部。全局变量:程序启动开始,程序终止结束。 --- 程序执行期间。static局部变量:程序启动开始,程序终止结束。 --- 程序执行期间。static全局变量:程序启动开始,程序终止结束。 --- 程序执行期间。全局函数:程序启动开始,程序终止结束。 --- 程序执行期间。static函数:程序启动开始,程序终止结束。 --- 程序执行期间。内存4区模型:代码段:.text段。 程序源代码(二进制形式)。数据段:只读数据段 .rodata段。初始化数据段 .data段。 未初始化数据段 .bss 段。stack:栈。 在其之上开辟 栈帧。windows 1M --- 10MLinux: 8M --- 16Mheap:堆。 给用户自定义数据提供空间。 约 1.3G+开辟释放 heap 空间:void *malloc(size_t size); 申请 size 大小的空间返回实际申请到的内存空间首地址。 【我们通常拿来当数组用】void free(void *ptr);释放申请的空间参数: malloc返回的地址值。使用 heap 空间:空间时连续。 当成数组使用。free后的空间,不会立即失效。 通常将free后的 地址置为NULL。free 地址必须 是 malloc申请地址。否则出错。如果malloc之后的地址一定会变化,那么使用临时变量tmp 保存。二级指针对应的 heap空间:申请外层指针: char **p = (char **)malloc(sizeof(char *) * 5);申请内层指针: for(i = 0; i < 5; i++)
{
p[i] = (char *)malloc(sizeof(char) *10);
}使用: 不能修改 p 的值。 for(i = 0; i < 5; i++)
{
strcpy(p[i], "helloheap");
}释放内层: for(i = 0; i < 5; i++)
{
free(p[i]);
}释放外层:free(p);栈的存储特性:局部变量:形参:内存操作函数:memset:memmove:memcmp:内存常见问题:1) 申请 0 字节空间2)free空指针3)越界访问4)free ++后的地址5)子函数malloc空间,main中用

Code

  • 01-非空字符串元素个数.c
int no_space_str(char *str)
{
int count = 0;char *p = str;while (*p)
{
if (*p != ' ')
{
count++;
}
p++;
}
return count;
}int main0101(void)
{
char str[] = "ni chou sha";int ret = no_space_str(str);printf("%d\n", ret);system("pause");
return EXIT_SUCCESS;
}
  • 02-字符串逆序.c
// o e l l h// 字符串逆序
void str_inserse(char *str)
{
//int i, j; // str[i] *(str+i)
char *start = str;// 记录首元素地址
char *end = str + strlen(str) - 1;// 记录最后一个元素地址。while (start < end)// 首元素地址是否 < 最后一个元素地址
{
char tmp = *start;// 三杯水 char 元素交换
*start = *end;
*end = tmp;
start++;// 首元素对应指针后移
end--;// 尾元素对应指针前移
}
}
// 判断回文字符串 abcddpba
int str_abcbb(char *str)
{
char *start = str;// 记录首元素地址
char *end = str + strlen(str) - 1;// 记录最后一个元素地址。while (start < end)// 首元素地址是否 < 最后一个元素地址
{
if (*start != *end)// 判断字符是否一致。
{
return 0; // 0 表示非 回文
}
start++;
end--;
}
return 1;// 1 表示 回文
}int main0201(void)
{
char str[] = "this is a test";str_inserse(str);printf("str=%s\n ---------------------\n", str);char s2[] = "abcmncba";int ret = str_abcbb(s2);if (ret == 0)
printf("不是回文\n");
else if (ret == 1)
printf("是回文\n");system("pause");
return EXIT_SUCCESS;
}
  • 03-字符串拷贝strcpy和strncpy.c
// strcpy
int main0301(void)
{
char src[] = "abc efg zhansan wangwu ";
char dest[10] = {0};char *p = strcpy(dest, src); ;// 字符串src 拷贝给destprintf("p= %s\n", p);
printf("dest = %s\n", dest);system("pause");
return EXIT_SUCCESS;
}
// strncpy
int main0302(void)
{
char src[] = "hello world";
char dest[100] = { 0 };char *p = strncpy(dest, src, 100); ;// 字符串src 拷贝给dest
for (size_t i = 0; i < 10; i++)
{
printf("%c\n", p[i]);
}printf("p= %s\n", p);
printf("dest = %s\n", dest);system("pause");
return EXIT_SUCCESS;
}
  • 04-字符串拼接 strcat和strncat.c
int main0401(void)
{
char src[] = "world";
char dest[] = "hello";char *p = strcat(dest, src);printf("p = %s\n", p);
printf("dest = %s\n", dest);system("pause");
return EXIT_SUCCESS;
}int main0402(void)
{
char src[] = "world";
char dest[6] = "hello";char *p = strncat(dest, src, 3);printf("p = %s\n", p);
printf("dest = %s\n", dest);printf("%d\n", strlen(dest));system("pause");
return EXIT_SUCCESS;
}
  • 05-strcmp和strncmp字符串比较.c
int main0501(void)
{
char *str1 = "helloworld";
char *str2 = "helloz";printf("ret = %d\n", strcmp(str1, str2));system("pause");
return EXIT_SUCCESS;
}int main0502(void)
{
char *str1 = "helloworld";
char *str2 = "helloz";printf("ret = %d\n", strncmp(str1, str2, 8));system("pause");
return EXIT_SUCCESS;
}
  • 06-格式化读入和写出 sprintf、sscanf.c
// sprintf
int main0601(void)
{
char buf[100] = {0}; //buffer string str source srcsprintf(buf, "%d%c%d=%d\n", 10, '+', 34, 10+34);puts(buf);system("pause");
return EXIT_SUCCESS;
}// sscanf
int main0602(void)
{
char buf[100] = { 0 }; //buffer string str source srcint a, b, c;char str[] = "13+56=89";sscanf(str, "%d+%d=%d", &a, &b, &c);printf("a = %d\n", a);
printf("b = %d\n", b);
printf("c = %d\n", c);system("pause");
return EXIT_SUCCESS;
}
  • 07-字符串分割strtok.c
int main0701(void)
{
char str[] = "www.itcast.cn.com.net"; // www itcast cnchar *p = strtok(str, "."); // 第一次拆分,参1 传 待拆分的原串。while (p != NULL)
{
p = strtok(NULL, "."); // 第1+ 次拆分是,参1传 NULL.printf("%s\n", p);
}
system("pause");
return EXIT_SUCCESS;
}int main0702(void)
{
char str[] = "www.itcast.cn$This is a strtok$test";char *p = strtok(str, "$ .");while (p != NULL)
{
p = strtok(NULL, ". $");
printf("p = %s\n", p);
}system("pause");
return EXIT_SUCCESS;
}
  • 08-atoi_atof_atol.c
static int a = 1034673;void test1(void)
{
static int b = 0;printf("b = %d\n", b++);
}int main0801(void)
{
char str[] = "abc345";
int num = atoi(str);
printf("num = %d\n", num);char str1[] = " -10";
int num1 = atoi(str1);
printf("num1 = %d\n", num1);char str2[] = "0.123f";
double num2 = atof(str2);
printf("num2 = %.2lf\n", num2);char str3[] = "123L";
long num3 = atol(str3);
printf("num3 = %ld\n", num3);system("pause");
return EXIT_SUCCESS;
}
  • 09-局部变量.c
void test1(void);  // 全局函数声明int m = 4456;int main0901(void)
{
int i = 10903;for (size_t j = 0; j < 10; j++)
{
printf("j = %d\n", j);
//test1();
}
printf("i 2 = %d\n", i);system("pause");
return EXIT_SUCCESS;
}
  • 10-申请堆空间.c
int main1001(void)
{
//int arr[1000000] = {10, 20, 40};
int *p = (int *)malloc(sizeof(int) * 10);
//char *str = (char *)malloc(sizeof(char)*10);
if (p == NULL)
{
printf("malloc error\n");
return -1;
}
char *tmp = p; // 记录malloc返回的地址值。用于free// 写数据到 malloc 空间。
for (size_t i = 0; i < 10; i++)
{
p[i] = i + 10;
}
// 读出malloc空间中的数据
//for (size_t i = 0; i < 10; i++)
//{
//printf("%d ", *(p+i));
//}
for (size_t i = 0; i < 10; i++)
{
printf("%d ", *p);
p++;
}// 释放申请的内存。
free(tmp);
p = NULL;system("pause");
return EXIT_SUCCESS;
}
  • 11-二级指针malloc空间.c
int main(void)
{
int **p = malloc(sizeof(int *) * 3);// int **p ==> int *p[10]; ==> [ int *, int *, int * ]for (size_t i = 0; i < 3; i++)
{
p[i] = malloc(sizeof(int) * 5);
}// 使用空间 -- 写
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 5; j++)
{
p[i][j] = i + j;
}
}// 使用空间 -- 读
for (size_t i = 0; i < 3; i++)
{
for (size_t j = 0; j < 5; j++)
{
printf("%d ", *(*(p+i)+j)); // p[i][j] == *(p+i)[j] == *(*(p+i)+j)
}
printf("\n");
}// 释放空间时,应先释放内层空间。
for (size_t i = 0; i < 3; i++)
{
free(p[i]); //*(p+i)
p[i] = NULL;
}
// 释放外层空间
free(p);
p = NULL;system("pause");
return EXIT_SUCCESS;
}

Day09

Code

  • 01-结构体定义及初始化.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>struct student {
int age;
char name[10];
int num;
}obj1, obj2;struct {
int age;
char name[10];
int num;
}obj, *obj4, obj5 = { 100, "abc", 666 };int main0102(void)
{
obj4 = &obj5;
printf("%x\n", obj5.name[0]);(*obj4).age = 200;//obj4->age = 200;
strcpy((*obj4).name,"200");
(*obj4).num = 200;printf("age=%d, name=%s, num=%d\n", obj4->age, obj4->name, obj4->num);printf("age=%d, |%s|, num=%d\n", (&obj5)->age, (&obj5)->name, (&obj5)->num);system("pause");
return EXIT_SUCCESS;
}int main0101(void)
{
struct student stu = { 18, "afei", 97 };
struct student stu2;stu2.age = 17;
strcpy(stu2.name, "andy");//stu2.name = "andy";
stu2.num = 99;printf("age = %d, name=%s, num= %d\n", stu2.age, stu2.name, stu2.num);
printf("age = %d, name=%s, num= %d\n", stu.age, stu.name, stu.num);system("pause");
return EXIT_SUCCESS;
}
  • 02-结构体数组.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>struct student {
int age;
char name[10];
int num;
};int main02(void)
{
struct student arr[5] = { 10, "andy", 10 ,11, "lucy", 11 ,12, "lily", 12 ,13, "mike", 13 ,14, "marry", 14 };int n = sizeof(arr) / sizeof(arr[0]);
int sum = 0;for (size_t i = 0; i < n; i++)
{
sum += arr[i].age;
}
printf("avg age = %d\n", sum / n);system("pause");
return EXIT_SUCCESS;
}int main0201(void)
{
struct student arr[5] = {
{ 10, "andy", 10 },
{ 11, "lucy", 11 },
{ 12, "lily", 12 },
{ 13, "mike", 13 },
{ 14, "marry", 14 }
};int n = sizeof(arr) / sizeof(arr[0]);
for (size_t i = 0; i < n; i++)
{
printf("age=%d, name=%s, num=%d\n", arr[i].age, arr[i].name, arr[i].num);
}
printf("\n");system("pause");
return EXIT_SUCCESS;
}int main0203(void)
{
struct student arr2[5] = {
10, "andy", 10 ,
11, "lucy", 11 ,
12, "lily", 12 ,
13, "mike", 13 ,
14, "marry", 14
};struct student arr[5] = {10, "andy", 10 ,11, "lucy", 11 ,12, "lily", 12 ,13, "mike", 13 ,14, "marry", 14};int n = sizeof(arr) / sizeof(arr[0]);for (size_t i = 0; i < n; i++)
{
printf("age=%d, name=%s, num=%d\n", arr[i].age, arr[i].name, arr[i].num);
}
printf("\n");system("pause");
return EXIT_SUCCESS;
}int main0202(void)
{
struct student arr[5];arr[0].age = 19;
strcpy(arr[0].name, "1111");
arr[0].num = 19;(*(arr+1)).age = 191;
strcpy((*(arr + 1)).name, "2222");
(*(arr + 1)).num = 192;(arr + 2)->age = 193;
strcpy((arr + 2)->name, "333");
(arr + 2)->num = 192;struct student *p = arr;(*(p + 3)).age = 194;
strcpy((*(p + 3)).name, "444");
(*(p + 3)).num = 192;(p + 4)->age = 196;
strcpy((p + 4)->name, "444");
(p + 4)->num = 192;int n = sizeof(arr) / sizeof(arr[0]);for (size_t i = 0; i < n; i++)
{
printf("age=%d, name=%s, num=%d\n", arr[i].age, arr[i].name, arr[i].num);
}
printf("\n");system("pause");
return EXIT_SUCCESS;
}
  • 03-结构体嵌套.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>struct person {
int age;
char name[10];
};struct student {
struct person man;
int score;
};int main0302(void)
{
struct student stu = { 18, 21, "BBB" };printf("age = %d\n", (&stu)->man.age);
printf("name = %s\n", (&stu)->man.name);
printf("score = %d\n", (&stu)->score);system("pause");
return EXIT_SUCCESS;
}int main0301(void)
{
struct student stu;stu.man.age = 16;
strcpy(stu.man.name, "zhangsan");
stu.score = 61;printf("age = %d\n", (&stu)->man.age);
printf("name = %s\n", (&stu)->man.name);
printf("score = %d\n", (&stu)->score);struct student *p = &stu;p->man.age = 18;strcpy(p->man.name, "AAA");
p->score = 100;printf("age = %d\n", (*p).man.age);
printf("name = %s\n", (&(p->man))->name);
printf("score = %d\n", p->score);system("pause");
return EXIT_SUCCESS;
}
  • 04-结构体做函数参数.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>struct student
{
int age;
char name[10];
int score;
short num;
};void func(struct student stu)
{
printf("func stu: age = %d, name= %s\n", stu.age, stu.name);
printf("func stu: score = %d, num= %d\n", stu.score, stu.num);stu.age = 100;
strcpy(stu.name, "super man");
stu.num = 666;
stu.score = 101;printf("2 func stu: age = %d, name= %s\n", stu.age, stu.name);
printf("2 func stu: score = %d, num= %d\n", stu.score, stu.num);
}void func2(struct student *stu)
{
printf("func stu: age = %d, name= %s\n", stu->age, stu->name);
printf("func stu: score = %d, num= %d\n", stu->score, stu->num);stu->age = 100;
strcpy(stu->name, "super man");
stu->num = 666;
stu->score = 101;printf("2 func stu: age = %d, name= %s\n", stu->age, stu->name);
printf("2 func stu: score = %d, num= %d\n", stu->score, stu->num);
}struct student func3(struct student stu)
{
printf("func stu: age = %d, name= %s\n", stu.age, stu.name);
printf("func stu: score = %d, num= %d\n", stu.score, stu.num);stu.age = 100;
strcpy(stu.name, "super man");
stu.num = 666;
stu.score = 101;printf("2 func stu: age = %d, name= %s\n", stu.age, stu.name);
printf("2 func stu: score = %d, num= %d\n", stu.score, stu.num);return stu;
}int main0401(void)
{
struct student stu1 = {15, "ABC", 67, 99};
struct student stu2 = stu1;//func(stu2);// 实参 给 形参 赋值
//func2(&stu2);stu2 = func3(stu2);printf("stu2: age = %d, name= %s\n", stu2.age, stu2.name);
printf("stu2: score = %d, num= %d\n", stu2.score, stu2.num);system("pause");
return EXIT_SUCCESS;
}
  • 05-含有指针成员的结构体.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>struct student {
int age;
char *name; // char name[10]; // 栈
int num;
};void init_struct(struct student **p)
{
*p = malloc(sizeof(struct student));// 先申请外层
if (*p == NULL) {
printf("malloc error");
return ;
}
(*p)->age = 10;
(*p)->name = malloc(sizeof(char)*10);// 再申请内层
strcpy((*p)->name, "hello");
(*p)->num = 100;
}int main0503(void)
{
struct student *p = NULL;
p = malloc(sizeof(struct student));// 先申请外层空间p->age = 100;
p->name = malloc(sizeof(char)*10);// 再申请内层空间
strcpy(p->name, "world");
p->num = 20;printf("age = %d, name=%s, num = %d\n", p->age, p->name, p->num);free(p->name); // 先释放内层
free(p);// 再释放外层system("pause");
return EXIT_SUCCESS;
}int main0502(void)
{
struct student *p = NULL;init_struct(&p);
printf("age = %d, name=%s, num = %d\n", p->age, p->name, p->num);free(p->name); // 先释放内层
free(p);// 再释放外层system("pause");
return EXIT_SUCCESS;
}int main0501(void)
{
struct student stu;
stu.age = 19;stu.name = malloc(sizeof(char) * 10); // 堆strcpy(stu.name, "andy"); // stu.name 是 野指针。stu.num = 10;printf("age = %d, name= %s, num= %d\n", stu.age, stu.name, stu.num);free(stu.name);
stu.name = NULL;system("pause");
return EXIT_SUCCESS;
}
  • 06-结构体数组作为函数参数.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>struct student {
int age;
char *name; // char name[10]; // ջ
int num;
};//void init_arr(struct student stu[5])
//void init_arr(struct student stu[])
void init_arr(struct student *stu, int n)
{
for (size_t i = 0; i < n; i++)
{
stu[i].age = i + 10;
stu[i].name = malloc(10);
strcpy(stu[i].name, "ABC");
stu[i].num = i * 10;
}
}void print_arr(struct student *stu, int n)
{
for (size_t i = 0; i < n; i++)
{
printf("age = %d\n", stu[i].age);
printf("name = %s\n", stu[i].name);
printf("num = %d\n", stu[i].num);
}
}int main0601(void)
{
struct student stu[5];int n = sizeof(stu) / sizeof(stu[0]);init_arr(stu, n);
print_arr(stu, n);for (size_t i = 0; i < n; i++)
{
free(stu[i].name);
}system("pause");
return EXIT_SUCCESS;
}
  • 07-联合体.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>union test {
char a;
short b;
int c;
char str[13];
};int main0701(void)
{
union test t1;t1.c = 0x87654321;printf("&t1 = %p\n", &t1);
printf("&t1.a = %p\n", &(t1.a));
printf("&t1.b = %p\n", &(t1.b));
printf("&t1.c = %p\n", &(t1.c));printf("a = %x\n", t1.a);
printf("b = %x\n", t1.b);
printf("c = %x\n", t1.c);t1.b = 0x3A;printf("----------------\na = %x\n", t1.a);
printf("b = %x\n", t1.b);
printf("c = %x\n", t1.c);printf("sizeof(t1) = %u\n", sizeof(t1));system("pause");
return EXIT_SUCCESS;
}
  • 08-枚举.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>enum color { red, black, blue = 10, yellow, pink, green };int main08(void)
{
int flg = yellow;if (flg == 3)
printf("flg = yellow\n");system("pause");
return EXIT_SUCCESS;
}
  • 09-typedef.c
typedef long long int32;typedef struct student {
int32 a;
int32 b;
int32 c;
int32 d;
int32 e;
int32 f;
}stu_t;// 给 struct student 类型起了一个别名: stu_t;int main09(void)
{
struct student stu;
stu_t s1;s1.a = 10;
s1.b = 20;system("pause");
return EXIT_SUCCESS;
}

Day10

笔记

共用体和联合体:union test {char ch;short sh;int var;
};联合体,内部所有成员变量地址一致。等同于整个联合体的地址。联合体的大小,是内部成员变量中,最大的那个成员变量的大小。(对齐)修改其中任意一个成员变量的值,其他成员变量会随之修改。枚 举:enum color { 枚举常量 };enum color { red, green, blue, black, pink, yellow }; 枚举常量: 是整型常量。不能是浮点数。可以是负值。 默认初值从 0 开始,后续常量较前一个常量 +1. 可以给任意一个常量赋任意初值。后续常量较前一个常量 +1-----------------------读写文件与printf、scanf关联printf -- 屏幕 -- 标准输出scanf -- 键盘 -- 标准输入perror -- 屏幕 -- 标准错误系统文件:标准输入 -- stdin -- 0标准输出 -- stdout -- 1标准错误 -- stderr -- 2应用程序启动时,自动被打开,程序执行结束时,自动被关闭。 ---- 隐式回收。1s = 1000ms 1ms = 1000us1us == 1000ns文件指针和普通指针区别:FILE *fp = NULL;借助文件操作函数来改变 fp 为空、野指针的状况。fopen(); --> 相当于 fp = malloc();操作文件, 使用文件读写函数来完成。 fputc、fgetc、fputs、fgets、fread、fwrite文件分类:设备文件:屏幕、键盘、磁盘、网卡、声卡、显卡、扬声器...磁盘文件:文本文件: ASCII二进制文件:0101 二进制编码文件操作一般步骤:1. 打开文件 fopen() --》 FILE *fp;2. 读写文件 fputc、fgetc、fputs、fgets、fread、fwrite3. 关闭文件 fclose() 打开、关闭文件函数:FILE * fopen(const char * filename, const char * mode);参1:待打开文件的文件名(访问路径)参2:文件打开权限:"r": 只读方式打开文件, 文件不存在,报错。存在,以只读方式打开。"w": 只写方式打开文件, 文件不存在,创建一个空文件。文件如果存在,清空并打开。"w+":读、写方式打开文件,文件不存在,创建一个空文件。文件如果存在,清空并打开。"r+":读、写方式打开文件, 文件不存在,报错。存在,以读写方式打开。"a": 以追加的方式打开文件。"b": 操作的文件是一个二进制文件(Windows)返回值:成功:返回打开文件的文件指针失败:NULLint fclose(FILE * stream);参1:打开文件的fp(fopen的返回值)返回值:成功 :0, 失败: -1;文件访问路径:绝对路径:从系统磁盘的 根盘符开始,找到待访问的文件路径Windows书写方法:1)C:\\Users\\afei\\Desktop\\06-文件分类.avi2)C:/Users/afei/Desktop/06-文件分类.avi --- 也使用于Linux。相对路径:1)如果在VS环境下,编译执行(Ctrl+F5),文件相对路径是指相对于 day10.vcxproj 所在目录位置。2)如果是双击 xxx.exe 文件执行,文件的相对路径是相对于 xxx.exe 所在目录位置。 按字符写文件 fputc:int fputc(int ch, FILE * stream);参1:待写入的 字符参2:打开文件的fp(fopen的返回值)返回值: 成功: 写入文件中的字符对应的ASCII码 失败: -1练习:写26个英文字符到文件中。按字符读文件 fgetcint fgetc(FILE * stream);参1:待读取的文件fp(fopen的返回值)返回值: 成功:读到的字符对应的ASCII码 失败: -1文本文件的结束标记: EOF ---》 -1 feof()函数:int feof(FILE * stream);参1: fopen的返回值返回值: 到达文件结尾--》非0【真】 没到达文件结尾--》0【假】作用:
用来判断到达文件结尾。 既可以判断文本文件。也可以判断 二进制文件。特性:要想使用feof()检测文件结束标记,必须在该函数调用之前,使用读文件函数。feof()调用之前,必须有读文件函数调用。fgets()函数:获取一个字符串, 以\n作为结束标记。自动添加 \0. 空间足够大 读\n, 空间不足舍弃\n, 必须有\0。char * fgets(char * str, int size, FILE * stream);char buf[10]; hello --> hello\n\0返回值: 成功: 读到的字符串 失败: NULLfputs()函数:写出一个字符串,如果字符串中没有\n, 不会写\n。int fputs(const char * str, FILE * stream);返回值: 成功: 0 失败: -1练习: 获取用户键盘输入,写入文件。假定:用户写入“:wq”终止接收用户输入,将之前的数据保存成一个文件。FILE *fp = fopen("test07.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return -1;
}
char buf[4096] = {0};while (1)
{
fgets(buf, 4096, stdin);
if (strcmp(buf, ":wq\n") == 0) // 实际 fgets 读到的是“:wq\n”
{
break;
}
fputs(buf, fp);
}fclose(fp);练习: 文件版四则运算:1. 封装 write_file 函数,将4则运算表达式写入。FILE * fp = fopen("w");fputs("10/4=\n", fp);fputs("10+4=\n", fp);
....fputs("10*4=\n", fp);2. 封装 read_file 函数, 将4则运算表达式读出,拆分,运算,写回。1) 读出:FILE * fp = fopen("r");while (1) {fgets(buf, sizeof(buf), fp);// buf中存储的 4则运算表达式
}2) 拆分:sscanf(buf, "%d%c%c=\n", &a, &ch, &b);// 得到运算数, 运算符3) 根据运算符,得到运算结果switch(ch) {case '+':
a+b;
}4) 拼接 结果到 运算式 上char result[1024];sprintf(reuslt, "%d%c%d=%d\n", a, ch, b, a+b);// reuslt 中包含带有结果的 运算式。5)将 多个带有结果的运算 拼接成一个字符串。char sum_ses[4096];// 存总的字符串 -- "10/2=5\n10*3=30\n4+3=7\n8-6=2\n"strcat(sum_ses,reuslt); // 在while中循环拼接6) 重新打开文件, 清空原有 4则运算表达式fclose(fp);fp = fopen("w");7) 将 拼接成一个字符串。写入到空的文件中fputs(sum_res);10/2=fgets(buf, 4096, 文件fp) --->"10/2=\n" --> 10 / 2 sscanf(buf, "%d%c%d=\n", &a, &c, &b); -> a=10, b=2, c='/'
10*3=
4+3=
8-6=
switch (c) {case '/':a / b;
break;case '+':
a + b;break;....
}fopen("", "w");char result[]; sprintf()/strcat() --> "10/2=5\n10*3=30\n4+3=7\n8-6=2\n" --> fputs(result, fp)
=====>10/2=5
10*3=30
4+3=7
8-6=2

Code

  • 01-联合体和枚举.c
typedef union test {
char ch;
short sh;
int a;
}test_t;int main0101(void)
{
test_t obj;obj.a = 0x87654321;printf("&obj = %p\n", &obj);
printf("&obj.ch = %p\n", &obj.ch);
printf("&obj.sh = %p\n", &obj.sh);
printf("&obj.a = %p\n", &obj.a);printf("sizeof(test_t) = %u\n", sizeof(test_t));printf("a = 0x%x\n", obj.a);
printf("sh = 0x%x\n", obj.sh);
printf("ch = 0x%x\n", obj.ch);obj.ch = 0xFF;printf("a = 0x%x\n", obj.a);
printf("sh = 0x%x\n", obj.sh);
printf("ch = 0x%x\n", obj.ch);system("pause");
return EXIT_SUCCESS;
}enum color { red, green = -5, blue, black, pink = 18, yellow };int main0102(void)
{
int flg = 2;// ......if (flg == blue)
{
printf("blue is 2\n");
}
else
{
printf("blue is not 2, blue = %d\n", blue);
}
printf("yellow = %d\n", yellow);system("pause");
return EXIT_SUCCESS;
}
  • 02-系统文件.c
int main0201(void)
{
//fclose(stdout);printf("hello file\n");system("pause");
return EXIT_SUCCESS;
}
  • 03-文件的打开和关闭.c
int main0301(void)
{
FILE *fp = NULL;fp = fopen("test2.txt", "w");
if (fp == NULL)
{
perror("fopen error"); //printf("fopen error\n"); :xxxxxxx
getchar();
return -1;
}fclose(fp);
printf("------------finish\n");system("pause");
return EXIT_SUCCESS;
}
  • 04-fputc.c
int main0401(void)
{
char *filename = "test04.txt";FILE *fp = fopen(filename, "w");
if (fp == NULL)
{
perror("fopen error");
return -1;
}int ret = fputc('A', fp);printf("ret = %d\n", ret);fclose(fp);
printf("---------------finish\n");system("pause");
return EXIT_SUCCESS;
}int main0402(void)
{
char *filename = "test04.txt";
int ret = 0;FILE *fp = fopen(filename, "w");
if (fp == NULL)
{
perror("fopen error");
return -1;
}
char ch = 'a';while (ch <= 'z')
{
ret = fputc(ch, fp);
if (ret == -1)
{
perror("fputc eror");
return -1;
}
ch++;
}system("pause");
return EXIT_SUCCESS;
}int main0403(void)
{
char *buf = "abcdefghijklmnopqrstuvwxyz";char *filename = "test04.txt";
int ret = 0;FILE *fp = fopen(filename, "w");
if (fp == NULL)
{
perror("fopen error");
return -1;
}
int n = strlen(buf);
for (size_t i = 0; i < n; i++)
{
ret = fputc(buf[i], fp);
if (ret == -1)
{
perror("fputc eror");
return -1;
}
}
fclose(fp);system("pause");
return EXIT_SUCCESS;
}
  • 05-fgetc.c
void write_file()
{
FILE *fp = fopen("05test.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return ;
}fputc('a', fp);
fputc('b', fp);
fputc('c', fp);
fputc('d', fp);fclose(fp);
}void read_file()
{
char ch = 0;FILE *fp = fopen("05test.txt", "r");
if (fp == NULL)
{
perror("fopen error");
return;
}while (1)
{
ch = fgetc(fp);
if (ch == EOF)
{
break;
}
printf("%d\n", ch);
}fclose(fp);
}int main0501(void)
{
//write_file();
read_file();system("pause");
return EXIT_SUCCESS;
}
  • 06-feof函数.c
void read_file06()
{
char ch = 0;FILE *fp = fopen("06test.txt", "r");
if (fp == NULL)
{
perror("fopen error");
return;
}while (1)
{
ch = fgetc(fp);if (feof(fp))
{
break;
}
printf("%d\n", ch);
}fclose(fp);
}void test_feof()
{
FILE *fp = fopen("06test.txt", "r");
if (fp == NULL)
{
perror("fopen error");
return ;
}
while (1)
{
printf("没有到达文件结尾\n");
fgetc(fp);// 一次读一个字符,读到字符直接丢弃。
if (feof(fp))
{
break;
}
}
fclose(fp);
}
void write_file06()
{
FILE *fp = fopen("06test.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return;
}
fputc('a', fp);
fputc('b', fp);
fputc(-1, fp);
fputc('c', fp);
fputc('d', fp);
fputc('\n', fp);fclose(fp);
}int main0601(void)
{
//write_file06();
//read_file06();
test_feof();system("pause");
return EXIT_SUCCESS;
}
  • 07-fgets和fputs.c
int main0701(void)
{
FILE *fp = fopen("test07.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return -1;
}
char buf[4096] = {0};while (1)
{
fgets(buf, 4096, stdin);
if (strcmp(buf, ":wq\n") == 0)
{
break;
}
fputs(buf, fp);
}fclose(fp);system("pause");
return EXIT_SUCCESS;
}
  • 08-文件版4则运算.c
void write_file08()
{
FILE *fp = fopen("test08.txt", "w");
if (fp == NULL)
{
perror("fopen error");
return;
}fputs("10/2=\n", fp);
fputs("10*3=\n", fp);
fputs("4-2=\n", fp);
fputs("10+2=\n", fp);fclose(fp);
}int calc(char ch, int a, int b)
{
switch (ch)
{
case '/':
return a / b;case '+':
return a + b;case '-':
return a - b;case '*':
return a *b;
default:
break;
}
}void read_file08()
{
char buf[4096] = {0};
char result[4096] = {0};char sum_res[4096] = {0};int a, b, ret;
char ch;FILE *fp = fopen("test08.txt", "r");
if (fp == NULL)
{
perror("fopen error");
return;
}while (1)
{
fgets(buf, 4096, fp); //buf = "10/2=\n\0";
if (feof(fp))
{
break;
}
sscanf(buf, "%d%c%d=\n", &a, &ch, &b);// a:10, ch:'/' b: 2sprintf(result, "%d%c%d=%d\n", a, ch, b, calc(ch, a, b)); // 10 / 2 = 5;strcat(sum_res, result);
}
fclose(fp); // 将 只有表达式没有结果的文件关闭。fp = fopen("test08.txt", "w");// 清空 只有表达式没有结果的文件
if (fp == NULL)
{
perror("fopen error");
return;
}
fputs(sum_res, fp);// 将 既有表达式又有结果的字符串写到文件中。fclose(fp);
}int main(void)
{
write_file08();
getchar();
read_file08();system("pause");
return EXIT_SUCCESS;
}

Day11

笔记

printf --- sprintf --- fprintf: 变参函数:参数形参中 有“...”, 最后一个固参通常是格式描述串(包含格式匹配符), 函数的参数个数、类型、顺序由这个固参决定。printf("hello");printf("%s", "hello");printf("ret = %d+%d\n", 10, 5);printf("%d = %d%c%d\n", 10+5, 10, '+', 5);--> 屏幕char buf[1024];   //缓冲区  sprintf(buf, "%d = %d%c%d\n", 10+5, 10, '+', 5);--> buf 中FILE * fp = fopen();fprintf(fp, "%d = %d%c%d\n", 10+5, 10, '+', 5);--> fp 对应的文件中scanf --- sscanf --- fscanfscanf("%d", &m);键盘 --> mchar str[] = "98";sscanf(str, "%d", &m);str --> mFILE * fp = fopen("r");fscanf(fp, "%d", &m);fp指向的文件中 --> mfprintf()函数:   ---> 将数据按指定的格式写进文件中写int fprintf(FILE * stream, const char * format, ...);fscanf()函数:--->  从文件中读取指定格式的数据到内存中读int fscanf(FILE * stream, const char * format, ...);成功:正确匹配的个数。失败: -11) 边界溢出。 存储读取的数据空间。在使用之前清空。2)fscanf函数,每次在调用时都会判断下一次调用是否匹配参数2, 如果不匹配提前结束读文件。(feof(fp) 为真)。练习:文件版排序生成随机数,写入文件。将文件内乱序随机数读出,排好序再写回文件。fgetc --- fputcfgets --- fputsfprintf -- fscanf默认处理文本文件。fwrite()函数:既可处理以文本文件。也处理二进制文件。写出数据到文件中。stu_t stu[4] = { ...... };size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);参1:待写出的数据的地址参2:待写出数据的大小参3:写出的个数-- 参2 x 参3 = 写出数据的总大小。参4:文件返回值: 成功:永远是 参3 的值。 --- 通常将参2 传 1. 将参3传实际写出字节数。 失败:0 fread()函数:从文件fp中读出数据。size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);参1:读取到的数据存储的位置参2:一次读取的字节数参3:读取的次数-- 参2 x 参3 = 读出数据的总大小参4:文件返回值: 成功:参数3.--- 通常将参2 传 1. 将参3传欲读出的字节数。 0:读失败 -- 到达文件结尾 -- feof(fp)为真。 练习:大文件拷贝已知一个任意类型的文件,对该文件复制,产生一个相同的新文件。1. 打开两个文件, 一个“r”, 另一“w”2. 从r中 fread , fwrite到 w 文件中。3. 判断到达文件结尾 终止。  4. 关闭。注意: 在windows下,打开二进制文件(mp3、mp4、avi、jpg...)时需要使用“b”。如:“rb”、“wb”随机位置 读:文件读写指针。在一个文件内只有一个。fseek():int fseek(FILE *stream, long offset, int whence);参1:文件参2:偏移量(矢量: + 向后, - 向前)参3:SEEK_SET:文件开头位置SEEK_CUR:当前位置SEEK_END:文件结尾位置返回值: 成功:0, 失败: -1ftell():获取文件读写指针位置。long ftell(FILE *stream);返回:从文件当前读写位置到起始位置的偏移量。借助 ftell(fp) + fseek(fp, 0, SEEK_END); 来获取文件大小。rewind():回卷文件读写指针。 将读写指针移动到起始位置。void rewind(FILE *stream);Linux和windows文件区别:1)对于二进制文件操作, Windows 使用“b”, Linux下二进制和文本没区别。2)windows下,回车 \r, 换行 \n。 \r\n  , Linux下 回车换行\n3) 对文件指针,先写后读。windows和Linux效果一致。       先读后写。Linux无需修改。windows下需要在写操作之前添加 fseek(fp, 0, SEEK_CUR); 来获取文件读写指针,使之生效。获取文件状态:打开文件,对于系统而言,系统资源消耗较大。int stat(const char *path, struct stat *buf);参1: 访问文件的路径参2: 文件属性结构体返回值: 成功: 0, 失败: -1;删除、重命名文件:int remove(const char *pathname); 删除文件。int rename(const char *oldpath, const char *newpath);  重名文件缓冲区刷新:标准输出-- stdout -- 标准输出缓冲区。   写给屏幕的数据,都是先存缓冲区中,由缓冲区一次性刷新到物理设备(屏幕)标准输入 -- stdin -- 标准输入缓冲区。从键盘读取的数据,直接读到 缓冲区中, 由缓冲区给程序提供数据。预读入、缓输出。行缓冲:printf(); 遇到\n就会将缓冲区中的数据刷新到物理设备上。全缓冲:文件。 缓冲区存满, 数据刷新到物理设备上。无缓冲:perror。 缓冲区中只要有数据,就立即刷新到物理设备。文件关闭时, 缓冲区会被自动刷新。  隐式回收:关闭文件、刷新缓冲区、释放malloc手动刷新缓冲区: 实时刷新。int fflush(FILE *stream);成功:0失败:-1

Code

  • 01-sprintf 和 sscanf.c
void write_file()
{
FILE *fp = fopen("abc.c", "w");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}fprintf(fp, "%d\n", 10);
fprintf(fp, "%d\n", 8);
fprintf(fp, "%d\n", 6);fclose(fp);
}void read_file()
{
int a;FILE *fp = fopen("abc.c", "r");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}fscanf(fp, "%d\n", &a);
printf("%d\n" , a);fscanf(fp, "%d\n", &a);
printf("%d\n", a);fscanf(fp, "%d\n", &a);
printf("%d\n", a);a = 0;
fscanf(fp, "%d\n", &a);
printf("%d\n", a);fclose(fp);
}// fscanf 循环读文件
void read_file2()
{
int a;FILE *fp = fopen("abc.c", "r");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
while (1)
{
fscanf(fp, "%d\n", &a); // 读
printf("%d\n", a);
if (feof(fp))// 真-- 文件结尾
break;
}fclose(fp);
}// fgets 循环读文件
void read_file3()
{
char buf[1024];
FILE *fp = fopen("abc.c", "r");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
while (1)
{
memset(buf , 0, 1024);
fgets(buf, 1024, fp);// 读 \n
if (feof(fp))// 真-- 文件结尾
break;
printf("%d\n", buf[0]);
}fclose(fp);
}int main0101(void)
{
//write_file();
read_file3();system("pause");
return EXIT_SUCCESS;
}int main(void)
{
FILE *fp = fopen("test0101.txt", "r");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}int a;
char ch;
char str[10];int ret = fscanf(fp, "%d %c %s", &a, &ch, str);
printf("ret = %d\n", ret);fclose(fp);system("pause");
return EXIT_SUCCESS;
}
  • 02-文件版排序.c
#include <stdlib.h>
#include <math.h>
#include <time.h>void write_rand()
{
FILE *fp = fopen("test02.txt", "w");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}srand(time(NULL)); // 随机数种子for (size_t i = 0; i < 10; i++)
{
fprintf(fp, "%d\n", rand() % 100); // 将生成的随机数写入文件
}fclose(fp);
}void BubbleSort(int * src, int len)
{
for (int i = 0; i < len - 1; i++)
{
for (int j = 0; j < len - 1 - i; j++)
{
if (src[j] > src[j + 1])
{
int temp = src[j];
src[j] = src[j + 1];
src[j + 1] = temp;
}
}
}
}void read_rand02()
{
int arr[10], i = 0;FILE *fp = fopen("test02.txt", "r");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}while (1)
{
fscanf(fp, "%d\n", &arr[i]);// 从文件中读取一个随机数,存入数组arr
i++;
if (feof(fp))// 先存储,后判断,防止最后一个元素丢失
break;
}
BubbleSort(arr, sizeof(arr)/sizeof(arr[0])); // 对读取到的乱序数组排序fclose(fp);// 关闭文件
fp = fopen("test02.txt", "w");// 重新w方式打开文件, 清空原未排序文件。
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
for (size_t i = 0; i < 10; i++)
fprintf(fp, "%d\n", arr[i]);// 写排好序的数组到文件fclose(fp);
}int main0201(void)
{
write_rand();getchar();read_rand02();system("pause");
return EXIT_SUCCESS;
}
  • 03-fwrite 和 fread.c
typedef struct student {
int age;
char name[10];
int num;
} stu_t;void write_struct()
{
stu_t stu[4] = {
18, "afei", 10,
20, "andy", 20,
30, "lily", 30,
16, "james", 40
};FILE *fp = fopen("test03.txt", "w");
if (!fp)
{
perror("fopen error");
return -1;
}int ret = fwrite(&stu[0], 1, sizeof(stu_t) * 4, fp);
if (ret == 0)
{
perror("fwrite error");
return -1;
}printf("ret = %d\n", ret);fclose(fp);
}// 一次读一个元素。
void read_struct()
{
FILE *fp = fopen("test03.txt", "r");
if (!fp)
{
perror("fopen error");
return -1;
}
stu_t s1;int ret = fread(&s1, 1, sizeof(stu_t), fp);
printf("ret = %d\n", ret);printf("age = %d, name=%s, num = %d\n", s1.age, s1.name, s1.num);fclose(fp);
}// 读所有元素
void read_struct2()
{
FILE *fp = fopen("test03.txt", "r");
if (!fp)
{
perror("fopen error");
return -1;
}
stu_t s1[10]; // stu_t *s1 = malloc(sizeof(stu_t) * 1024);
int i = 0;
while (1)
{
int ret = fread(&s1[i], 1, sizeof(stu_t), fp);
//if (ret == 0)// 替代feof()函数来判断读到文件结尾。
if (feof(fp))
{
break;
}
i++;
printf("age = %d, name=%s, num = %d\n", s1[i].age, s1[i].name, s1[i].num);
}
fclose(fp);
}int main0301(void)
{
//write_struct();
read_struct2();system("pause");
return EXIT_SUCCESS;
}
  • 04-大文件拷贝.c
void myfile_cp()
{
FILE *rfp = fopen("C:\\itcast\\08-fread函数.avi", "rb");
FILE *wfp = fopen("C:\\itcast\\mycopy.avi", "wb");char buf[4096] = {0}; // 缓冲区。int ret = 0;while (1)
{
memset(buf, 0, sizeof(buf));
ret = fread(buf, 1, sizeof(buf), rfp);
if (ret == 0)
{
break;
}
printf("ret = %d\n", ret);
fwrite(buf, 1, ret, wfp);
}fclose(wfp);
fclose(rfp);
}int main0401(void)
{
myfile_cp();printf("---------------------finish\n");system("pause");
return EXIT_SUCCESS;
}
  • 05-随机读文件.c
typedef struct student {
int age;
char name[10];
int num;
} stu_t;int main0501(void)
{
stu_t stu[4] = {
18, "afei", 10,
20, "andy", 20,
30, "lily", 30,
16, "james", 40
};
stu_t s1;FILE *fp = fopen("test05.txt", "wb+");
if (!fp) // fp == NULL
{
perror("fopen error");
return -1;
}
int ret = fwrite(&stu[0], 1, sizeof(stu), fp); // 以二进制形式写入,
printf("ret = %d\n", ret);fseek(fp, sizeof(stu_t)*2, SEEK_SET);// 从文件起始位置,向后偏移一个stu结构体ret = fread(&s1, 1, sizeof(s1), fp);
printf("ret = %d\n", ret);printf("1 age= %d, name=%s, num=%d\n", s1.age, s1.name, s1.num);int len = ftell(fp); // 获取文件当前读写指针位置,到文件起始位置的偏移量。printf("len = %d\n", len);rewind(fp);// 将文件读写指针回卷到起始。ret = fread(&s1, 1, sizeof(s1), fp);printf("2 age= %d, name=%s, num=%d\n", s1.age, s1.name, s1.num);// 获取文件大小。
fseek(fp, 0, SEEK_END);// 将文件读写指针放到文件结尾。
len = ftell(fp);
printf("文件大小为:%d\n", len);fclose(fp);system("pause");
return EXIT_SUCCESS;
}int main0502(void)
{
FILE *fp = fopen("test0501.txt", "w+"); // "r+"int ret = fputs("11111", fp);
printf("ret 1 = %d\n", ret);// 0 表示成功。ret = fputs("22222", fp);
printf("ret 2 = %d\n", ret);ret = fputs("33333", fp);
printf("ret 3 = %d\n", ret);char buf[1024] = { 0 };//fseek(fp, 5 * 2, SEEK_SET); // 改变读写指针位置。
rewind(fp); // 起始位置。
char *ptr = fgets(buf, 1024, fp);
if (ptr == NULL)
printf("ptr == NULL \n");printf("fgets ptr = %s\n", ptr);
printf("buf = %s\n", buf);fclose(fp);
system("pause");
return EXIT_SUCCESS;
}#include <stdio.h>
#include <stdlib.h>
#include <string.h>int main0503(int argc, char *argv[])
{
FILE *fp = fopen("test1.txt", "r+");char buf[6] = { 0 };
char *ptr = fgets(buf, 6, fp);printf("buf=%s, ptr=%s\n", ptr, buf);fseek(fp, 0, SEEK_CUR);
int ret = fputs("AAAAA", fp);
printf("ret = %d\n", ret);fclose(fp);system("pause");
return 0;
}
  • 06-获取文件属性-大小.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>#include <sys/types.h>
#include <sys/stat.h>/*
FILE *fp = fopen("test05.txt", "r");fseek(fp, 0, SEEK_END);int len = ftell(fp);printf("文件大小:%d\n", len);fclose(fp);
*/int main0602(void)
{
struct stat buf;int ret = stat("test05.txt", &buf); // 传出参数:在函数调用结束时,充当函数返回值。printf("文件大小:%d\n", buf.st_size); // 不打开文件,获取文件大小。system("pause");
return EXIT_SUCCESS;
}
  • 07-刷新缓冲区.c
int main0701(void)
{
FILE *fp = fopen("test07.txt", "w+");
if (!fp)
{
perror("fopen error");
return -1;
}
char m = 0;while (1)
{
scanf("%c", &m);
if (m == ':')
{
break;
}
fputc(m, fp);
fflush(fp); // 手动刷新文件缓冲到物理磁盘。
}
// 当文件关闭时,会自动刷新缓冲区。
fclose(fp);system("pause");
return EXIT_SUCCESS;
}

Day12 — 贪吃蛇游戏

Code

  • 源文件 — main.c
 #define _CRT_SECURE_NO_WARNINGS#include "snake.h"// 引入自定义头文件int main(void)
{
// 去除光标。
CONSOLE_CURSOR_INFO cci;
cci.dwSize = sizeof(cci);
cci.bVisible = FALSE; // TRUE :
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cci);srand(time(NULL)); // 播种随机数种子。initSnake();// 初始化蛇
initFood();// 初始化食物initWall();// 画墙
initUI();// 画蛇和食物playGame();// 启动游戏showScore();// 打印分数system("pause");
return EXIT_SUCCESS;
}void showScore(void)
{
// 将光标默认位置移动至 不干扰游戏的任意位置。
COORD coord;coord.X = 0;
coord.Y = HIGH + 2;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);printf("Game Over!!!\n");
printf("成绩为:%d\n\n\n", score);
}void initWall(void)
{
for (size_t i = 0; i <= HIGH; i++)// 多行
{
for (size_t j = 0; j <= WIDE; j++)// 一行中的多列
{
if (j == WIDE)
{
printf("|");
}
else if (i == HIGH)
{
printf("_");
}
else
{
printf(" ");
}
}
printf("\n");
}
}void playGame(void)
{
char key = 'd';// 判断蛇撞墙
while (snake.body[0].X >= 0 && snake.body[0].X < WIDE
&& snake.body[0].Y >= 0 && snake.body[0].Y < HIGH)
{
// 更新蛇
initUI();// 接收用户按键输入 asdw
if (_kbhit()) {// 为真时,说明用户按下按键。
key = _getch();
}
switch (key)
{
case 'w': kx = 0; ky = -1; break;
case 's': kx = 0; ky = +1; break;
case 'd': kx = +1; ky = 0; break;
case 'a': kx = -1; ky = 0; break;
default:
break;
}// 蛇头撞身体: 蛇头 == 任意一节身体
for (size_t i = 1; i < snake.size; i++)
{
if (snake.body[0].X == snake.body[i].X
&& snake.body[0].Y == snake.body[i].Y)
{
return;// 游戏结束。
}
}// 蛇头撞食物
if (snake.body[0].X == food.X && snake.body[0].Y == food.Y)
{
initFood();// 食物消失
snake.size++;// 身体增长
score += 10;// 加分sleepSecond -= 100;// 加速
}// 存储蛇尾坐标
lastX = snake.body[snake.size - 1].X;
lastY = snake.body[snake.size - 1].Y;// 蛇移动,前一节身体给后一节身体赋值。
for (size_t i = snake.size - 1; i > 0; i--)
{
snake.body[i].X = snake.body[i - 1].X;
snake.body[i].Y = snake.body[i - 1].Y;
}
snake.body[0].X += kx;// 蛇头坐标根据用户按键,修改。
snake.body[0].Y += ky;Sleep(sleepSecond);
// 清屏
//system("cls");
}return;
}// 定义初始化蛇函数
void initSnake(void)
{
snake.size = 2;snake.body[0].X = WIDE / 2;//蛇头初始化
snake.body[0].Y = HIGH / 2;snake.body[1].X = WIDE / 2 - 1;// 蛇一节身体初始化
snake.body[1].Y = HIGH / 2;return;
}// 初始化界面控件
void initUI(void)
{
COORD coord = {0};// 光标移动的位置。// 画蛇
for (size_t i = 0; i < snake.size; i++)
{
coord.X = snake.body[i].X;
coord.Y = snake.body[i].Y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);if (i == 0)
putchar('@');
else
putchar('*');
}
// 去除蛇尾
coord.X = lastX;
coord.Y = lastY;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
putchar(' ');// 画食物
coord.X = food.X;
coord.Y = food.Y;SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
putchar('#');
}// 食物的初始化函数
void initFood(void)
{
food.X = rand() % WIDE; // 0-59
food.Y = rand() % HIGH; // 0-59
return;
}
  • 头文件 — snake.h
#ifndef __SNAKE_H__
#define __SNAKE_H__#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <conio.h>
#include <Windows.h>#define WIDE 60// 宽度
#define HIGH 20// 高度// 一个身体的对象
struct BODY {
int X;
int Y;
};// 定义蛇对象
struct SNAKE {
struct BODY body[WIDE*HIGH];
int size;
}snake;// 一个蛇对象// 定义食物对象
struct FOOD {
int X;
int Y;
}food1;// 一个食物对象int score = 0;// 分数int kx = 0;// 用户按下 asdw 任意一个按键所得到的 坐标值。
int ky = 0;int lastX = 0;// 蛇尾的坐标。
int lastY = 0;int sleepSecond = 400;// 声明函数
void initSnake(void);
void initFood(void);
void initUI(void);
void playGame(void);
void initWall(void);
void showScore(void);#endif

Day13

笔记


vim 3 种工作模式:命令模式:使用所有输入都被vim当成命令看。i、a、o、s -- I、A、O、S文本模式(编辑模式):在该模式下编辑代码。末行模式:“:” 切换为末行模式。 w:保存。 q:退出。
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:8,999
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,511
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,357
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,140
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,770
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,848