侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

C 语言函数手册

2023-11-30 星期四 / 0 评论 / 0 点赞 / 56 阅读 / 11022 字

int main (int argc, char * argv[]) argc 是命令行总的参数个数,记录了用户在运行程序的命令行中输入的参数的个数; argv[] 存放了命令行输入的全部字符

int main (int argc, char * argv[])

    argc 是命令行总的参数个数,记录了用户在运行程序的命令行中输入的参数的个数;

    argv[] 存放了命令行输入的全部字符串,包含 argc 个参数,其中第 0 个参数是程序的全名,至少有一个字符指针,指向程序中可执行文件的文件名,有些版本的编译器中还包括程序文件所在的路径;

    程序中得到这些参数的工作是编译器完成的,编译器将输入参数的信息放入 main 函数的参数列表中,赋值过程也是编译器完成的。

 

stat.h

    导入 sys/stat.h 头文件可以获取文件的属性,其中声明了一个重要的结构体 stat:

struct stat{mode_t st_mode; //文件类型和权限信息ino_t st_ino; //i结点标识dev_t st_dev; //device number (file system)dev_t st_rdev; //device number for special filesnlink_t st_nlink; //符号链接数uid_t st_uid; //用户IDgid_t st_gid; //组IDoff_t st_size; //size in bytes,for regular filestime_t st_st_atime; //最后一次访问的时间time_t st_mtime; //文件内容最后一次被更改的时间time_t st_ctime; //文件结构最后一次被更改的时间blksize_t st_blksize; //best I/O block sizeblkcnt_t st_blocks; //number of disk blocks allocated};

    文件类型包括了:普通文件、目录文件、块特殊文件、字符特殊文件、套接字、FIFO、符号链接,文件类型信息包含在 stat 结构的 st_mode 成员中,可以通过宏确定文件类型,这些宏是 stat 结构中的 st_mode 成员:S_ISREG()、S_ISDIR()、S_ISCHR()、S_ISBLK()、S_ISFIFO()、S_ISSOCK()

    S_TYPEISMQ() 表示消息队列、S_TYPEISSEM() 表示信号量、S_TYPEISSHM() 表示共享存储对象。

    进程每次打开,创建或删除一个文件时,内核就进行文件访问权限测试,测试可能涉及文件所有者(st_uid 和 st_gid),进行的有效 ID 以及进程的附加组 ID:

    (1).若进程的有效用户ID是0(超级用户),则允许访问。
    (2).若进程的有效用户ID等于文件的有效用户ID,那么若所在者适当的访问权限被设置,则允许访问。
    (3).若进程的有效组ID或进程的附加组ID之一等于文件的组ID,那么组适当的访问权限位被设置,则允许访问。
    (4).若其他用户适当的访问权限位被设置,则允许访问。
按顺序执行以上四步。

    

stat()、lstat()、fstat()

    stat()、lstat()、fstat() 函数都是获取文件(普通文件、目录、管道、socket、字符、块)的属性。

    int stat(const  char *restrict  pathname, struct stat *restrict buf); 提供文件名字,获取文件对应属性;

    int fstat(int  filedes,  struct stat *buf); 通过文件描述符,获取文件对应的属性;

    int lstat(const char *restrict pathname, struct stat *restrict buf); 连接文件描述符,获取文件属性

    fstat() 用来将参数 filedes 所指向的文件状态复制到参数 buf 所指向的结构中(structstat),fstat() 与 stat() 作用完全相同,不同之处在于传入的参数为已打开的文件描述符

    返回值:执行成功返回 0,失败返回 -1,错误代码保存在 errno;

#include <stdio.h>#include <stdlib.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>main(){    struct stat buf;    int fd;    fd = open("/etc/passwd", O_RDONLY);    fstat(fd, &buf);    fstat(fd, &buf);    printf("/etc/passwd file size = %d/n", (int)(buf.st_size));}

 

malloc()、calloc()、realloc()、free()、memcpy()  

    头文件 malloc.h(alloc.h 两个头文件内容相同的)

    函数声明:extern void *malloc(unsigned int num_bytes);

    分配长度为 num_bytes 字节的内存块,分配成功返回指向被分配内存的指针,否则返回空指针 NULL。

#include <stdio.h>#include <malloc.h>int main(){    char *p;    p = (char *)malloc(100);    if(p)        printf("Memory Allocated at %x/n", p);    else        printf("Not Enough Memory!/n");    free(p);    return 0;}

