C

备注

本节讲述 C 语言部分内容。施行标准为 C99

Const

const 是在编译阶段实现的,并且只对被const限定的变量进行检查。这意味着你可以另外设置一个指针来绕过限制

表达式短路

例如:

  • 对于 表达式1&&表达式2计算出表达式 1 为 0 ,则无需对表达式 2 求值,表达式 2 被短路

  • 对于 表达式1||表达式2计算出表达式 1 非 0 ,则表达式 2 被短路

空指针

对一个NULL指针解引用是一个违法的操作。会直接无法通过编译

查找文件

C查找文件需要:头文件 direct.hio.h 结构体 struct _finddata_t 和函数 _findfirst_findnext_fineclose

结构体 struct _finddata_t 被包含在头文件 io.h 中,其储存了文件的各种信息,完整定义如下:

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);**用来结束查找。

示例:

#include<stdio.h>
#include <direct.h>

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

#include <direct.h> //_getcwd(), _chdir()
#include <io.h>     //_finddata_t, _findfirst(), _findnext(), _findclose()
#include <stdio.h>
#include <stdlib.h> //_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 语言为这种情况提供了一个解决方案,它允许您定义一个函数,能根据具体的需求接受可变数量的参数。下面的实例演示了这种函数的定义。

int func(int, ... ){
   .
   .
   .
}

int main()
{
   func(2, 2, 3);
   func(3, 2, 3, 4);
}

请注意,函数 func() 最后一个参数写成省略号,即三个点号( ),省略号之前的那个参数是 int ,代表了要传递的可变参数的总数。为了使用这个功能,您需要包含 stdarg.h ,该文件提供了实现可变参数功能的函数和宏。具体步骤如下:

  1. 定义一个函数,最后一个参数为省略号,省略号前面可以设置自定义参数。

  2. 在函数定义中创建一个 va_list 类型变量,该类型是在 stdarg.h 头文件中定义的。

  3. 使用 int 参数和 va_start 宏来初始化 va_list 变量为一个参数列表。宏 va_start 是在 stdarg.h 头文件中定义的。

  4. 使用 va_arg 宏和 va_list 变量来访问参数列表中的每个项。

  5. 使用宏 va_end 来清理赋予 va_list 变量的内存。

现在让我们按照上面的步骤,来编写一个带有可变数量参数的函数,并返回它们的平均值:

#include <stdio.h>
#include <stdarg.h>

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
1

C 可变参数