######################################## C ######################################## .. note:: 本节讲述 C 语言部分内容。施行标准为 C99 Const **************************************** const 是在编译阶段实现的,并且只对被const限定的变量进行检查。这意味着你可以另外设置一个指针来绕过限制 表达式短路 **************************************** 例如: - 对于 ``表达式1&&表达式2`` 若 **计算出表达式 1 为 0** ,则无需对表达式 2 求值,表达式 2 被短路 - 对于 ``表达式1||表达式2`` 若 **计算出表达式 1 非 0** ,则表达式 2 被短路 空指针 **************************************** 对一个NULL指针解引用是一个违法的操作。会直接无法通过编译 查找文件 **************************************** C查找文件需要:头文件 ``direct.h`` 、 ``io.h`` 结构体 ``struct _finddata_t`` 和函数 ``_findfirst`` 、 ``_findnext`` 、 ``_fineclose`` 。 结构体 ``struct _finddata_t`` 被包含在头文件 ``io.h`` 中,其储存了文件的各种信息,完整定义如下: .. code:: c struct _finddata_t{ unsigned attrib; //文件属性的储存位置 time_t time_create; //文件被创建时间 time_t time_access; //文件最后一次被访问的时间 time_t time_write; //文件最后一次被修改时间 _fsize_t size; //文件大小(字节) char name[_MAX_FNAME]; //文件名 } .. unsigned attrib:文件属性的储存位置。文件属性使用位来表示,包括:_A_ARCH(存档)、 _A_HIDDEN(隐藏)、_A_NORMAL(正常)、_A_RDONLY(只读)、_A_SUBDIR(文件夹)、_A_SYSTEM(系统)。 这些都是定义在头文件中的宏,可以直接被使用。多个属性之间通过异或组合。 _findfirst ----------- ​ 函数 ``long _findfirst( char *filespec, struct _finddata_t *fileinfo );`` ​ 函数的第一个参数用来指定文件名(允许通配符),第二个参数是一个用来存储信息的结构体,当查找失败时,返回0。查找成功时,返回一个可用于_findnext函数的文件句柄。 _findnext ---------- ​ 函数**int _findnext( long handle, struct _finddata_t *fileinfo );** ​ 第一个参数就是_findfirst返回的long型句柄。当查找成功时,返回值为0,否则返回-1; _findclose ----------- ​ 函数**int _findclose(long handle);**用来结束查找。 示例: ------ .. code:: c #include #include int main(void){ long hFIle; struct _finddata_t fileinfo; if((hFIle=_findfirst("*.*",&fileinfo))!=-1L) { do{ if (!(fileinfo.attrib & _A_SUBDIR)) printf("文件名:%-30s" "文件大小:%-15d" "字节\n" ,fileinfo.name ,fileinfo.size); }while (_findnext(hFIle,&fileinfo)==0); _findclose(hFIle); } return 0; } 输出结果如下:: C::\Users\Dragon\CLionProjects\Test\_For_C11\cmake-build-debug\Test\_For_C11.exe 文件名:CMakeCache.txt 文件大小:21225 字节 文件名:cmake_install.cmake 文件大小:1483 字节 文件名:Makefile 文件大小:5290 字节 文件名:Test_For_C11.cbp 文件大小:5975 字节 文件名:Test_For_C11.exe 文件大小:43262 字节 Process finished with exit code 0 目录操作 **************************************** 头文件: ``sdtlib.h`` .. code:: c #include //_getcwd(), _chdir() #include //_finddata_t, _findfirst(), _findnext(), _findclose() #include #include //_MAX_PATH, system() void main(void) { char buffer[_MAX_PATH]; //获取当前工作目录 if (_getcwd(buffer, _MAX_PATH) == NULL) perror("_getcwd error"); else printf("%s\n", buffer); //更改当前工作目录 - 相对路径方式 if (_chdir("./temp")) printf("Unable to locate the directory you specified \n"); else { _getcwd(buffer, _MAX_PATH); //重新获取当前工作目录 printf("The CWD is: %s\n", buffer); //输出当前工作目录 system("type hello.c"); // system用于执行命令行指令 } //更改当前工作目录 - 绝对路径方式 if (_chdir("F:\\temp")) //双反斜杠处理转义字符'\' printf("Unable to locate the directory you specified \n"); else { _getcwd(buffer, _MAX_PATH); printf("\n\nThe CWD is: %s\n", buffer); system("dir *.*"); } //查找当前目录中符合要求的文件, 并输出文件的相关信息 long hFile; _finddata_t fileinfo; if ((hFile = _findfirst("*.c", &fileinfo)) != -1L) { do { if (!(fileinfo.attrib & _A_SUBDIR)) //检查是不是目录, 如果不是,则进行处理 { printf("%s, %ul bytes\n", fileinfo.name, fileinfo.size); } } while (_findnext(hFile, &fileinfo) == 0); _findclose(hFile); } } 删除文件 **************************************** 头文件要求: ``stdio.h`` 函数原型: ``int remove(const char * filename);`` 可变参数 [#parm] **************************************** 有时,您可能会碰到这样的情况,您希望函数带有可变数量的参数,而不是预定义数量的参数。C 语言为这种情况提供了一个解决方案,它允许您定义一个函数,能根据具体的需求接受可变数量的参数。下面的实例演示了这种函数的定义。 .. code:: cpp int func(int, ... ){ . . . } int main() { func(2, 2, 3); func(3, 2, 3, 4); } 请注意,函数 **func()** 最后一个参数写成省略号,即三个点号( **…** ),省略号之前的那个参数是 int ,代表了要传递的可变参数的总数。为了使用这个功能,您需要包含 **stdarg.h** ,该文件提供了实现可变参数功能的函数和宏。具体步骤如下: #. 定义一个函数,最后一个参数为省略号,省略号前面可以设置自定义参数。 #. 在函数定义中创建一个 **va_list** 类型变量,该类型是在 stdarg.h 头文件中定义的。 #. 使用 **int** 参数和 **va_start** 宏来初始化 **va_list** 变量为一个参数列表。宏 va_start 是在 stdarg.h 头文件中定义的。 #. 使用 **va_arg** 宏和 **va_list** 变量来访问参数列表中的每个项。 #. 使用宏 **va_end** 来清理赋予 **va_list** 变量的内存。 现在让我们按照上面的步骤,来编写一个带有可变数量参数的函数,并返回它们的平均值: .. code:: cpp #include #include double average(int num,...){ va_list valist; double sum = 0.0; int i; // 为 num 个参数初始化 valist va_start(valist, num); // 访问所有赋给 valist 的参数 for (i = 0; i < num; i++) { sum += va_arg(valist, int); } // 清理为 valist 保留的内存 va_end(valist); return sum/num; } int main(){ printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5)); printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15)); } 当上面的代码被编译和执行时,它会产生下列结果。应该指出的是,函数 **average()** 被调用两次,每次第一个参数都是表示被传的可变参数的总数。省略号被用来传递可变数量的参数。 输出结果为:: Average of 2, 3, 4, 5 = 3.500000 Average of 5, 10, 15 = 10.000000 .. [#parm] `C 可变参数 `_