函数原理解析

目录

sscanf和sprintf:

snprintf()

fopen

fprintf()

fileno:

perror:

getopt:

和时间有关的函数:

str开头系列函数:

strcmp():

stricmp():

strchr:

strcmp():

strcat():

strncat():

strstr(str1,str2):

strpbrk()函数原型:

strcasecmp()

strncasecmp()

strspn:

文件操作类函数:

creat:

open:

lseek:

exit()

string类的函数:

如何比较两个string字符串:

如何从一个string字符串中抽取出需要的字符串:

substr函数:

string的数值转换:

如何判断string对象是否为空:

对string源对象字符串进行插入,删除:


sscanf和sprintf:

int sscanf (const char *str,const char * format,........);    
按照指定格式在str中找到字符串,并放入后边的地址

从这个位置——格式符所在位置对应字符串中的位置,如果只有格式符就表示从头开始。
%[n]s:从这个位置读取指定宽度的数据
%[aBc]:从这个位置读取aBc中的一个,如果这个位置的第一个匹配失败,就不再匹配了,如果匹配成功,继续匹配直到匹配到不aBc中的字符为止
%[a-z]:从这个位置读取a到z中的任意字符,直到遇到不是a到z的字符
%[^a-z]:从这个位置读取数据,直到遇到a到z中的任意一个字符为止,读取的数据不包括最后检测的a到z的字符
%[^a]:原理同上,只是这里指定停止的字符为a
%*s:忽略字符串(跳过)
%*d:忽略整形数据
%*[^@]:从这个位置忽略数据直到遇到字符@,@不忽略
(
%*[^a]:忽略数据直到a
%[^a]:读取数据直到a
)
%*[@]:忽略字符@

只要不是格式字符都要放入[  ]

sscanf遇到空格自动停止:

int main()
{
        char* p="get http://www.baidu.com/dir/defualt http/1.1";
        char filepath[100];
        sscanf(p,"%s",filepath);
        cout<<filepath<<endl;
        sscanf(p,"get %s",filepath);
        cout<<filepath<<endl;
        sscanf(p,"get http://www.baidu.com/dir/defualt %s",filepath);
        cout<<filepath<<endl;

        return 0;
}
 

get
http://www.baidu.com/dir/defualt
http/1.1
 

sscanf可参考

sprintf( char *buffer, const char *format [, argument,...] );
sprintf的第一个参数是目的字符串
sprintf的作用是将一个格式化的字符串输出到一个目的字符串中,而printf是将一个格式化的字符串输出到屏幕。第二个格式字符可以有多个,对应的,后面的参数也可以有多个。

可以使用sprintf实现把整形数据存放到char 数组中。      
  int num=123343;     
     char buf[100];        
     sprintf(buf,"%d",num);       
      int len=strlen(buf);     
         for(int i=0;i<len;i++)                            

          printf("%d=%c\n",i,buf[i]);


snprintf()

int snprintf(char *str, size_t size, const char *format, ...);

将...中的字符串按照format中的格式转化,然后取所有转化后的数据中的size个字节存入str代表的地址中,按顺序从起始地址依次往后存放。
1,如果数据少于size,就补0.
2,如果数据多余size,取size-1个,最后一个是'\0'
返回的是所有原来的字符串转化之后的字符个数。
失败返回-1.
注意:str是char*类型(数组名也是),

fopen

FILE *fopen(const char *pathname, const char *mode);
打开一个文件,并将一个流和这个文件相关联

FILE是一个结构体类型,称为文件指针,fopen如果成功则返回一个FILE文件指针,指向打开文件的流。

失败返回NULL,置errno

权限:

1,只有r,r+要求必须文件存在。

2,没有+表示单独权限,有+表示另一个权限也要。

链接

popen和pclose

链接

开启一个进程执行指定的脚本命令,通过返回的IO流可以读取指定命令执行的结果。

fprintf()

int fprintf(FILE *stream, const char *format, ...);

printf是将数据输出到标准输出

fprintf是将数据输出到文件指针所指向的流,将数据输入到文件中。

fileno:

int fileno(FILE *stream);
将文件指针转为文件描述符

access:

int access(const char* pathname, int mode);

参数介绍:

    pathname 是文件的路径名+文件名

    mode:指定access的作用,取值如下

F_OK 值为0,判断文件是否存在
 
X_OK 值为1,判断对文件是可执行权限
 
W_OK 值为2,判断对文件是否有写权限
 
R_OK 值为4,判断对文件是否有读权限
 
注:后三种可以使用或“|”的方式,一起使用,如W_OK|R_OK
返回值:成功0,失败-1

perror:


  void perror(const char *s); 
  perror()用来将上一个函数发生错误的原因输出到标准设备(stderr)。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。。此错误原因依照全局变量errno的值来决定要输出的字符串。

