1.calloc与realloc的使用
void *malloc(size_t size)size -- 内存块的大小,以字节为单位
该函数返回一个指针 ,指向已分配大小的内存。如果请求失败,则返回 NULL。
void *realloc(void *ptr, size_t size)size -- 内存块的新的大小,以字节为单位。如果大小为 0,且 ptr 指向一个已存在的内存块,则 ptr 所指向的内存块会被释放,并返回一个空指针。
该函数返回一个指针 ,指向重新分配大小的内存。如果请求失败,则返回 NULL。
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>static void test01(){ //int* p = malloc(sizeof(int) * 10);//开辟出堆区的内存是未知数据 int* p = calloc(10, sizeof(int));//calloc会将堆区分配的内容初始化为0 for (int i = 0; i < 10; i++) { printf("%d\n", p[i]); } if (p!= NULL) { free(p); p = NULL; }}//realloc重新在堆区分配内存static void test02(){ int* p = malloc(sizeof(int) * 10); printf("%d\n", p); for (int i = 0; i < 10; i++) { p[i] = i; } p = realloc(p, sizeof(int) * 20); for (int i = 0; i < 20; i++) { printf("%d\n",p[i]); } printf("%d\n", p); if (p != NULL) { free(p); p = NULL; }}int main01(){ //test01(); test02(); return 0;}2.sscanf的使用
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>//1、%*s或%*d 跳过数据static void test01(){ char* str = "123abcd"; char buf[1024] = { 0 }; sscanf(str, "%*d%s", buf);//从str中读取字符串 忽略%d打印出%s 输出到buf中 printf("%s\n", buf);}static void test02(){ char* str = "abcd12345";//在中间加空格或者\t都可以实现取出数字的效果 char buf[1024] = { 0 }; //sscanf(str, "%*s%s", buf); sscanf(str, "%*[a-z]%s", buf);//忽略a~z printf("%s\n", buf);}//2、%[width]s 读取指定宽度的数据static void test03(){ char* str = "1234abcd"; char buf[1024] = { 0 }; sscanf(str, "%6s", buf); printf("%s\n", buf);}//3、%[a-z]匹配a~z中任意字符static void test04(){ char* str = "12345abcde"; char buf[1024] = { 0 }; sscanf(str, "%*d%[a-c]", buf);//忽略数组匹配a~c printf("%s\n", buf);}//4、%[aBc]匹配a、B、c中的一员,贪婪性static void test05(){ char* str = "aabcde12345"; char buf[1024] = { 0 }; sscanf(str, "%[aBc]", buf);//匹配过程中只要有一个失败了,后续不再进行匹配 printf("%s\n", buf);//aa}//5、%[^a]匹配非a的任意字符,贪婪性static void test06(){ char* str = "abcde12345"; char buf[1024] = { 0 }; sscanf(str, "%[^c]", buf); printf("%s\n", buf);//ab}//6、%[^a-z]读取除a~z以外的所有字符static void test07(){ char* str = "abcde12345"; char buf[1024] = { 0 }; sscanf(str, "%[^0-9]", buf); printf("%s\n", buf);//abcde}//7、案例static void test08(){ char* ip = "127.0.0.1"; int num1 = 0; int num2 = 0; int num3 = 0; int num4 = 0; sscanf(ip, "%d.%d.%d.%d", &num1, &num2, &num3, &num4); printf("%d\n", num1); printf("%d\n", num2); printf("%d\n", num3); printf("%d\n", num4);}static void test09(){ char* str = "abcde#longGG@12345"; char buf[1024] = { 0 }; sscanf(str, "%*[^#]#%[^@]", buf); printf("%s\n", buf);}static void test10(){ char* str = "helloworld@itcase.cn"; char buf1[1024] = { 0 }; char buf2[1024] = { 0 }; sscanf(str, "%[a-z]%*[@]%s", buf1, buf2); printf("%s\n", buf1);//helloworld printf("%s\n", buf2);//itcase.cn}int main02(){ //test01(); //test02(); //test03(); //test04(); //test05(); //test06(); //test07(); //test08(); //test09(); test10(); return 0;}3.查找子串
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>int mystrcpy(char* str, char* substr){ int num = 0; while (*str != '\0') { if (*str != *substr) { str++; continue; } //创建临时指针 char* tmpstr = str; char* tmpsubstr = substr; while (*tmpsubstr != '/0') { if (*tmpstr != *tmpsubstr) { //匹配失败 str++; num++; break; } tmpstr++; tmpsubstr++; } if (*tmpsubstr == '\0') { //匹配成功 return num; } } return -1;}static void test01(){ char* str = "abcdefghdnf"; int ret = mystrcpy(str, "dnf"); if (ret == -1) { printf("未找到子串\n"); } else { printf("找到子串位置是:%d\n", ret); }}int main03(){ test01(); return 0;}4.const使用场景
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>struct person{ char name[64]; int age; int id; double score;};//const使用场景:修饰函数中的形参,防止误操作static void printperson(const struct person *p){ //p->age = 100;加入const之后编译器会检测误操作 printf("姓名:%s,年龄:%d,学号:%d,成绩:%d\n", p->name, p->age, p->id, p->score);}static void test01(){ struct person p1 = {"张飒",22,01,78}; printperson(&p1); printf("p1年龄:%d\n", p1.age);}int main05(){ test01(); return 0;}5.二级指针作为函数参数的输入特性
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>//二级指针做函数参数的输入特性//主调函数分配内存,被调函数使用static printarr(int**parr,int len){ for (int i = 0; i < len; i++) { printf("%d\n", *parr[i]); }}static void test01(){ //在堆区分配内存 int** p = malloc(sizeof(int*) * 5); //在栈区创建数据 int a1 = 10; int a2 = 20; int a3 = 30; int a4 = 40; int a5 = 50; p[0] = &a1; p[1] = &a2; p[2] = &a3; p[3] = &a4; p[4] = &a5; printarr(p, 5); if (p != NULL) { free(p); p = NULL; }}static void test02(){ //在栈区创建 int* parr[5]; for (int i = 0; i < 5; i++) { parr[i] = malloc(4); *(parr[i]) = 100 + i; } int len = sizeof(parr) / sizeof(int*); printarr(parr, len); for (int i = 0; i < 5; i++) { if (parr[i] != NULL) { free(parr[i]); parr[i] = NULL; } }}int main06(){ //test01(); test02(); return 0;}6.二级指针作为函数参数的输出特性
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>static allocatespace(int** p){ int* arr = malloc(sizeof(int) * 10); for(int i = 0; i < 10; i++) { arr[i] = i + 10; } *p = arr;}static void printarray(int**parr,int len){ for (int i = 0; i < 10; i++) { printf("%d\n", (*parr)[i]); }}static void freespace(int**p){ if (*p != NULL) { free(*p); *p = NULL; }}static void test01(){ int* p = NULL; allocatespace(&p); printarray(&p, 10); freespace(&p);}int main07(){ test01(); return 0;}7.二级指针文件读写
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<string.h>#include<stdlib.h>//获取文件的行数int getFileLines(FILE* file){ if (file == NULL) { return -1; } char buf[1024]; //读取的数据存入到buf int num = 0; while (fgets(buf, 1024, file) != NULL) { num++; //printf("%s", buf); } //将文件光标 置为文件首 fseek(file, 0, SEEK_SET); return num;}//参数1 文件指针 参数2 有效函数 参数3 堆区数组void readFileData(FILE* file, int len, char** pArray){ if (file == NULL) { return; } if (len <= 0) { return; } if (pArray == NULL) { return; } char buf[1024]; //读取的数据存入到buf int index = 0; while (fgets(buf, 1024, file) != NULL) { //buf中就是存放的每行的数据 int currentLen = strlen(buf) + 1; char* currentP = malloc(sizeof(char) * currentLen); //将数据拷贝到堆区内存中 strcpy(currentP, buf); pArray[index++] = currentP; //清空缓冲区 memset(buf, 0, 1024); }}void showFileData(char** pArray, int len){ for (int i = 0; i < len; i++) { printf("第 %d 行的数据为 %s", i + 1, pArray[i]); }}void freeSpace(char** pArray, int len){ for (int i = 0; i < len; i++) { if (pArray[i] != NULL) { free(pArray[i]); pArray[i] = NULL; } } free(pArray); pArray = NULL;}void test01(){ FILE* file = fopen("f:/a.txt", "r"); if (file == NULL) { printf("文件打开失败\n"); return; } int len = getFileLines(file); printf("文件的有效行数为:%d\n", len); char** pArray = malloc(sizeof(char*) * len); //将文件中的数据 读取后 放入到pArray中 readFileData(file, len, pArray); //打印数据 showFileData(pArray, len); //释放数据 freeSpace(pArray, len); pArray = NULL; //关闭文件 fclose(file); file = NULL;}int main08() { test01(); system("pause"); return EXIT_SUCCESS;}8.按位取反、或、与、左移和右移
#define _CRT_SECURE_NO_WARNINGS#include<stdio.h>#include<stdlib.h>#include<string.h>#include<time.h>//1、按位取反~static void test01(){ int num = 2; printf("~num=%d\n", ~num);//-3 //010按位取反 101原码 //101补码 110+1=111 最高位是符号位}//2、按位与static void test02(){ int num = 123; if((num & 1) == 0) { printf("num为偶数\n"); } else { printf("num为奇数\n");//奇 }}//3、按位或static void test03(){ int num1 = 5; int num2 = 3; printf("num1|num2=%d\n", num1 | num2);//7}//4、三种方式交换两个数字static void test04(){ int num1 = 10; int num2 = 20; //方式1 //int temp = num1; //num1 = num2; //num2 = temp; //按位异或方式2 num1 = num1 ^ num2; num2 = num1 ^ num2; num1 = num1 ^ num2; //不用临时变量实现两个数字交换 //num1 = num1 + num2; //num2 = num1 - num2; //num1 = num1 - num2; printf("交换后\n"); printf("num1=%d\n", num1); printf("num2=%d\n", num2);}//左移运算符static void test05(){ int num = 10; printf("%d\n", num <<= 2);// <<n即乘以2的n次方}//右移运算符static void test06(){ int num = 10; printf("%d\n", num >>= 1);// >>n即除以2的n次方}int main(){ //test01(); //test02(); //test03(); //test04(); //test05(); test06(); return 0;}
