新版typora可以直接上传图床了!!!

Makedown+LaTeX是两种脚本语言,Typora是一款markdown编辑器

Typora是我用过最好用、最干净的markdown编辑器 突然我手里的vs code和vim都不香了 markdown语法超级简单,入门只需十分钟,笔记清晰明了 LaTeX只用来输入公式一俩小时就可以熟悉了 LaTeX常见符号https://blog.csdn.net/zgj926503/article/details/52757631 Makedown语法:http://www.markdown.cn/

这是我看到讲的最好的讲师了,思路清晰,甚至想来推荐,本人是以看书、看文档为主的,能让我推荐的视频必有的水平。 不过好像没有出第二季还是有点可惜的,这个老师在csdn好像有c语言课程,有需要的可以去支持一下,说不定能出个第二季?

自己写的教程里的demo

github

1
2
3
4
5
#插件commentary
gc #注释一行
gcc #注释一段
:7,17Commentary #注释7-17行

1
<cursor>Lorem ipsum dolor sit amet.

Type w((easymotion-w)) to trigger the word motion w. When the motion is triggered, the text is updated (no braces are actually added, the text is highlighted in red by default):

1
<cursor>Lorem {a}psum {b}olor {c}it {d}met.

Press c to jump to the beginning of the word "sit":

阅读全文 »

标准流管道

1
2
3
4
5
#include<stdio.h>
FILE popen(const char* command,const char* open_mode);
int pclode(FILE *Fp);
//popen():允许一个程序将另一个程序作为新进程来启动,并可以传递数据给它或者通过它接收数据。
//pclose():关闭与之关联的文件流

无名管道

1
2
#include<unistd.h>
int pipe(int fds[2]);

命名管道

阅读全文 »

信号

  • 由进程的某个操作产生的信号称为同步信息(synchronous signals)
  • 由像用户点击这样的进程外部事件产生的信号叫做异步信号(asynchronous signals)
  • SIGKILL和SIGSTOP既不能忽略也不能被捕捉,进程收到这两个信号只能几首系统的默认处理,即终止进程

signal信号处理机制

1
2
3
4
5
6
#include<signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum,sighandler_t handler);
//singnum表示要捕捉的信号
//handler是函数指针,表示要对该信号进行捕捉的函数,该参数也可以是SIG_DFL(系统缺省)或者SIG_IGN(忽略该信号不做任何处理)。
//成功返回以前该信号处理函数的地址,否则返回SIG_ERR

sigaction信号处理机制

阅读全文 »

LinuxC——ls -l实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include<sys/stat.h>
#include<sys/types.h>
#include<unistd.h>
#include<dirent.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<time.h>
#include<grp.h>
#include<pwd.h>

void mode_to_letters(int mode, char str[]) //mode转为rwx格式字符串
{
strcpy(str, "----------");
if (S_ISDIR(mode))
{
str[0] = 'd';
}
if (S_ISCHR(mode))
{
str[0] = 'c';
}
if (S_ISBLK(mode))
{
str[0] = 'b';
}
if ((mode & S_IRUSR))
{
str[1] = 'r';
}
if ((mode & S_IWUSR))
{
str[2] = 'w';
}
if ((mode & S_IXUSR))
{
str[3] = 'x';
}
if ((mode & S_IRGRP))
{
str[4] = 'r';
}
if ((mode & S_IWGRP))
{
str[5] = 'w';
}
if ((mode & S_IXGRP))
{
str[6] = 'x';
}
if ((mode & S_IROTH))
{
str[7] = 'r';
}
if ((mode & S_IWOTH))
{
str[8] = 'w';
}
if ((mode & S_IXOTH))
{
str[9] = 'x';
}
}
char * uid_to_name(uid_t uid) //uid转为用户名
{
struct passwd *pw_ptr;
static char numstr[10];
if((pw_ptr=getpwuid(uid))==NULL)
{
sprintf(numstr,"%d",uid);
return numstr;
}
else
{
return pw_ptr->pw_name;
}
}
char* gid_to_name(gid_t gid) //gid转为用户组
{
struct group *str;
static char name_gid[10];
if((str=getgrgid(gid))==NULL)
{
sprintf(name_gid,"%d",gid);
return name_gid;
}
else
{
return str->gr_name;
}
}
int main(int argc,char *argv[])
{
if(2!=argc) //没加参数直接报错
{
perror("error input");
}
chdir(argv[1]); //切换目录
DIR *dp=opendir(argv[1]); //打开目录文件
char name[11];
if(NULL==dp) //目录不存在报错
{
perror("cannot open the dir\n");
}
struct dirent *entry;
struct stat statbuf;
while((entry=readdir(dp))!=NULL)
{
if(strcmp(entry->d_name,".")==0||strcmp(entry->d_name,"..")==0)
{
continue;
}
stat(entry->d_name,&statbuf);
mode_to_letters(statbuf.st_mode,name);
printf("%s",name);
printf("%4d ",(int) statbuf.st_nlink);
printf("%-13s",uid_to_name(statbuf.st_uid));
printf("%-13s",gid_to_name(statbuf.st_gid));
printf("%8ld ",(long) statbuf.st_size);
printf("%.12s ",4+ctime(&statbuf.st_mtime));
printf("%s\n",entry->d_name);
}
}

信号量