perror()中的字符串不用加:,因为系统输出的信息就自带冒号:

getopt:

int getopt(int argc, char * const argv[],const char *optstring);

 getopt()函数将传递给mian()函数的argc,argv作为参数,同时接受字符串参数optstring -

和时间有关的函数:

time_t T=time(NULL):获取系统当前时间

ctime(T):把时间转为字符串

字符操作函数

getchar(void)

从缓冲区读取一个字符,包括‘\n’

注意:键盘--》缓冲区--》getchar

getchar和scanf的注意事项

注意:无论是scanf还是getchar循环获取字符时,都要再利用一个getchar队'\n'进行过滤,否则下一次读取到的不是再次输入缓冲区的数据,而是'\n'

getc

int getc(FILE *stream);

getchar()=getc(stdin)

getchar只能从标准输入流获取

getc可以从所有的文件流获取一个字符

       int getc(FILE *stream);

       int getchar(void);
 

这两个函数返回的字符强转为Int型,赋值时,结构又变为charxing

如何获取文件流:

putc

int put(char c,FILE* stream)

从标准输入获取一个字符,并输入stream流代表的文件

putchar()

putchar(char c)

输出字符c到显示屏

puts()

int puts(const char *s);

输出字符串,s可以是数组名

gets()

获取一组字符串

int gets(const char *s);

str开头系列函数:

字符串的操作默认到'\0'停止,如果一个字符串中,中间中间含有'\0',则操作系统识别到'\0'就停止了

字符串是连续存储在连续地址中的,如果将期中某个字符换位'\0',则一个字符串就变为了两个。

strcmp():

区分大小写,比较字符串

stricmp():

不区分大小写比较字符串

stricmp是windows中的,linux中用不了

strcpy()

char *strcpy(char *dest, const char *src);

将src指向的字符串复制给dest指针

char *strncpy(char *dest, const char *src, size_t n);
将src指向的字符串的前n个字符复制给dest指针

.如果src的长度小于n,strncpy()会向dest写入额外的空字节,以确保总共写入n个字节。

strcpy():

char *strcpy(char *dest, const char *src);

实现的原理就是将一个地址中的字符串复制到另一个地址中去。

strncpy()

char *strncpy(char *dest, const char *src, size_t n);
 

The  strcpy() function copies the string pointed to by src, including the terminating null byte ('\0'), to the buffer pointed to by dest.  The strings may not overlap(重复,覆盖), and the destination string dest must be large  enough to receive the copy.  Beware of buffer overruns(超出范围)!  (See BUGS.)

       The  strncpy()  function  is  similar, except that at most n bytes of src are copied.  Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated. If the length of src is less than n, strncpy() writes additional null bytes to dest to ensure(确保) that a total  of  n bytes are written.
 

strcat():

char *strcat(char *dest, const char *src);

原理:地址

strncat():

char *strncat(char *dest, const char *src, size_t n);
原理:地址

把src所指字符串的前n个字符添加到dest结尾处(默认覆盖dest结尾处的'\0')并添加'\0'

strchr:

寻找字符在字符串中首次出现的位置,并返回这个位置的地址
如果没有,返回NULL

strstr(str1,str2):

功能:在字符串str1中寻找字符串str2,并返回字符串首字符地址。

注意:返回的是str2的首地址,这字符之后的地址依然是连续地址

获得str2的地址之后,再利用sscanf取出需要的部分字符。

可用于http中检测文件类型

strpbrk()函数原型:

char *strpbrk(const char *s, const char *accept);

函数的作用是:函数检索两个字符串中首个相同字符的位置

如果accept,s含有相同的字符,那么返回指向s中第一个相同字符的指针,否则返回NULL。

注意:

1,strpbrk()不会对结束符'\0'进行检索。

2,如果输出返回指针的内容,则会输出该指针所指地址以及之后的所有内容。

strcasecmp()


1.功能:忽略大小写比较字符串
2.头文件《string.h》
3. 函数说明 strcasecmp()用来比较参数s1和s2字符串,比较时会自动忽略大小写的差异
4.  返回值 :若参数s1和s2字符串相同则返回0。s1长度大于s2长度则返回大于0 的值,s1 长度若小于s2 长度则返回小于0的值

strcasecmp只在linux中提供,相当于windows中的stricmp

strncasecmp()

用来比较参数s1和s2字符串前n个字符,比较时会自动忽略大小写的差异返回值 :若参数s1和s2字符串相同则返回0 s1若大于s2则返回大于0的值 s1若小于s2则返回小于0的值

strspn:(找找看有几对夫妻)

size_t strspn(const char *str, const char *accept)
从str起始地址开始拿一个一个的字符去accept中寻找有没有相同字符,有一个就统计一个,直到统计完毕,或者直到str中的某个字符在accpet中找不到为止,返回可以找到的连续字符的个数。

