建设简易电子商务网站流程图,湄洲岛网站建设,象山县建设工程招投标网站,网站 国外服务器并非从0开始的c day6二级指针练习-文件读写位运算位逻辑运算符按位取反 ~位于#xff08;AND#xff09;#xff1a;位或#xff08;OR#xff09;#xff1a; |位异或: ^移位运算符左移右移多维数组一维数组数组名一维数组名传入到函数参数中数组指…
并非从0开始的c day6二级指针练习-文件读写位运算位逻辑运算符按位取反 ~位于AND位或OR |位异或: ^移位运算符左移右移多维数组一维数组数组名一维数组名传入到函数参数中数组指针1、先定义出数组的类型在通过类型定义出数组指针2、先定义出数组指针的类型通过类型创建数组指针变量3、直接定义数组指针变量二维数组二维数组的定义二维数组做函数参数二级指针练习-文件读写
需求在代码根目录下新建一个txt文件输入若干行字符读取并一个个输出出来
//获取文件中有效的函数
int getFileLines(FILE * file)
{if (file NULL){return -1;}char buf[1024];int lines 0;while (fgets(buf, 1024, file) ! NULL){lines;//printf(%s\n, buf);}//将文件的光标 置首fseek(file, 0, SEEK_SET);//SEEK_SET//SEEK_CUR//SEEK_ENDreturn lines;
}void readFileData(FILE * file,char ** pArray,int len)
{if (file NULL){return;}if (pArray NULL){return;}if (len 0){return;}char buf[1024] { 0 };int count 0;while (fgets(buf, 1024, file) ! NULL){//计算开辟每个字符串的大小int currentLen strlen(buf)1;//字符串最后字符改为\0buf[strlen(buf) - 1] \0;//开辟堆区空间char * currentP malloc(sizeof(char) * currentLen);//将文件中读取的内容放入到开辟的空间中strcpy(currentP, buf);//将开辟空间的数据放入到我们维护的数组中pArray[count] currentP;//清空bufmemset(buf, 0, 1024);}
}//打印数组
void showFileData(char** pArray, int len)
{for (int i 0; i len; i){printf(%d行的数据为:%s\n, i 1, pArray[i]);}
}//释放堆区空间
void freeSpace(char** pArray, int len)
{for (int i 0; i len; i){if (pArray[i] ! NULL){printf(%s被释放了\n, pArray[i]);free(pArray[i]);pArray[i] NULL;}}free(pArray);pArray NULL;
}void test01()
{//打开文件FILE * file fopen(./test.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, pArray, len);//打印数组showFileData(pArray,len);//释放堆区空间freeSpace(pArray,len);pArray NULL;//关闭文件fclose(file);file NULL;
}FILE * file fopen(“./test.txt”, “r”); 为读取文件的命令r代表读 在getFileLines读取了file指针后指针已经发生了偏移若没有重置直接再次调用会报错 故这里使用memset重置SEEK的三个可选项分别对应当前位置cur、开头set、末尾end
txt文件中内容自带换行故在print的时候不需要手动加\n来换行 若不需要文件自带换行想自己换的话需要在读取的时候将字符串最后一个字符改为\0即可
free的个数要对应malloc的个数free要先free指针底下的内容再释放指针自身要不然底下的东西会变成无法访问的垃圾
位运算
位逻辑运算符
按位取反 ~
一元运算符~ 将每一1变为0将每个0变为1
void test01()
{int num 2;printf(~num %d\n, ~num);// -3//0000 0010~ 1111 1101源码 ~1000 0011 补码
}这样得到的结果为-3因为数据经过取反补码就是符号位转变后加一
位于AND
二进制运算符通过对两个操作数逐位进行比较产生一个新值。对于每个位只有两个操作数的对应位都是1是结果才为1。 同真为真其余为假 void test02()
{int num 123;if ((num 1 ) 0){printf(偶数\n);}else{printf(奇数\n);}
}位或OR | 同假为假其余为真 void test03()
{int num1 5;int num2 3;printf(num1 | num2 %d\n, num1 | num2);
}
可运用于将某个位变为1
位异或: ^ 同样为真不同为假 a00101110 b11000111 r11101001 a^b r a^r b b^r a
void test04() {int num1 5;int num2 9;//实现两个数字交换num1 num1 ^ num2;num2 num1 ^ num2;num1 num1 ^ num2;printf(num1 %d\n, num1);printf(num2 %d\n, num2);}移位运算符
左移
(10001010)2 (00101000) n 代表乘以2^n
void test05()
{int num 20;printf(%d\n, num 3);
}右移 n 代表如果number非负则number除以2^n
void test06()
{int num 20;printf(%d\n, num 1);
}多维数组
一维数组
元素类型角度数组是相同类型的变量的有序集合内存角度连续的一大片内存空间
数组名 void test01()
{int arr[5] { 1,2,3,4,5 };printf(sizeof arr %d\n, sizeof(arr));printf(%d\n, arr);printf(%d\n, arr1);int* p arr;p p 3;printf(%d\n, p[-1]);
}//一维数组的名 是不是指向第一个元素的指针 //对数组名 取地址 可得步长为20 //第一种 对数组名称 sizeof //第二种 对数组名称取地址 步长为整个数组长度 //除了这两种情况以外一维数组名 指向数组第一个元素的指针
//指针常量 int * const p 常量指针const int * p //前者为指针常量要指针指向的值才能修改后者为常量指针指针指向的值不能改但指针本身能改
//数组名 要是指针常量 //arr NULL;//指针的指向是不可以修改的 //arr[0] 100;//指针指向的值是可以修改的
//如果将指针偏移过则访问的时候可以为负数
一维数组名传入到函数参数中
void printArray(int arr[],int len)//int arr[] 等价于 int *arr
{for (int i 0; i len; i)printf(%d\n, arr[i]);//等同于*(arri)
}void test02()
{int arr[5] { 1,2,3,4,5 };int len sizeof(arr) / sizeof(int);printArray(arr, len);
}数组指针
1、先定义出数组的类型在通过类型定义出数组指针
void test01()
{int arr[5] { 1,2,3,4,5 };typedef int(ARRAY_TYPE)[5];//ARRAY_TYPE是一个有5个int元素的数组的类型ARRAY_TYPE* arrP arr;//*arrP arrfor (int i 0; i 5; i){printf(%d\n, (*arrP)[i]);}
}2、先定义出数组指针的类型通过类型创建数组指针变量
void test02()
{int arr[5] { 1,2,3,4,5 };typedef int(*ARRAY_TYPE)[5];ARRAY_TYPE arrp arr;//可以使用但是比较麻烦printf(%d\n, *arrp[0]);
}3、直接定义数组指针变量
void test03()
{int arr[5] { 1,2,3,4,5 };//语法数组元素类型(*数组指针变量名称)[元素个数]int(* p)[5] arr;//*p arrfor (int i 0; i 5; i){printf(%d\n, (*p)[i]);}
}二维数组
二维数组的定义
void test01()
{int arr[3][3] {{1,2,3},{2,3,4},{4,5,6}};int arr2[3][3] { 1,2,3,4,5,6,7,8,9 };int arr3[][3] { 1,2,3,4,5,6,7,8,9 };
}
三种定义方法第一种可读性最强
二维数组做函数参数
void printArray(int (*pArray)[3],int len1,int len2)//(*pArray)[3] 也可以表述为pArr[3][3]更加易读
{for (int i 0; i len1; i){for (int j 0; j len2; j){printf(%d , pArray[i][j]);printf(%d , *(*(pArrayi)j));}printf(\n);}
}void test02()
{int arr[3][3] {{1,2,3},{4,5,6},{7,8,9}};printArray(arr, 3, 3);//sizeofprintf(sizeof arr %d\n, sizeof(arr));//取地址printf(%d\n, arr);printf(%d\n, arr 1);int(* p)[3][3] arr;
}sizeof获取整个二维数组占用内存大小 取地址步长为整个二维数组长度 除了这两种情况二维数组名指向第一行数组的数组指针