    malloc 向系统申请分配指定 size 个字节的内存空间,返回类型是 void* 类型(未确定类型的指针,C、C++规定,void *类型可以强制转化为任何其它类型的指针)

    当内存不再使用时,应使用 free() 函数将内存块释放;
    void free(void *ptr); //#include <stdlib.h> 或 #include <malloc.h>

    释放 ptr 指向的存储空间,被释放的空间通常被送入可用存储区池,以后可在调用 malloc、realloc 以及 realloc 函数再分配(连续两次 free 会报错,malloc 次数要和 free 此时相对)

    free(str) 后指针仍然指向原来的堆地址,即你仍然可以继续使用,但很危险,因为操作系统已经认为这块内存可以使用,会分配给其它程序,这种情况就叫“野指针”(指程序员或操作者不能控制的指针,不是 NULL 指针,而是指向“垃圾”的指针),最好 free() 了以后再置空,str = NULL,即放弃使用它;

    

    calloc() 函数用来动态地分配内存空间并初始化为 0:

    void * calloc(size_t num, size_t size);

    calloc() 在内存中动态地分配 num 个长度为 size 的连续空间,并将每一个字节都初始化为 0,所以它的结构是分配了 num*size 个字节长度的内存空间,并且每个字节的值都是 0。

    分配成功返回指向该内存的地址,失败则返回 NULL。

 

    realloc() 函数用来更改已经配置的内存空间,即更改由 malloc() 函数分配的内存空间大小,如果将分配的内存减少,realloc 仅仅是改变索引的信息;

    realloc(void * __ptr, size_t __size)

    如果是将内存扩大:

    1)如果当前内存段后面有需要的内存空间,则直接扩展这段内存空间,realloc() 将返回原指针;

    2)如果当前内存段后面的空闲字节不够,那么就使用堆中第一个能满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据块释放掉,返回新的内存块位置。

    3)如果申请失败,将返回 NULL,此时,原来的指针仍然有效;

    如果调用成功,不管当前内存段后面的空闲空间是否满足要求,都会释放原来的指针,重新返回一个指针,虽然返回的指针有可能和原来的指针一样,即不能再次释放掉原来的指针。(如果当前内存段后有足够的空间,则返回原来的指针,如果没有足够的空间,会返回一个新的内存段指针)

 

    #include <string.h>

    void * memcpy(void *destin, const void *src, size_t n);

    有 src 指向地址为起始地址的连续 n 个字节的数据复制到以 destin 指向地址为起始地址的空间内,返回一个指向 dest 的指针。

    source 和 destin 所指内存区域不能重置,函数返回指向 distin 的指针;

 

errno.h    

    C 语言错误处理,提供了宏 errno、 perror() 函数和 strerrno() 函数

    perror() 函数显示的字符串传递,然后接一个冒号,一个空格,然后目前 errno 值得文字表述;

    strerrno() 函数返回一个指针,指向目前的 errno 值的文字描述。

    errno 在头文件 errno.h 中定义

#ifndef errnoextern int errno;#endif#define EDOM 33 /* Math argument out of domain of function */

    errno 常见用法是在调用库函数之前清零,随后再进行检查。

 

二级指针

    看代码的过程中,很多地方遇到了类似这样的声明 void ** A = &B,A(即 B 的地址)是指向指针的指针,称为二级指针,用于存放二级指针的变量称为二级指针变量,根据 B 的情况不同,二级指针又分为指向指针变量的指针和指向数组的指针。

    任何值都有地址,一级指针的值虽然是地址,但这个地址做为一个值亦需要空间来存放,是空间就具有地址,这就是存放地址这一值的空间所具有的地址,二级指针就是为了获取这个地址。

    数组也是一种指针,指针+1 的操作类似于数组下标加一,指针加一实际上是相对于声明指针时类型而言的,如果声明指针时为 int 类型,那么指针加一,实际上移动了 4 个字符位。

 

    在 C 和 C++ 中,void 代表一种抽象的无类型,任何变量都应该是有类型的,void * 即为无类型指针,void * 可以指向任何类型的数据,因为 void * 的声明指针类型可以转变成任何其它类型。

 

内存管理函数 | 内存控制函数   

    

函数 说明
getpagesize() 取得内存页大小
mmap() 建立内存映射
munmap() 接触内存映射
memccpy() 复制内存中的内容
memchr() 在内存中查找特定字符
memcmp() 比较内存前 n 个字节

附带 C 语言函数手册:http://c.biancheng.net/cpp/u/hs3/

 

 

广告 广告

评论区