strspn(s1,s2)组团找老婆的原则:s1中都是老公,s2中都是老婆。让s1中的老公从第一个开始,去s2中找自己老婆,一对找到成功,记录一次,如果中途有一个男的老婆不在s2里,那就暂停寻找,函数返回之前之前寻找成功的次数。

源码:
size_t strspn(const char *str, const char *accept)
{
const char *p = NULL;
const char *a = NULL;
size_t count = 0;
for (p = str; *p != ‘\0’; ++p)
{
for (a = accept; *a != ‘\0’; ++a)
{
if (*p == *a)
{
++count;
break;
}
}
if (*a == ‘\0’)
{
return count;
}
}
return count;
}

strcpy(str1,str2):字符串复制,str1内存必须大于str2,str1必须是数组名,str2可以是数组名也可以是字符串常量
如果str已有字符,则被覆盖。

strncpy():

strlen():不包括’\0’。

strlwr()转为小写
strupr()转为大写

在字符串中寻找指定字符串

url=https:/\/\/\/\//\\www.baidu.com变为url=https://www.baidu.com

方法1:

strpbrk():寻找到第一个/的地址;

sscanf(url,"%[/\]")

字符串分割函数--strtok()

c/c++中没有split函数

       #include <string.h>

       char *strtok(char *str, const char *delim);

str是被分割字符串,delim是用于分割的字符,可以是多个字符,每一个字符都作为分割字符

#include <string>
#include "stdio.h"

int main ()
{
    char str[] ="a,b,c,d*e";
    const char * split = ",";
    char * p;
    p = strtok (str,split);
    while(p!=NULL) {
        printf ("%s\n",p);
        p = strtok(NULL,split);
    } 

    return 0;
}

输出:

a

b

c

d*e

原理:只需要在第一次使用的时候传入被分割字符串地址,之后就不用传入,用null代替,函数会自动不断往后分割,直到最后分割完成返回null

自定义字符串分割的lambda表达式后缀函数

#include <iostream>
#include <string>
#include <vector>
using namespace std;
auto split = [](const string p, const char c)->vector<string> {
    vector<string> res;
    string tmp;

    for (char n : p) {
        if (n == c) {
            res.push_back(tmp);
            tmp.clear();
        }
        else tmp.push_back(n);
    }
    if (!tmp.empty()) res.push_back(tmp);

    return res;
};
int main() {
    string str = "aa,bbbb,cccc,dddd,";
    vector<string> nums = split(str, ',');

    for(string s:nums)
        cout << s<< endl;
    
    return 0;
}

stat()

头文件:

#include "sys/stat.h"

#include <unistd.h>

struct stat:
主要在HTTP中使用。

struct stat  
{   
    dev_t       st_dev;     /* ID of device containing file -文件所在设备的ID*/  
    ino_t       st_ino;     /* inode number -inode节点号*/    
    mode_t      st_mode;    /* 目标对应的类型模式,权限,文件或者目录等*/    
    nlink_t     st_nlink;   /* number of hard links -链向此文件的连接数(硬连接)*/    
    uid_t       st_uid;     /* user ID of owner -user id*/    
    gid_t       st_gid;     /* group ID of owner - group id*/    
    dev_t       st_rdev;    /* device ID (if special file) -设备号,针对设备文件*/    
    off_t       st_size;    /* total size, in bytes -文件大小,字节为单位*/    
    blksize_t   st_blksize; /* blocksize for filesystem I/O -系统块的大小*/    
    blkcnt_t    st_blocks;  /* number of blocks allocated -文件所占块数*/    
    time_t      st_atime;   /* time of last access -最近存取时间*/    
    time_t      st_mtime;   /* time of last modification -最近修改时间*/    
    time_t      st_ctime;   /* time of last status change - */    
};  

