C基础学习笔记02
来源:互联网 发布:d3.js调用百度地图api 编辑:程序博客网 时间:2024/04/26 23:59
- 数组类型
int A[5] = {0};int B[3][5] ={0};
C语言规定[一维数组]: 数组名(A)是数组首元素的地址 根据数组名取地址(&A),取出的则是整个数组的地址
C语言规定[二维/多维数组]: int * pArr[5] -> B[x][5]; 数组名(B)是指向数组第0行的所有元素地址 B+1 -> 是指向数组第一行的所有元素的地址 *(B+1) -> 是指向第一行第一列的元素的地址 *(B+1)+i <==> &B[i][j] B[3][5] <==> *(*(B+3)+5); 二维数组作为参数传递:function(int (*a)[5]);
typedef int (MyArray)[5];//为数组定义一个别名 定义一个数组:MyArray arr ;==> int arr[5]; 定义一个指针数组:MyArray * pArr;==>int * pArr[5]; typedef int (*pArray)[5];//为指针定义一个别名 定义一个指针数组:pArray pArr;==> int * pArr[5];
- 指针数组的自我结束
char * str[] = {"abc","abc","abc","\0"};// 在数组中["\0" <==> 0 <==> NULL] //指针数组的遍历方式(数组元素不确定) void show(char ** str){ int i = 0; for (;str[i] != NULL;i++) printf("%s\n",str[i]); }
- 结构体
struct Teacher{ char name[64]; int age;};....struct Teacher one = {"aaa",16};struct Teacher two;memset(&two,0,two);//操作一[在main函数中拷贝]two = one;//成功把one的内容拷贝到two的内容中去//操作二[在自定义函数中拷贝(传递实参的值)]void copyTeacher(struct Teacher to ,struct Teacher from ){to = from;}copyTeacher(two,one);//失败,形参的值(to)发生改变,实参的值(two)并没有发生改变//操作三[在自定义函数中拷贝(传递实参的地址)]void copyTeacher(struct Teacher * to , struct Teacher * from){*to = *from;}copyTeacher(&two,&one);//成功
* 结构体与一级指针
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>typedef struct Teacher{ char * Name; int age;}Teacher;/*分配内存*/Teacher * createTeacher_01(int num);int createTeacher_02(Teacher ** teacher ,int num);/*释放内存*/void FreeTeacher(Teacher * teacher, int num);int main(){ return 0;}/* 函数实现 *///不建议Teacher * createTeacher_01(int num/*in*/){ Teacher * temp = NULL; temp = (Teacher *)malloc(sizeof(Teacher) * num);//分配结构体内存[Name的内存并没有分配] if (temp == NULL) return NULL; memset(temp,0,sizeof(Teacher) * num);//初始化 return temp;}int createTeacher_02(Teacher ** t/*out*/,int num/*in*/){ Teacher * temp = NULL; temp = (Teacher *)malloc(sizeof(Teacher) * num); if (temp == NULL) return -1; memset(temp,0,sizeof(Teacher) * num); int i = 0; for (i = 0;i < num;i++){ temp[i].Name = (char *)malloc(60); //(temp + i)->Name = (char *)malloc(60); } *t = temp;//间接修改实参的值 return 0;}void FreeTeacher(Teacher * t/*in*/,int num/*in*/){ if (t == NULL) return ; int i = 0; for (i = 0;i < num;i++){ if (t[i].Name != NULL){ free(t[i].Name); } } free(t);}
* 结构体与二级指针
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>typedef struct Teacher{ int age; char * Name; char ** StuName;}Teacher;/*分配内存*/int createTeacher(Teacher ** t,int num);/*回收内存*/void FreeTeacher(Teacher * t,int num);int main(){ int result = 0; Teacher * Tarr = NULL; result = createTeacher(&Tarr,3); if (result){ printf("memery error!"); return 0;//结束程序 } int i = 0 ,j = 0; char name[20] = {0}; for (i = 0;i < 3;i++){ Tarr[i].age = (i+1);//age sprintf(name,"%s%d","name:",i); strcpy(Tarr[i].Name,name);//name for(j = 0;j < 3;j++){ sprintf(name,"%s%d%d","sname:",i,j); strcpy(Tarr[i].StuName[j],name);//stuname } } for (i = 0;i < 3;i++){ printf("age = %d\n",Tarr[i].age); printf("name = %s\n",Tarr[i].Name); for (j = 0;j < 3;j++){ printf("\tstuname = %s\n",Tarr[i].StuName[j]); } printf("=================\n"); } FreeTeacher(Tarr,3); return 0;}/*函数实现*/int createTeacher(Teacher ** t/*out*/,int num/*in*/){ Teacher * temp = NULL; //分配结构体数组 temp = (Teacher *)malloc(sizeof(Teacher) * num); if (temp == NULL){ return -1; } memset(temp,0,sizeof(Teacher) * num); int i = 0, j = 0; for (i = 0;i < num;i++){ //分配一级指针 temp[i].Name = (char *)malloc(60); //分配二级指针 char ** pt = (char ** )malloc(sizeof(char *) * 3); for (j = 0;j < 3;j++){ pt[j] = (char *)malloc(60); } temp[i].StuName = pt; } *t = temp; return 0;}void FreeTeacher(Teacher * t/*in*/,int num/*in*/){ if (t == NULL){ return ; } int i = 0, j = 0; for (i = 0;i < num;i++){ //释放一级指针 if (t[i].Name != NULL){ free(t[i].Name); } //释放二级指针 char ** ptr = t[i].StuName; for (j = 0;j < 3;j++){ if (ptr[i] != NULL){ free(ptr[i]); } } free(ptr); t[i].StuName = NULL; } free(t);}
* 数组合并
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>/*合并*/int strArray(char ** str1,int len1,char (*str2)[10],int len2,char *** strArr,int * Arrlen);/*内存回收*/void FreeArray(char ** arr,int len);void FreeArray_02(char *** arr,int len);int main(){ //char *str1[10] ={"xxx","yyy","zzz"};//char *str[] ==> char ** str //char str2[3][10] = {"aaa","bbb","ccc"};//char str[][] ==> char (*str)[] //int arrlength = 0; //char ** strArr = NULL;//strArr = str1 + str2(将str1和str2的内容放进strArr) //strArray(str1,3,str2,3,&strArr,&arrlength); //FreeArray_02(&strArr,arrlength); return 0;}/*函数实现*/int strArray(char ** str1/*in*/,int len1/*in*/,char (*str2)[10]/*in*/,int len2/*in*/,char *** strArr/*out*/,int * Arrlen/*out*/){ char ** ArrayList = NULL; int i = 0 , j = 0; /*分配内存*/ ArrayList = (char **)malloc(sizeof(char *) * (len1 + len2)); if (ArrayList == NULL){ return -1; } memset(ArrayList,0,sizeof(char*) * (len1 + len2)); int length = 0;//计算每个字符串的大小 /*拷贝str1->ArrayList*/ for (i = 0;i < len1;i++){ length = strlen(str1[i]) + 1;//"\0" ArrayList[i] = (char *)malloc(length); strcpy(ArrayList[i],str1[i]); } /*拷贝str2->ArrayList*/ for(j = 0;j < len2;j++,i++){//"i++" length = strlen(str2[j]) + 1; ArrayList[i] = (char *)malloc(length); strcpy(ArrayList[i],str2[j]); } /*赋值*/ *strArr = ArrayList; *Arrlen = (len1 + len2); return 0;}void FreeArray(char ** arr/*in*/,int len/*in*/){ if (arr == NULL){ return; } char ** pstr = arr; int i = 0; for (i = 0;i < len;i++){ if (pstr[i] != NULL){ free(pstr[i]); } } free(pstr);}void FreeArray_02(char *** arr/*in*/,int len/*in*/){ if (arr == NULL){ return; } char ** pstr = *arr; int i = 0; for (i = 0;i < len;i++){ if (pstr[i] != NULL){ free(pstr[i]); } } free(pstr); *arr = NULL;}
* 结构体中的浅拷贝和深拷贝
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>typedef struct Temp{ int data; char * text;}Temp;void copyTemp(Temp * to,Temp * from);int main(){ Temp temp1,temp2; memset(&temp1,0,sizeof(temp1)); memset(&temp2,0,sizeof(temp2)); temp1.data = 10; temp1.text = (char *)malloc(60); strcpy(temp1.text,"aaaaaa"); //将temp1 -> temp2 copyTemp(&temp2,&temp1); //释放内存(temp1) if (temp1.text != NULL){ free(temp1.text); temp1.text = NULL; } //释放内存(temp2) if (temp2.text != NULL){ //1. printf("[%s]\n",temp2.text); //2. free(temp2.text); /*执行浅拷贝时 代码段1会打印出一堆垃圾值 代码段2则会引发异常[不同的编译器可能处理方式不同] 原因: 执行浅拷贝,temp1.text只是将只是将自己的内存地址拷贝给temp2.text,并没有为temp2.text重新分配一块内存,即 temp1.text -> 0x100;//假设temp1.text指向的内存地址是[0x100("aaaaaa")] *to = *from ==> temp2.text = temp1.text ==>temp2.text ->0x100//并未重新为temp2.text分配内存 :在结构体中"="操作符是一种浅拷贝 */ //执行深拷贝时重新为[temp2.text]分配了内存则不会出问题 temp2.text = NULL; } return 0;}void copyTemp(Temp * to/*out*/,Temp * from/*in*/){ //结构体中的浅拷贝方式=================== //浅拷贝1 *to = *from; //浅拷贝2 //memcpy(to,from,sizeof(Temp)); //=================================== //结构体中的深拷贝=================== //深拷贝 *to = *from; to->text = (char *)malloc(60); strcpy(to->text,from->text); //===================================}
* 结构体中的偏移量
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>typedef struct Adv{ char name[64]; int age; char * text;}Adv;int main(){ Adv * p = NULL; //age在结构体中的偏移量 int offsize = (int)(&(p->age)); //offsize = 64因为name的长度为64(不考虑大端对齐与小端对齐) //将"0"地址强制解释为[Adv*]类型然后求出age相对p的偏移量 offsize = (int)(&(((Adv*)0)->age)); //初始化 p = (Adv*)malloc(sizeof(Adv)); strcpy(p->name,"芦苇微微"); p->age = 16; p->text = (char *)malloc(64); strcpy(p->text,"一笑奈何"); //定义一个无符号类型的指针 void * pstr = NULL; pstr = (int)(&(p->age)) - offsize; //指向p首地址 printf("%s\n",((Adv*)pstr)->name); printf("%s\n",((Adv*)pstr)->text); printf("%d\n",((Adv*)pstr)->age); return 0;}
* 文件操作(fgetc & fputc[单个字符读取/写入])
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>//写文件int writeFile(const char * path,char * data);//读文件int readFile(const char * path);int main(){ char * data = "Talent is continuing patience!\n";//写入内容 char * path = "D:/Test/1.txt";//文件内容 writeFile(path,data); readFile(path); return 0;}int writeFile(const char * path/*in*/,char * data/*in*/){ FILE * fp = NULL; fp = fopen(path,"r+"); if (fp == NULL){ return -1; } int i = 0; for (i = 0;i < strlen(data);i++){ fputc(data[i],fp); } if (fp != NULL){ fclose(fp); } return 0;}int readFile(const char * path /*in*/){ FILE * fp = NULL; if ((fp = fopen(path,"r+")) == NULL){ return -1; } while (!feof(fp)){ char str = fgetc(fp); printf("%c",str); } /* char str = NULL; while ((str = fgetc(fp)) != EOF) printf("%c",str); */ if (fp != NULL) { fclose(fp); } return 0;}
r 以只读方式打开文件,只允许读取,不允许写入。该文件必须存在。r+ 以读/写方式打开文件,允许读取和写入。该文件必须存在。rb+ 以读/写方式打开一个二进制文件,允许读/写数据。rt+ 以读/写方式打开一个文本文件,允许读和写。w 以只写方式打开文件,若文件存在则长度清为0,即该文件内容消失,若不存在则创建该文件。w+ 以读/写方式打开文件,若文件存在则文件长度清为零,即该文件内容会消失。若文件不存在则建立该文件。a 以追加的方式打开只写文件。若文件不存在,则会建立该文件,如果文件存在,写入的数据会被加到文件尾,即文件原先的内容会被保留(EOF符保留)。a+ 以追加方式打开可读/写的文件。若文件不存在,则会建立该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(原来的EOF符 不保留)。wb 以只写方式打开或新建一个二进制文件,只允许写数据。wb+ 以读/写方式打开或建立一个二进制文件,允许读和写。wt+ 以读/写方式打开或建立一个文本文件,允许读写。at+ 以读/写方式打开一个文本文件,允许读或在文本末追加数据。ab+ 以读/写方式打开一个二进制文件,允许读或在文件末追加数据。
* 文件操作(fgets [按行读取])
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>int readFile(const char * path);int main(){ char * path = "D:/Test/1.txt"; readFile(path); return 0;}int readFile(const char * path/*in*/){ FILE * fp = NULL; if ((fp = fopen(path,"r+")) == NULL){ return -1; } char buf[1024] = {0};//缓冲区 char * pstr = NULL; while ((pstr = fgets(buf,1024,fp)) != NULL){ printf("%s",pstr); } if (fp != NULL){ fclose(fp); } return 0;}
* 文件操作(fread & fwrite[按结构体格式读取/写入内容])
typedef struct Teacher{ char name[12]; int age;}Teacher;int readFile(char * path);int writeFile(const char * path,Teacher * t);int main(){ char * path = "D:/Test/2.txt"; Teacher t[3] ; memset(&t,0,sizeof(Teacher) * 3); int i = 0; for (i = 0;i < 3;i++){ sprintf(t[i].name,"%d%d%d",(i+3),(i+3),(i+3)); t[i].age = (i+5); } writeFile(path,t); readFile(path); return 0;}int writeFile(const char * path/*in*/,Teacher * t/*in*/){ FILE * fp = NULL; if ((fp = fopen(path,"wb")) == NULL){ return -1; } int i= 0; int count = 1; for (i = 0;i < 3;i++){ if (count != fwrite(&t[i],sizeof(Teacher),count,fp)){ return -1; } } if (fp != NULL){ fclose(fp); } return 0;}int readFile(char * path/*in*/){ FILE * fp = NULL; if ((fp = fopen(path,"rb+")) == NULL){ return -1; } Teacher t[3]; memset(&t,0,sizeof(Teacher) * 3); int i = 0; int count = 1; for (i = 0;i < 3;i++){ if (count != fread(&t[i],sizeof(Teacher),count,fp)){ return -1; } } for (i = 0;i < 3;i++){ printf("%s - %d\n",t[i].name,t[i].age); } if (fp != NULL){ fclose(fp); } return 0;}
//fread & fwrite参数解释 //_Check_return_opt_ _CRTIMP size_t __cdecl // fwrite(_In_count_x_(_Size*_Count) const void * _Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE * _File); //函数参数 //_Str : 从内存块的开始 //_Size //内存打包技术 //_Count 写多少次 //_File : 写入到 文件指针 所指向的文件中
* 按(key=value)的形式读写文件
====>MAIN.C#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#include "readCFG.h"int main(){ /*读=========================== char * path = "D:/Test/3.txt"; char * key = "love"; char str[12] = {0}; int length = 0; getReadCFGFile(path,key,str,&length); printf("str = %s\n",str); ==============================*/ /*写============================= char * path = "D:/Test/3.txt"; char * key = "love"; char * value = "yurisa"; setReadCFGFile(path,key,value); ================================*/ return 0;}====>READCFG.H#ifndef READCFG_H_INCLUDED#define READCFG_H_INCLUDED//读取配置文件int getReadCFGFile(const char * path,const char * key,char * value,int * valuelength);//写入/修改配置文件int setReadCFGFile(const char * path,const char * key,const char * value);#endif // READCFG_H_INCLUDED====>READCFG.C#include <stdlib.h>#include <string.h>#include <ctype.h>#define MAX 1024int getReadCFGFile(const char * path/*in*/,const char * key/*in*/,char * value/*out*/,int * valuelength/*out*/){ FILE * fp = NULL; char * pTmp = NULL; char * pstr = NULL; char BUF[MAX] = {0}; int flag = 0; if ((fp = fopen(path,"r+")) == NULL){ return -1; } while ((pstr = fgets(BUF,MAX,fp)) != NULL){ //判断是否有"="和key是否在这一行 if ((pstr = strchr(BUF,'=')) == NULL || (pstr = strstr(BUF,key)) == NULL){ continue; } flag = 1;//[找到key] //指针移动到value的位置 pTmp = BUF + strlen(BUF) - 1;//"key = value\n"==>"\n" pstr = BUF + strlen(key) + 1; //"key = value\n" ==>"v" //获取value,剔除空格 for (;*pstr == ' ';pstr++); for (;*pTmp == ' ' || *pTmp == '\n';pTmp--); break; } if (!flag){ return -1; } //赋值 *valuelength = (int)(pTmp - pstr) + 1; memcpy(value,pstr,*valuelength); if (fp != NULL){ fclose(fp); } return 0;}int setReadCFGFile(const char * path/*in*/,const char * key/*in*/,const char * value/*in*/){ if(path == NULL || key == NULL || value == NULL){ return -1; } FILE * fp = NULL; char * pstr = NULL; char BUF[MAX] = {0}; char FILEBUF[MAX * 8] = {0}; int length = 0; int flag = 0; if ((fp = fopen(path,"r+")) == NULL){ return -1; } fseek(fp,0,SEEK_END);//文件指针移动到文件末尾 length = ftell(fp); fseek(fp,0,SEEK_SET);//文件指针移动到文件头 if(length > MAX * 8){ return -1; } while ((pstr = fgets(BUF,MAX,fp)) != NULL){ //判断key是否存在 if ((pstr = strstr(BUF,key)) != NULL){ flag = 1; sprintf(BUF,"%s = %s\n",key,value); strcat(FILEBUF,BUF); }else{ strcat(FILEBUF,BUF); } } if (!flag){ sprintf(BUF,"%s = %s\n",key,value); strcat(FILEBUF,BUF); } //关闭文件流并重新写入 if(fp != NULL){ fclose(fp); fp = NULL; } fp = fopen(path,"wt+"); fputs(FILEBUF,fp); if(fp != NULL){ fclose(fp); } return 0;}
0 0
- C基础学习笔记02
- C/C++基础学习笔记
- C语言基础学习笔记
- C、C++基础学习笔记
- 【C#】C#基础学习笔记
- C基础学习笔记01
- C++&C学习笔记(一)(基础)
- 学习笔记—C语言基础篇02
- 学习笔记之C语言基础篇
- C/C++基础 达内学习笔记
- C语言基础学习笔记综合
- 数据结构学习笔记之C指针基础
- Object-c基础编程学习笔记-Foundation
- Object-c基础编程学习笔记-NSString
- Object-c基础编程学习笔记-集合
- Object-c基础编程学习笔记-分类
- Object-c基础编程学习笔记-协议
- Object-c基础编程学习笔记-NSPredicate
- fragment No host的问题
- klist链表链接图
- nginx 防盗链心得
- swiper.js 图片滑动
- Android中变量的命名规范
- C基础学习笔记02
- 每天一条linux ---文件属性详解
- 浏览器主页/启动页被拦截,尤其是火狐浏览器
- hdu 5894 组合Lucas
- 解析到127.0.0.1的域名
- leetCode练习(29)
- Python进阶强化训练之对象迭代与反迭代技巧
- 分页原理以及代码分析
- 用 React.js 写一个最简单的 To-do List 应用