zoukankan      html  css  js  c++  java
  • 01C语言基础(二)

    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', ''};			变量,可读可写
    
    		char str2[] = "hi";				变量,可读可写
    
    		char *str3 = "hi";				常量,只读
    
    			str3变量中,存储的是字符串常量“hi”中首个字符‘h’的地址值。
    
    
    			str3[1] = 'H';	// 错误!!
    
    		char *str4 = {'h', 'i', ''};  // 错误!!!
    
    	2)
    		当字符串(字符数组), 做函数参数时, 不需要提供2个参数。 因为每个字符串都有 ''。
    
    
    	练习:比较两个字符串: 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] == '')
    		{
    			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 == '')
    		{
    			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] = '';
    }
    
    //指针版
    void mystrcpy2(char *src, char *dst)
    {
    	while (*src != '')  // src[i] == *(src+i)
    	{
    		*dst = *src;
    		src++;
    		dst++;
    	}
    	*dst = '';
    }
    
    	练习:在字符串中查找字符出现的位置:
    
    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] = '';
    }
    // 指针版
    void str_no_space2(char *src, char *dst)
    {
    	while (*src != 0)
    	{
    		if (*src != ' ')
    		{
    			*dst = *src;
    			dst++;
    		}
    		src++;
    	}
    	*dst = '';
    }
    
    
    带参数的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.exe
    
    		test.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
    ", m, n);
    	// 函数调用
    	//swap(m, n);  // m/n 实参
    
    	swap2(&m, &n);
    
    	printf("--after-- m = %d, n = %d
    ", 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
    ", 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("
    ");
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    • 03-数组做函数参数测试.c
    void test_func(int arr[])
    {
    	printf("size 2 = %u
    ", sizeof(arr));  // 整个数组大小
    
    	printf("%d
    ", arr[0]);
    }
    
    int main0301(void)
    {
    	int arr[] = { 4, 5, 5, 6, 7 };
    
    	printf("size 1 = %u
    ", 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 == 0
    
    	ret = test_func2(10, 20);
    
    	printf("ret = %d
    ", *ret);
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    • 05-指针和字符串.c
    int main(void)
    {
    	char str1[] = "hello";		// {'h',, 'e', 'l', 'l', 'o', ''}
    	char m[] = "hello";
    
    	char *str2 = "hello";		// "hello" 是一个字符串常量, 不能修改。
    	char *n = "hello";
    
    	str1[0] = 'R';
    	str2[0] = 'R';
    
    	printf("str1 = %p
    ", str1);
    	printf("m = %p
    ", m);
    
    	printf("str2 = %p
    ", str2);
    	printf("n = %p
    ", 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] == '')
    		{
    			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 == '')
    		{
    			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("相同
    ");
    	else if (ret == 1)
    		printf("str1 > str2
    ");
    	else if (ret == -1)
    		printf("str1 < str2
    ");
    	else
    		printf("异常
    ");
    
    	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] = '';
    }
    //指针版
    void mystrcpy2(char *src, char *dst)
    {
    	while (*src != '')  // src[i] == *(src+i)
    	{
    		*dst = *src;
    		src++;
    		dst++;
    	}
    	*dst = '';
    }
    
    int main0701(void)
    {
    	char *src = "helloworldfuoie11ll";
    
    	char dst[100];
    
    	mystrcpy2(src, dst);
    
    	printf("dst = %s
    ", 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
    ", 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] = '';
    }
    // 指针版
    void str_no_space2(char *src, char *dst)
    {
    	while (*src != 0)
    	{
    		if (*src != ' ')
    		{
    			*dst = *src;
    			dst++;
    		}
    		src++;
    	}
    	*dst = '';
    }
    
    int main0901(void)
    {
    	char str[] = "ni chou sha chou ni za di";
    	char dst[100] = {0};
    
    	str_no_space2(str, dst);
    
    	printf("dst = %s
    ", 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
    ", i, argv[i]);
    	}
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    • 11-字符串中找子串.c
    //strstr函数测试
    int main1101(void)
    {
    	char *ret = strstr("hellollollo", "llo");
    
    	printf("ret = %s
    ", 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次
    ", ret);
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    

    Day08

    笔记

    求非空字符串元素个数:
    
    	“ni chou sha chou ni za di”  
    
    字符串逆置: str_inverse
    
    	hello -- 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对应的空间一致。 
    
    			默认 不添加 ‘’
    
    			char *strncpy(char *dest, const char *src, size_t n);	
    
    			特性: n > src: 只拷贝 src 的大小
    
    			       n < src: 只拷贝 n 字节大小。 不添加 ‘’
    
    	字符串拼接:
    
    		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 返回1
    
    			s1 < s2 返回-1
    
    			int 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 返回1
    
    			s1 < s2 返回-1
    			
    
    
    	字符串格式化输入、输出:
    
    		sprintf():  s -- string
    
    			int sprintf(char *str, const char *format, ...);
    
    			对应printf,将原来写到屏幕的“格式化字符串”,写到 参数1 str中。
    
    			printf("%d+%d=%d
    ", 10, 24, 10+24);
    
    			---》 
    			char str[100];
    
    			sprintf(str, "%d+%d=%d
    ", 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
    " strchr("hehehahahoho", 'a'));  --> "ahahoho"
    
    		strrchr():
    
    			自右向左,在字符串str中 找一个字符出现的位置。 返回字符在字符串中的地址。
    
    			char *strrchr(const char *s, int c);
    
    			printf("%s
    " strrchr("hehehahahoho", 'a'));  --> "ahoho"
    
    		strstr():
    
    			在字符串str中,找子串substr第一次出现的位置。返回地址。
    
    			char *strstr(const char *str, const char *substr);
    
    			在字符串中找子串的位置。 
    
    			printf("%s
    " strrchr("hehehahahoho", "ho"));  --> "hoho"
    
    			printf("%s
    " strrchr("hehehahahoho", "xixi"));  --> NULL
    
    scanf("%s", str);
    
    scanf("%[^
    ]", str);
    
    	字符串分割:
    
    		strtok(): 按照既定的分割符,来拆分字符串。“www.baidu.com”  --> "wwwbaidu.com"
    
    		char *strtok(char *str, const char *delim);
    
    			参1: 待拆分字符串
    
    			参2: 分割符组成的“分割串”
    
    		返回:字符串拆分后的首地址。 “拆分”:将分割字符用 ''替换。
    
    	特性:
    		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
    ", p);
    		}
    
    	atoi/atof/atol:
    		
    		使用这类函数进行转换,要求,原串必须是可转换的字符串。
    
    		错误使用:"abc123" --> 0;	"12abc345" ---> 12;  "123xyz" -->123
     		
    		atoi:字符串 转 整数。
    
    		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 --- 10M	Linux: 8M --- 16M
    
    	heap:堆。 给用户自定义数据提供空间。 约 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
    ", 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
     ---------------------
    ", str);
    
    	char s2[] = "abcmncba";
    
    	int ret = str_abcbb(s2);
    
    	if (ret == 0)
    		printf("不是回文
    ");
    	else if (ret == 1)
    		printf("是回文
    ");
    
    	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 拷贝给dest
    
    	printf("p= %s
    ", p);
    	printf("dest = %s
    ", 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
    ", p[i]);
    	}
    
    	printf("p= %s
    ", p);
    	printf("dest = %s
    ", 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
    ", p);
    	printf("dest = %s
    ", 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
    ", p);
    	printf("dest = %s
    ", dest);
    
    	printf("%d
    ", strlen(dest));
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    • 05-strcmp和strncmp字符串比较.c
    int main0501(void)
    {
    	char *str1 = "helloworld";
    	char *str2 = "helloz";
    
    	printf("ret = %d
    ", strcmp(str1, str2));
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    int main0502(void)
    {
    	char *str1 = "helloworld";
    	char *str2 = "helloz";
    
    	printf("ret = %d
    ", 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 src
    	 
    	sprintf(buf, "%d%c%d=%d
    ", 10, '+', 34, 10+34);
    
    	puts(buf);
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    // sscanf
    int main0602(void)
    {
    	char buf[100] = { 0 }; //buffer  string str  source src
    
    	int a, b, c;
    
    	char str[] = "13+56=89";
    
    	sscanf(str, "%d+%d=%d", &a, &b, &c);
    
    	printf("a = %d
    ", a);
    	printf("b = %d
    ", b);
    	printf("c = %d
    ", c);
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    • 07-字符串分割strtok.c
    int main0701(void)
    {
    	char str[] = "www.itcast.cn.com.net";  // www itcast cn
    
    	char *p = strtok(str, ".");  // 第一次拆分,参1 传 待拆分的原串。
    
    	while (p != NULL)
    	{
    		p = strtok(NULL, ".");  // 第1+ 次拆分是,参1传 NULL.
    
    		printf("%s
    ", 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
    ", 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
    ", b++);
    }
    
    
    int main0801(void)
    {
    	char str[] = "abc345";
    	int num = atoi(str);
    	printf("num = %d
    ", num);
    
    	char str1[] = "     -10";
    	int num1 = atoi(str1);
    	printf("num1 = %d
    ", num1);
    
    	char str2[] = "0.123f";
    	double num2 = atof(str2);
    	printf("num2 = %.2lf
    ", num2);
    
    	char str3[] = "123L";
    	long num3 = atol(str3);
    	printf("num3 = %ld
    ", 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
    ", j);
    		//test1();
    	}	
    	printf("i 2 = %d
    ", 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
    ");
    		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("
    ");
    	}
    
    	// 释放空间时,应先释放内层空间。
    	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
    ", obj5.name[0]);
    
    	(*obj4).age = 200;//obj4->age = 200;
    	strcpy((*obj4).name,"200");
    	(*obj4).num = 200;
    
    	printf("age=%d, name=%s, num=%d
    ", obj4->age, obj4->name, obj4->num);
    
    	printf("age=%d, |%s|, num=%d
    ", (&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
    ", stu2.age, stu2.name, stu2.num);
    	printf("age = %d, name=%s, num= %d
    ", 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
    ", 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
    ", arr[i].age, arr[i].name, arr[i].num);
    	}
    	printf("
    ");
    
    	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
    ", arr[i].age, arr[i].name, arr[i].num);
    	}
    	printf("
    ");
    
    	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
    ", arr[i].age, arr[i].name, arr[i].num);
    	}
    	printf("
    ");
    
    	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
    ", (&stu)->man.age);
    	printf("name = %s
    ", (&stu)->man.name);
    	printf("score = %d
    ", (&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
    ", (&stu)->man.age);
    	printf("name = %s
    ", (&stu)->man.name);
    	printf("score = %d
    ", (&stu)->score);
    
    	struct student *p = &stu;
    
    	p->man.age = 18;
    
    	strcpy(p->man.name, "AAA");
    	p->score = 100;
    
    	printf("age = %d
    ", (*p).man.age);
    	printf("name = %s
    ", (&(p->man))->name);
    	printf("score = %d
    ", 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
    ", stu.age, stu.name);
    	printf("func stu: score = %d, num= %d
    ", 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
    ", stu.age, stu.name);
    	printf("2 func stu: score = %d, num= %d
    ", stu.score, stu.num);
    }
    
    void func2(struct student *stu)
    {
    	printf("func stu: age = %d, name= %s
    ", stu->age, stu->name);
    	printf("func stu: score = %d, num= %d
    ", 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
    ", stu->age, stu->name);
    	printf("2 func stu: score = %d, num= %d
    ", stu->score, stu->num);
    }
    
    struct student func3(struct student stu)
    {
    	printf("func stu: age = %d, name= %s
    ", stu.age, stu.name);
    	printf("func stu: score = %d, num= %d
    ", 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
    ", stu.age, stu.name);
    	printf("2 func stu: score = %d, num= %d
    ", 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
    ", stu2.age, stu2.name);
    	printf("stu2: score = %d, num= %d
    ", 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
    ", 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
    ", 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
    ", 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
    ", stu[i].age);
    		printf("name = %s
    ", stu[i].name);
    		printf("num = %d
    ", 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
    ", &t1);
    	printf("&t1.a = %p
    ", &(t1.a));
    	printf("&t1.b = %p
    ", &(t1.b));
    	printf("&t1.c = %p
    ", &(t1.c));
    
    	printf("a = %x
    ", t1.a);
    	printf("b = %x
    ", t1.b);
    	printf("c = %x
    ", t1.c);
    
    	t1.b = 0x3A;
    
    	printf("----------------
    a = %x
    ", t1.a);
    	printf("b = %x
    ", t1.b);
    	printf("c = %x
    ", t1.c);
    
    	printf("sizeof(t1) = %u
    ", 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
    ");
    
    	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 = 1000us
    
    	1us == 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、fwrite
    
    	3. 关闭文件 fclose()  
    
    
    打开、关闭文件函数:
    
    	FILE * fopen(const char * filename, const char * mode);
    
    		参1:待打开文件的文件名(访问路径)
    
    		参2:文件打开权限:
    
    			"r": 只读方式打开文件, 文件不存在,报错。存在,以只读方式打开。
    
    			"w": 只写方式打开文件, 文件不存在,创建一个空文件。文件如果存在,清空并打开。
    
    			"w+":读、写方式打开文件,文件不存在,创建一个空文件。文件如果存在,清空并打开。
    
    			"r+":读、写方式打开文件, 文件不存在,报错。存在,以读写方式打开。
    
    			"a": 以追加的方式打开文件。
    
    			"b": 操作的文件是一个二进制文件(Windows)
    
    		返回值:成功:返回打开文件的文件指针
    
    			失败:NULL
    
    
    	int fclose(FILE * stream);
    
    		参1:打开文件的fp(fopen的返回值)
    
    		返回值:成功 :0, 失败: -1;
    
    文件访问路径:
    
    	绝对路径:
    
    		从系统磁盘的 根盘符开始,找到待访问的文件路径
    
    		Windows书写方法:
    
    			1)C:\Users\afei\Desktop\06-文件分类.avi
    
    			2)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个英文字符到文件中。
    
    
    按字符读文件 fgetc
    
    	int fgetc(FILE * stream);
    
    		参1:待读取的文件fp(fopen的返回值)
    
    		返回值: 成功:读到的字符对应的ASCII码
    
    			 失败: -1
    
    	文本文件的结束标记: EOF ---》 -1 
    	
    	
    feof()函数:
    
    	int feof(FILE * stream);
    
    		参1: fopen的返回值
    
    		返回值: 到达文件结尾--》非0【真】
    				
    			 没到达文件结尾--》0【假】
    
    	作用:	
    		用来判断到达文件结尾。 既可以判断文本文件。也可以判断 二进制文件。
    
    	特性:
    
    		要想使用feof()检测文件结束标记,必须在该函数调用之前,使用读文件函数。
    
    		feof()调用之前,必须有读文件函数调用。
    
    fgets()函数:
    	
    	获取一个字符串, 以
    作为结束标记。自动添加 . 空间足够大 读
    , 空间不足舍弃
    , 必须有。
    
    	char * fgets(char * str, int size, FILE * stream);
    
    		char buf[10];  	hello --> hello
    
    
    		返回值: 成功: 读到的字符串
    
    			 失败: NULL
    
    fputs()函数:
    
    	写出一个字符串,如果字符串中没有
    , 不会写
    。
    
    	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
    ") == 0)	 // 实际 fgets 读到的是“:wq
    ”
    		{
    			break;
    		}
    		fputs(buf, fp);
    	}
    
    	fclose(fp);
    
    
    练习: 文件版四则运算:
    
    
    	1. 封装 write_file 函数,将4则运算表达式写入。
    
    		FILE * fp = fopen("w");
    
    		fputs("10/4=
    ", fp);
    
    		fputs("10+4=
    ", fp);
    		....
    
    		fputs("10*4=
    ", 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=
    ", &a, &ch, &b);	// 得到运算数, 运算符
    
    		3) 根据运算符,得到运算结果
    
    			switch(ch) {
    
    				case '+':
    					a+b;
    			}
    
    		4) 拼接 结果到  运算式 上
    
    			char result[1024];
    
    			sprintf(reuslt, "%d%c%d=%d
    ", a, ch, b, a+b);		// reuslt 中包含带有结果的 运算式。
    
    		5)将 多个带有结果的运算 拼接成一个字符串。
    
    			char sum_ses[4096];	// 存总的字符串  -- "10/2=5
    10*3=30
    4+3=7
    8-6=2
    "
    
    			strcat(sum_ses,reuslt);  // 在while中循环拼接
    
    		6) 重新打开文件, 清空原有 4则运算表达式
    
    			fclose(fp);
    
    			fp = fopen("w");
    
    		7) 将 拼接成一个字符串。写入到空的文件中
    
    			fputs(sum_res);
    
    			
    
    10/2=	fgets(buf, 4096, 文件fp) --->"10/2=
    " --> 10   /   2   sscanf(buf, "%d%c%d=
    ", &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
    10*3=30
    4+3=7
    8-6=2
    "  --> 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
    ", &obj);
    	printf("&obj.ch = %p
    ", &obj.ch);
    	printf("&obj.sh = %p
    ", &obj.sh);
    	printf("&obj.a  = %p
    ", &obj.a);
    
    	printf("sizeof(test_t) = %u
    ", sizeof(test_t));
    
    	printf("a  = 0x%x
    ", obj.a);
    	printf("sh = 0x%x
    ", obj.sh);
    	printf("ch = 0x%x
    ", obj.ch);
    
    	obj.ch = 0xFF;
    
    	printf("a  = 0x%x
    ", obj.a);
    	printf("sh = 0x%x
    ", obj.sh);
    	printf("ch = 0x%x
    ", 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
    ");
    	}
    	else
    	{
    		printf("blue is not 2, blue = %d
    ", blue);
    	}	
    	printf("yellow = %d
    ", yellow);
    
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    • 02-系统文件.c
    int main0201(void)
    {
    	//fclose(stdout);
    
    	printf("hello file
    ");
    
    	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
    ");  :xxxxxxx
    		getchar();
    		return -1;
    	}
    
    	fclose(fp);
    	printf("------------finish
    ");
    
    	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
    ", ret);
    
    	fclose(fp);
    	printf("---------------finish
    ");
    
    	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
    ", 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
    ", ch);
    	}
    
    	fclose(fp);
    }
    
    void test_feof()
    {
    	FILE *fp = fopen("06test.txt", "r");
    	if (fp == NULL)
    	{
    		perror("fopen error");
    		return ;
    	}
    	while (1)
    	{
    		printf("没有到达文件结尾
    ");
    		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('
    ', 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
    ") == 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=
    ", fp);
    	fputs("10*3=
    ", fp);
    	fputs("4-2=
    ", fp);
    	fputs("10+2=
    ", 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=
    ";
    		if (feof(fp))
    		{
    			break;
    		}
    		sscanf(buf, "%d%c%d=
    ", &a, &ch, &b);	// a:10, ch:'/' b: 2
    
    		sprintf(result, "%d%c%d=%d
    ", 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
    ", 10, 5);
    
    	printf("%d = %d%c%d
    ", 10+5, 10, '+', 5);			--> 屏幕
    
    
    	char buf[1024];   //缓冲区  
    
    	sprintf(buf, "%d = %d%c%d
    ", 10+5, 10, '+', 5);		--> buf 中
    
    	FILE * fp = fopen();
    
    	fprintf(fp, "%d = %d%c%d
    ", 10+5, 10, '+', 5);			--> fp 对应的文件中
    
    scanf --- sscanf --- fscanf
    
    	scanf("%d", &m);		键盘 --> m
    
    
    	char str[] = "98";
    
    	sscanf(str, "%d", &m);		str --> m
    
    
    	FILE * fp = fopen("r");
    
    	fscanf(fp, "%d", &m);		fp指向的文件中 --> m
    
    
    fprintf()函数:   ---> 将数据按指定的格式写进文件中
    
    	写
    
    	int fprintf(FILE * stream, const char * format, ...);
    
    fscanf()函数:--->  从文件中读取指定格式的数据到内存中
    
    	读
    
    	int fscanf(FILE * stream, const char * format, ...);
    
    		成功:正确匹配的个数。
    
    		失败: -1
    
    	1) 边界溢出。 存储读取的数据空间。在使用之前清空。
    
    	2)fscanf函数,每次在调用时都会判断下一次调用是否匹配参数2, 如果不匹配提前结束读文件。(feof(fp) 为真)。
    
    
    练习:文件版排序
    
    	生成随机数,写入文件。将文件内乱序随机数读出,排好序再写回文件。
    
    
    fgetc --- fputc
    
    fgets --- fputs
    
    fprintf -- 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, 失败: -1
    
    	ftell():
    
    		获取文件读写指针位置。
    
    		long ftell(FILE *stream);
    
    		返回:从文件当前读写位置到起始位置的偏移量。
    
    		
    		借助 ftell(fp) + fseek(fp, 0, SEEK_END); 来获取文件大小。
    
    	rewind():
    
    		回卷文件读写指针。 将读写指针移动到起始位置。
    
    		void rewind(FILE *stream);
    
    
    Linux和windows文件区别:
    
    	1)对于二进制文件操作, Windows 使用“b”, Linux下二进制和文本没区别。
    
    	2)windows下,回车 
    , 换行 
    。 
      , Linux下 回车换行
    
    
    	3) 对文件指针,先写后读。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(); 遇到
    就会将缓冲区中的数据刷新到物理设备上。
    
    	全缓冲:文件。 缓冲区存满, 数据刷新到物理设备上。
    
    	无缓冲: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
    ", 10);
    	fprintf(fp, "%d
    ", 8);
    	fprintf(fp, "%d
    ", 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
    ", &a);
    	printf("%d
    " , a);
    
    	fscanf(fp, "%d
    ", &a);
    	printf("%d
    ", a);
    
    	fscanf(fp, "%d
    ", &a);
    	printf("%d
    ", a);
    
    	a = 0;
    	fscanf(fp, "%d
    ", &a);
    	printf("%d
    ", 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
    ", &a);  // 读
    		printf("%d
    ", 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);// 读 
    
    		if (feof(fp))		// 真-- 文件结尾
    			break;
    		printf("%d
    ", 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
    ", 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
    ", 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
    ", &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
    ", 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
    ", 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
    ", ret);
    
    	printf("age = %d, name=%s, num = %d
    ", 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
    ", 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
    ", ret);
    		fwrite(buf, 1, ret, wfp);
    	}
    
    	fclose(wfp);
    	fclose(rfp);
    }
    
    int main0401(void)
    {
    	myfile_cp();
    
    	printf("---------------------finish
    ");
    
    	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
    ", ret);
    
    	fseek(fp, sizeof(stu_t)*2, SEEK_SET);		// 从文件起始位置,向后偏移一个stu结构体
    
    	ret = fread(&s1, 1, sizeof(s1), fp);
    	printf("ret = %d
    ", ret);
    
    	printf("1 age= %d, name=%s, num=%d
    ", s1.age, s1.name, s1.num);
    
    	int len = ftell(fp); // 获取文件当前读写指针位置,到文件起始位置的偏移量。
    
    	printf("len = %d
    ", len);
    
    	rewind(fp);	// 将文件读写指针回卷到起始。
    
    	ret = fread(&s1, 1, sizeof(s1), fp);
    
    	printf("2 age= %d, name=%s, num=%d
    ", s1.age, s1.name, s1.num);
    
    	// 获取文件大小。
    	fseek(fp, 0, SEEK_END);	// 将文件读写指针放到文件结尾。
    	len = ftell(fp);
    	printf("文件大小为:%d
    ", 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
    ", ret);		// 0 表示成功。
    
    	ret = fputs("22222", fp);
    	printf("ret 2 = %d
    ", ret);
    
    	ret = fputs("33333", fp);
    	printf("ret 3 = %d
    ", 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 
    ");
    
    	printf("fgets ptr = %s
    ", ptr);
    	printf("buf = %s
    ", 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
    ", ptr, buf);
    
    	fseek(fp, 0, SEEK_CUR);
    	int ret = fputs("AAAAA", fp);
    	printf("ret = %d
    ", 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
    ", len);
    
    fclose(fp);
    */
    
    int main0602(void)
    {
    	struct stat buf;
    
    	int ret = stat("test05.txt", &buf);  // 传出参数:在函数调用结束时,充当函数返回值。
    
    	printf("文件大小:%d
    ", 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!!!
    ");
    	printf("成绩为:%d
    
    
    ", 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("
    ");
    	}
    }
    
    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:退出。
    
  • 相关阅读:
    旅行喵 React Native 技术实践
    微信、QQ这类IM App怎么做——谈谈Websocket
    IOS热更新-JSPatch实现原理+Patch现场恢复
    jquery 插件开发及extend
    JS Nice – JavaScript 代码美化和格式化工具
    ExtJS与jQuery的一点细节上的对比
    JQuery实现图片的预加载与延时加载
    十个实用但IE不支持的CSS属性
    如何通过预加载器提升网页加载速度
    遭遇Asp.Net长文件名下载的问题和解决办法
  • 原文地址:https://www.cnblogs.com/zranguai/p/14998997.html
Copyright © 2011-2022 走看看