在POSIX中定义了检查这些目标对象类型的宏定义:
    S_ISLNK (st_mode)    判断是否为符号连接
    S_ISREG (st_mode)    是否为一般文件
    S_ISDIR (st_mode)    是否为目录
    S_ISCHR (st_mode)    是否为字符装置文件
    S_ISBLK (st_mode)       是否为先进先出
    S_ISSOCK (st_mode)   是否为socket

    S_IFMT   0170000    文件类型的位遮罩
    S_IFSOCK 0140000    套接字
    S_IFLNK 0120000     符号连接
    S_IFREG 0100000     一般文件
    S_IFBLK 0060000     区块装置
    S_IFDIR 0040000     目录
    S_IFCHR 0020000     字符装置
    S_IFIFO 0010000     先进先出

    S_ISUID 04000     文件的(set user-id on execution)位
    S_ISGID 02000     文件的(set group-id on execution)位
    S_ISVTX 01000     文件的sticky位

    S_IRUSR(S_IREAD) 00400     文件所有者具可读取权限
    S_IWUSR(S_IWRITE)00200     文件所有者具可写入权限
    S_IXUSR(S_IEXEC) 00100     文件所有者具可执行权限

    S_IRGRP 00040             用户组具可读取权限
    S_IWGRP 00020             用户组具可写入权限
    S_IXGRP 00010             用户组具可执行权限

    S_IROTH 00004             其他用户具可读取权限
    S_IWOTH 00002             其他用户具可写入权限
    S_IXOTH 00001             其他用户具可执行权限

    上述的文件类型在POSIX中定义了检查这些类型的宏定义:
    S_ISLNK (st_mode)    判断是否为符号连接
    S_ISREG (st_mode)    是否为一般文件
    S_ISDIR (st_mode)    是否为目录
    S_ISCHR (st_mode)    是否为字符装置文件
    S_ISBLK (s3e)        是否为先进先出
    S_ISSOCK (st_mode)   是否为socket
若一目录具有sticky位(S_ISVTX),则表示在此目录下的文件
只能被该文件所有者、此目录所有者或root来删除或改名,
在linux中,最典型的就是这个/tmp目录啦。

对应的使用函数:
int stat(const char *filepath, struct stat *buf)

获取filepath指定文件信息(结构体中信息),存放在struct stat指针对象中。
成功返回0,失败返回-1

对文件权限和文件/目录的属性检查

        if(stat(file_buffer,&m_file_stat)<0)
                return NO_RESOURCE;
        if(!m_file_stat.st_mode&S_IROTH)
                return FORBIDDEN_REQUEST;
        if(S_ISDIR(m_file_stat.st_mode))
                return BAD_REQUEST;
1,权限检查------与运算

2,文件/目录属性,用宏函数,传递结构体的st_mode成员

文件操作类函数:


creat:


int creat(const char *pathname, mode_t mode);
创建文件。

open:


 int open(const char *pathname, int flags);
 int open(const char *pathname, int flags, mode_t mode);

这两个函数的区别:

第一个是用来打开已经存在的文件的,不需要权限设置。

第二个是用来可能需要创建一个文件是,给新创建的文件设置权限的。

O_RDONLY:   只读打开
  O_WRONLY:   只写打开
  O_RDWR:     读,写打开
这三个常量,必须制定一个且只能指定一个
  O_CREAT:    若文件不存在,则创建它,需要使
              用mode选项。来指明新文件的访问权限
  O_APPEND:   追加写,如果文件已经有内容,这次打开文件所
              写的数据附加到文件的末尾而不覆盖原来的内容

O_TRUNC 若文件存在并且以可写的方式打开时, 此旗标会令文件长度清为0, 而原来存于该文件的资料也会消失.

O_SYNC:文件数据和所有文件元数据同步写入磁盘,防止数据丢失;

lseek:


重定位文件指针(光标)在文件中的位置,seek---寻找,定位。

off_t lseek(int fd, off_t offset, int whence);

offset:可正可负

光标的偏移位置是whence指定的位置加上offset的值。

SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2.
 

ftruncate()

链接

read类函数

read

readline()

#include <stdio.h>
       #include <readline/readline.h>
       #include <readline/history.h>

       char *
       readline (const char *prompt);

DESCRIPTION
       readline will read a line from the terminal and return it, using prompt(提示符) as a prompt.  If prompt is NULL or the empty string, no prompt is issued. 

同shell的read -p ''prompt"

注意:

1,使用前要先下载readline库-----sudo apt install libreadline-dev

2,使用时要连接readline库

g++ readfile.cpp -o readfile.out -l readline

#include <iostream>
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
using namespace std;

int main(int argc,char** argv){
        //fd=open(*argv[0]);
        string lineStr=string(readline("Please input:"));
        cout<<lineStr<<endl;

        return 0;
}

#include <iostream>
#include <string>
#include <readline/readline.h> //实现tab补全、行编辑快捷键
#include <readline/history.h> //实现历史命令

using namespace std;

int main(void)
{
    string Aline;

    using_history(); // 初始化

    while(true)
    {
        //将参数打印然后从标准输入读取数据作为字符串返回
        Aline = readline("enter expression, or q to quit: ");

        if(Aline == "q")
        {
            break;
        }

        //将此条命令存入history中
        add_history(Aline.c_str());
    }

    return 0;
}

ifstream

 本质是一个标准类模板,俗称文件流类。

需要铜鼓哦简历对象,进行文件操作,包括:

文件读取,文件读取一行。。。

详情链接

#include <fstream>
#include <sstream>
#include <vector>
#include <string.h>
using namespace std;