1
2
3
4
5
6
#include<sys/sem.h>
#include<sys/ipc.h>
#include<sys/types.h>
int semget(key_t key,int nsems,int flags);
int semop(int semid,struct sembuf *sops,size_t num_sops);
int semctl(int semid,int semnum,int cmd,...);
  • 函数semget创建一个信号集或访问一个已存在的信号集。返回值:成功时返回信号量标识符的整数,出错时返回-1
  • 参数key时唯一标识一个信号量的关键字,如果为IPC_PRIVATE(值为0,私有)表示创建一个可以被多个进程共享的信号量
  • 参数nsems指定需要使用的信号量的数目。如果是创建新集合,必须指定nsems,如果引用一个现存的集合,则指定为0
  • 参数flag是一组标志,其作用与open函数的标志很相似,它低端九位是该操作量的权限
  • 函数semop用于改变信号量对象中各个信号量的状态。返回值:成功时返回0;失败时返回-1
    1
    2
    3
    4
    5
    struct sembuf{
    short sem_num;//编号,从0开始
    short sem_op;//信号量,-1:p操作,+1:v操作
    short sem_flg; //通常设为:SEM_UNDO,程序结束,信号量为semop调用前的值
    };
    参数cmd为执行的操作,通常为 | 参数 | 说明 | | -------- | ------------------------------------------------------------ | | IPC_RMID | 立即删除信号集,唤醒所有被阻塞进程 | | GETVAL | 根据semun返回信号量的值,从0开始,第一个信号编号为0 | | SETVAL | 根据semun设定信号的值,从0开始,将所有的信号存入semun.array中 | | SETALL | 将所有semun.array的值设定到信号集中,第二个参数为0 | 参数...是一个union semun(需要自己定义),至少包含以下成员
    1
    2
    3
    4
    5
    6
    union semun{
    int val;
    struct semid_da *buf;
    unsigned short *array;
    };
    //通常情况只用val,给val赋值1
    删除命令是ipcrm [-m|-s|-q] id

-m 删除共享内存,-s删除共享信号量,-q删除共享队列。

ipcrm -m shmid

阅读全文 »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys.msg.h>
int msgget(key_t key,int msgflg);
int msgsnd(int msqid,struct msgbuf *msgp,size_t msgsz,int msgflg);
ssize_t msgrcv(int msqid,struct msgbuf *msgp,size_t msgsz,long msgtyp,int msgflg);
int msgctl(int msqid,int cmd,struct msqid_ds *buf);
//msgget创建和访问一个消息队列。成功返回唯一的消息队列标识符,失败返回-1;
//key是唯一标识一个消息队列的关键词,如果为IPC_PRIVATE(0)则创建一个只用创建者才可以访问额消息队列,可用于父子之间通信。
//msgflg知名队列的访问权限和创建标志,IPC_CREAT或IPC_EXCL
//msgsnd和msgrcy用来将消息添加到消息队列中和从一个消息队列中获取信息
//参数msgid指明消息队列的ID(通常是msgget的返回值)
//参数misbuf是消息结构体,长度必须小于系统规定的上限,必须以一个长整型成员变量开始,接收函数将用这个成员变量来确定消息类型
struct msgbuf{
long mtype; //type of message
char mtext[1];//message text
};
//mtype是用户自己指定的消息类型,第二个成员是说明性结构,可以使用任何类型,就是消息内容
//参数msgsz是消息体的大小,每个消息体最大不要超过4K
//msgflg可以为0(通常情况)或IPC_NOWAIT(此选项下,msgsnd和msgrcv不会阻塞,如果队列满并调用msgsnd或者队列空调用msgrcv将返回错误)
//参数mstyp有三种选项:
//==0 接收队列中第一个消息(通常为0)
//>0 接收队列中第一个类型等于msgtyp的消息
//<0 接收其类型小于或者等于msgtyp绝对值的第一个最低类型消息
//函数msgctl是消息队列的控制函数,常用来删除消息队列
//参数msqid是消息队列标识符
//参数cmd通常是IPC_RMID表示删除消息队列
//参数buf通常是NULL即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
key_t ftok(const char *pathname,int proj_id);
//pathname:全路径文件名,必须可以访问
//proj_id:通常传入一个非零字符
//成功返回关键字,否则返回-1
int shmget(key_t key,int size,int shmflg);
//成功:内存标志号,失败:-1
void *shmat(int shmid,const void *shmaddr,int shmflg);
//
int shmdt(const void *shmaddr);
int shmctl(int shmid,int cmd,struct shmid_ds *buf);
//ftok用于创建一个关键词,可以用该关键词关联一个共享内存段

ipcs -m //查看共享内存

Linux下的文件操作

文件读写

1
2
3
4
#include<stdio.h>
size_t fread(void *ptr,size_t size,size_t nmemb,FILE *steam);
size_t fwrite(void *ptr,size_t size,size_t nmemb,FILE *stream)
//数据块读写
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<stdip.h>
//格式化读写
int printf(const char *format,...);
int scanf(const char *format,...);
int fprintf(FILE *stream,const char *format,...);
int fscanf(FILE *stream,const char *format,...);
int sprintf(char *str,const char *format,...);
int sscanf(char *str,const char *format,...);
//单个字符读写
int fgetc(FILE *stream);
int fputc(int c,FILE *stream);
int getc(FILE *stream) //等同于fgetc
int putc(int c,FILE *stream); //等同于fputc
int getchar(void) //等同于fgetc(stdin)
int putchar(int c); //等同于fputc(int c,stdout);
//字符串读写
char *fgets(char *s,int size,FILE *stream);
int fputs(const char *s,FILE *stream);
int puts(const char *s);
char *gets(char *s); //等同于fgets(const char *s,int size,stdin)
//文件定位
int feof(FILE *stream); //通常用法为while(!feof(fp))
int fseek(FILE *stream,long offset,int whence);//设置当前读写点到偏移whence长度为offset处
//whence可以是: SEEK_SET(文件开头 *0) SEEK_CUR(文件当前位置 *1) SEEK_END(文件末尾 *2)
long ftell(FILE *stream); //用来获取文件流当前的读取位置
void rewind(FILE *stream); //把文件流的读写位置移动至文件开头

目录操作

阅读全文 »
0%