int main(int argc,char** argv){
        //1,create ifstream object
        ifstream reader(argv[1],ios::in|ios::binary);

        char buffer[100];
        string str;
        //2,readline
        while(reader.getline(buffer,100)){
                //3,split
                str=string(strtok(buffer," "));
                cout<<str<<endl;
                str=string(strtok(nullptr," "));
                cout<<str<<endl;
        }

        return 0;
}

exit()

exit(int v)

进程终止函数

v为0表示正常退出,为非0表四异常退出

exit(0)的调用就如同在main函数种调用return 0;

都是exit()一定要有参数,return可以不要返回值

string类的函数:

首先string也是一个类

如何比较两个string字符串:

1,string类可以用关系运算符进行比较:

比较的原则是:ASCII码大者为大         ,小写字母大于大写字母

        string str1="vdufbvf",s1="yhhhhuu";
        string str2="iwufvbdfv",s2="Yhhhuu";

        if(str1>str2)
                cout<<"str1>str2"<<endl;
        else if(str1<str2)
                cout<<"str1<str2"<<endl;

        if(s1>s2)
                cout<<"s1"<<s1<<endl;
        else if(s1<s2)
                cout<<"s2"<<s2<<endl;

2,

string类的compare函数:

compare返回0,1,-1

compare的参数可以是以下类型:

string str1="come here,dear.";
string str2="ok,I am going now.";

str2.compare(str1);// 1
str2.compare("you are late.");// 2
str2.compare(4,4,str1);// 3,将str2从4开始的4个字符与str1比较
str2.compare(4,4,str1,3,4);// 4,将str2从4开始的4个字符与str1从3开始的4个字符比较

char arr[]="oehdfcbfc";
str2.compare(arr);// 5
str2.compare(2,4,arr);// 6,原理同3
str2.compare(3,5,arr+n,4);// 7,将str2从3开始的5个字符和arr+n的地址开始的4个字符比较

如何从一个string字符串中抽取出需要的字符串:

substr函数:

string str="We will not seperate forever";
string s=str.substr(0);//拷贝str中的所有字符
string s=str.substr(3);//从w(注意小写的w)考试拷贝所有字符
string s=str.substr(5,10);//从地址为5个的地址拷贝10个字符

//当开始拷贝位置加上计数值大于str时,substr只会拷贝到结尾
//当开始拷贝的位置大于str的最大字节数时,程序报错

string的数值转换:

1,其他类型转string:

int n=10;

string s=to_string(n);

注意:to_string只能运用于任何算数类型,而不能用于char

 那么如何将char类型转为string:

可以用string的构造方法:

其中要转换为数值的string对象中的第一个字符必须是数字

p,b参数可以不要,只要s.

如何判断string对象是否为空:

string类的empty函数:
string s;

s.empty();

empty函数返回一个bool类型

对string源对象字符串进行插入,删除:

字符判断函数

字母(不区分大小写):isalpha();    alphabet----(代表)全部字母,字母表

大写字母:isupper();

小写字母:islower();

数字:isdigit();

字母和数字:isalnum();

3、大小写字母转化:

(1)转化为大写:toupper();

(2)转化为小写:tolower();

排序函数

链接

stable_sort()性能要比sort()好一点

#include<iostream>
#include<string>
#include<vector>
#include <map>
#include<algorithm>
using namespace std;
typedef pair<string,int> PAIR;

struct cmpByScoreLess{
    bool operator()(const PAIR& p1,const PAIR& p2){
        return p1.second>p2.second;
    }
};
struct cmpByScoreGreater{
    bool operator()(const PAIR& p1,const PAIR& p2){
        return p1.second<p2.second;
    }
};

int main() {
    int n,flag;
    while(cin>>n>>flag){
        vector<pair<string,int>> name_score(n);
        int score;
        for(int i=0;i<n;++i){
            cin>>name_score[i].first>>name_score[i].second;
        }
        if(flag==0)
            stable_sort(name_score.begin(),name_score.end(),cmpByScoreLess());
        else
            stable_sort(name_score.begin(),name_score.end(),cmpByScoreGreater());
        for(auto info:name_score)
            cout<<info.first<<" "<<info.second<<endl;
    }
}

比较函数的第三个参数,可以是结构体,类,或者直接是函数,如果是结构体或者类,需要()调用,如果是函数只需要函数名

#include<iostream>
#include<string>
#include<vector>
#include <map>
#include<algorithm>
using namespace std;
typedef pair<string,int> PAIR;

bool cmpByScoreLess(const PAIR& p1,const PAIR& p2){
        return p1.second>p2.second;
}
bool cmpByScoreGreater(const PAIR& p1,const PAIR& p2){
        return p1.second<p2.second;
}

int main() {
    int n,flag;
    while(cin>>n>>flag){
        vector<pair<string,int>> name_score(n);
        int score;
        for(int i=0;i<n;++i){
            cin>>name_score[i].first>>name_score[i].second;
        }
        if(flag==0)
            stable_sort(name_score.begin(),name_score.end(),cmpByScoreLess);
        else
            stable_sort(name_score.begin(),name_score.end(),cmpByScoreGreater);
        for(auto info:name_score)
            cout<<info.first<<" "<<info.second<<endl;
    }
}

mmap,munmap:


mmap将一个文件或者其它对象的数据映射进指定(可由系统指定)的内存。(通俗一点就是从其他地方指定的位置拷贝数据到本进程指定长度的地址当中)

mmap操作提供了一种机制,让用户程序直接访问设备内存,这种机制,相比较在用户空间和内核空间互相拷贝数据,效率更高。在要求高性能的应用中比较常用。

munmap执行相反的操作,删除特定内存区的对象映射。

#include <sys/mman.h>

 void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);
 int munmap(void *start, size_t length);

start:映射区内存的起始地址,设置为0时表示由系统决定映射区的起始地址。
 length:映射区内存的长度。注意,这个不是映射的数据长度。

为什么length=1,也可以映射正文件的内容:


 prot:内存区保护标志,不能与文件的打开模式冲突。是以下的某个值,可以通过or运算(“|”)合理地组合在一起
  PROT_EXEC //内存区内容可以被执行
  PROT_READ //内存区内容可以被读取
  PROT_WRITE //内存区可以被写入
  PROT_NONE //内存区不可访问

flags:设置内存区的属性。

fd:文件描述符。

offset:被映射对象内容起始点。

返回映射区起始地址

注意:mmap返回的地址类型是void*,需要强转。

下面说一下内存映射的步骤:
用open系统调用打开文件, 并返回描述符fd.
用mmap建立内存映射, 并返回映射首地址指针start.
对映射(文件)进行各种操作, 显示(printf), 修改(sprintf).
用munmap(void *start, size_t lenght)关闭内存映射.
用close系统调用关闭文件fd.

memcpy:
memory copy内存(数据)拷贝函数

void *memcpy(void *dest, const void *src, size_t n);
它的功能是从src的开始位置拷贝n个字节的数据到dest。如果dest存在数据,将会被覆盖。memcpy函数的返回值是dest的指针。memcpy函数定义在string.h头文件里。

void main()
{
        char arr[10]="aaaaaaaa";
        char* str="uiefcb";
        memcpy(arr,str,6);
        printf("%s\n",arr);
}
输出:uiefcbaa
 

时间函数:

time:

 time_t time(time_t *calptr) 

函数功能: 得到当前日历时间或者设置日历时间(获取时间值)

参数说明: timer=NULL时得到当前日历时间(从1970-01-01 00:00:00到现在的秒数),timer=时间数值时,用于设置日历时间,time_t是一个unsigned long类型。如果 timer不为空,则返回值也存储在变量 timer中。

time_t nowtime;

nowtime=time(NULL);

time(nowtime);

上面的2,3行代码功能相同

ctime函数


函数原型: char *ctime(const time_t * timer)

函数功能: 将日历时间参数timer转换为一个表示本地当前时间的字符串

函数返回: 返回字符串格式:星期,月,日,小时:分:秒,年

利用这两函数就可以获取时间:

time获取时间,ctime将获取的时间转为字符串,便可以输出

asctime

char* asctime(struct tm * ptr)

函数功能:将结构struct tm * ptr所表示的时间以字符串表示

函数返回: 返回的时间字符串格式为:星期,月,日,小时:分:秒,年

clock_gettime---linux下

int clock_gettime(clockid_t clk_id, struct timespec *tp);

根据需要,获取不同要求的精确时间,tp为timespec结构体对象指针

clk_id如果为CLOCK_REALTIME,则表示获取系统当前时间,和time差不多,还更加精确

struct timespec {
               time_t   tv_sec;        /* seconds */
               long     tv_nsec;       /* nanoseconds */
           };


localtime:

struct tm *localtime(const time_t *timer)

函数功能: 使用 timer 的值来填充 tm 结构。timer 的值被分解为 tm 结构,并用本地时区表示。

#include <stdio.h>
#include <time.h>

int main ()
{
   time_t timer;
   struct tm *Now;

   time( &timer );
   Now = localtime( &timer );
   printf("当前的本地时间和日期:%s", asctime(Now));

   return(0);
}

当前的本地时间和日期:Sun Nov 21 13:12:56 2021

struct tm {
               int tm_sec;    /* Seconds (0-60) */
               int tm_min;    /* Minutes (0-59) */
               int tm_hour;   /* Hours (0-23) */
               int tm_mday;   /* Day of the month (1-31) */
               int tm_mon;    /* Month (0-11) */
               int tm_year;   /* Year - 1900 */
               int tm_wday;   /* Day of the week (0-6, Sunday = 0) */
               int tm_yday;   /* Day in the year (0-365, 1 Jan = 0) */
               int tm_isdst;  /* Daylight saving time */
           };

clock---windows

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <list>
#include <algorithm>
using namespace std;

void findFunc() {
	clock_t start, finish;
	double duration;
	vector<int> vec;
	list<int> lis;

	//vector查找数据性能
	for (int i = 0; i < 1000000; ++i)
		vec.push_back(i);
	start = clock();
	int v=vec[888888];
	finish = clock();
	duration = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("vector查找数据所花费时间:%fms\n", duration);

	//list删除数据性能
	for (int i = 0; i < 1000000; ++i)
		lis.push_back(i);
	auto ite = lis.begin();
	start = clock();
	for (; ite != lis.end(); ++ite) {
		if (*ite == 888888) break;
	}
	finish = clock();
	duration = (double)(finish - start) / CLOCKS_PER_SEC;
	printf("list查找数据所花费时间:%fms\n", duration);
	cout << endl;
}


math类函数

rand()

.产生一定范围随机数的通用表示公式

要取得 [a,b) 的随机整数,使用 (rand() % (b-a))+ a;

要取得 [a,b] 的随机整数,使用 (rand() % (b-a+1))+ a;

要取得 (a,b] 的随机整数,使用 (rand() % (b-a))+ a + 1;

通用公式: a + rand() % n;其中的 a 是起始值,n 是整数的范围。

所在头文件:

stdlib.h 注意一定要.h,否则报错

随机数序列和随机数种子

链接

关于ctime网上看

如何生成0~1的随机数

链接

三角函数:

注意:三角函数sin(),cos()等这些函数在编程使用时,计算的是弧度角,不是角度,在使用时需要把角度转换为弧度。

eg:

计算正弦值90度

不是直接:sin(90)

正确的编程方式:

hudu=90*3.1415926/180;

sin(hudu);

幂函数

pow(x,y)

x的y次方

exp(x)

c++中的函数exp(x)是求e的x 次方。

e=2.71828...

对数函数

logy(x)=z,x是底,y是x的z次方的结果。

log()和log10()

log函数包括两种函数

一种以e为低的log()函数

另一种为以10为底的log 10()函数

x=e^(logx) 

进制转换函数

10转其他进制

long ret = strtol(n,&result,a);
n -- 要转换为长整数的字符串。

result -- 对类型为 char* 的对象的引用,其值由函数设置为 str 中数值后的下一个字符。

a -- 基数,必须介于 2 和 36(包含)之间,或者是特殊值 0。
 

其他进制转10

_itoa(a,result,b); 

a为要转换的数,result用来存储转换结果,b为要转变的进制数。

#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
using namespace std;

string getResult(int num, int radix) {
    char res[100];
    _itoa(num,res,radix);
    string str(res,res+strlen(res));
    return str;
}

#include "function.h"

int main() {
	string res = getResult(100,2);
	cout << "10--二进制:" << res << endl;
	res = getResult(100,8);
	cout << "10--八进制:" << res << endl;
	res = getResult(100, 16);
	cout << "10--十六进制:" << res << endl;

	char t_arr[] = {'1','1','0','1'};
	long num = strtol(t_arr,NULL,2);
	cout << "二进制---10:" << num << endl;

	char e_arr[] = {'2','3','7'};
	num = strtol(e_arr,NULL,8);
	cout << "八进制---10:" << num << endl;

	char s_arr[] = { '2','3','7' };
	num = strtol(s_arr, NULL, 16);
	cout << "十六进制---10:" << num << endl;

	return 0;
}

注意:一定要加上:#define _CRT_SECURE_NO_WARNINGS

(控制安全没有报警)

int ceil(x)

返回大于等于x的最小整数

min_element()--max_element()

求数组第一个最大(小)元素的位置(下标)

#include <algorithm>

	vector<int> arr = {2,3,4,5,6,5,4};
	auto p = max_element(arr.begin(), arr.end());
	cout << *p << endl;
	p = min_element(arr.begin(),arr.end());
	cout << *p << endl;
	return 0;

va_list 原理以及用法

头文件:#include <stdarg.h>

VA_LIST 是在C语言中解决变参问题的一组宏,变参问题是指参数的个数不定,可以是传入一个参数也可以是多个;可变参数中的每个参数的类型可以不同,也可以相同;可变参数的每个参数并没有实际的名称与之相对应,用起来是很灵活。

参考代码:

#include <stdarg.h> 

int AveInt(int,...);

 void main()
{
   printf("%d/t",AveInt(2,2,3));
   printf("%d/t",AveInt(4,2,4,6,8));
   
   return;
}

int AveInt(int v,...)
{
   int ReturnValue=0;
   int i=v;
   
   va_list ap ;  //char* ap;
   va_start(ap,v);

   while(i>0)
   {
	   ReturnValue+=va_arg(ap,int) ;
       i--;
   }
   va_end(ap); 
   return ReturnValue/=v;
}

下面讲解一下va_list各个语句含义(如上示例黑体部分)和va_list的实现。

可变参数是由宏实现的,但是由于硬件平台的不同,编译器的不同,宏的定义也不相同,下面是VC6.0中x86平台的定义 :

      typedef char * va_list;     // TC中定义为void*
      #define _INTSIZEOF(n)    ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) ) //为了满足需要内存对齐的系统
      #define va_start(ap,v)    ( ap = (va_list)&v + _INTSIZEOF(v) )     //ap指向第一个变参的位置,即将第一个变参的地址赋予ap
      #define va_arg(ap,t)       ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )   /*获取变参的具体内容,t为变参的类型,如有多个参数,则通过移动ap的指针来获得变参的地址,从而获得内容*/
      #define va_end(ap) ( ap = (va_list)0 )   //清空va_list,即结束变参的获取

各个宏(函数)的作用:

va_list ap :

va----variable变量

定义一个va_list变量ap
va_start(ap,v) :

启动变量ap获取第一个参数的地址

执行ap = (va_list)&v + _INTSIZEOF(v),ap指向参数v之后的那个参数的地址,即 ap指向第一个可变参数在堆栈的地址。
va_arg(ap,t) :

arg--argument 参数

获取(返回)ap指向的地址的数值,并使ap指向下一个参数的地址,只要通过循环这个函数,就可以持续获取这些参数

( (t )((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )取出当前ap指针所指的值,并使ap指向下一个参数。 ap+= sizeof(t类型),让ap指向下一个参数的地址。然后返回ap-sizeof(t类型)的t类型指针,这正是第一个可变参数在堆栈里的地址。然后 用取得这个地址的内容。
va_end(ap) ;:

清空va_list ap。

vsnprintf

函数功能:将可变参数格式化输出到一个地址中

注意:
在linux环境下是:vsnprintf
但在VC6环境下是:_vsnprintf

头文件:#include <stdarg.h>

int mon_log(char* format, ...)
{}
函数声明:int vsnprintf(char *str, size_t size, const char *format, va_list ap);四个参数

注意:

1,format不是一个参数,format中含有所有可变参数,所有可变参数的类型,顺序。

所以,不管有多少个可变参数,只要第一个参数是格式转换,后面的参数都会被转换为指定的字符串,也就是说,不需要程序员转,只需要传入参数,函数执行的过程就完成转换了,在指定区域就得到结果

2,至少也要有两个参数,第一个一定是转换的格式,第二个是需要转换的内容。

respone_line("%s","\r\n")

参数:

str
保存输出字符串缓冲区的起始地址。

size
缓冲区可用的大小。

format
包含格式字符串的字符串,其格式字符串与printf中的格式相同

arg
变量参数列表,用va_list 定义。

返回值:
执行成功,返回最终生成字符串的长度若生成字符串的长度大于size,则将字符串的前size个字符复制到str,同时将原串的长度返回(不包含终止符);执行失败,返回负值,并置errno.
案列:

#include "stdio.h"
#include "stdarg.h"
#include "string.h"

void display(const char* format,...)
{
        char buffer[30];
        va_list ap;
        va_start(ap,format);
        int len=vsnprintf(buffer,sizeof(buffer),format,ap);
        va_end(ap);

        if(len!=0)
             printf("%s",buffer);
}

void main()
{
        char* str="Flown by the plane.";
        display("%s is %d\n",str,strlen(str));
}

原文链接

计算类函数

次方计算

       double pow(double x, double y);
       float powf(float x, float y);
       long double powl(long double x, long double y);
 

double pow(double x, double y);
       float powf(float x, float y);
       long double powl(long double x, long double y);

       Link with -lm.
 

返回x的y次方

STD提供的函数

sort(void* v1,void* v2,排序方式)

用来对一个指定区间的数进行排序,第三个参数可以不用指定。如果指定,有以下两种选择:

less----从小到大(默认)

greater---从大到小。

v1,v2用指针。

注意:

是在原容器进行排序,排序的结果也是存储在容器中的。

前两个参数是地址

int arr[10];

sort(a,a+10);

记住这个函数,很多容器的排序需要它直接完成。

swap(void p1,void p2);

可以实现两个变量数据的交换,原理:将地址中的值进行交换。

和容器的swa原理不同-------链接

也可以用来实现容器中元素的交换。

reverse(void* p1,void* p2)

#include <algorithm>

实现元素反转

string to_string(void value)

标准库中的函数,将任意算术类型的数据转为string类型。

获取系统信息函数--sysconf

链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值