1
2
3
4
5
6
7
8
#预处理 c++一般用.ii后缀
gcc -E test.c -o test.i
#编译
gcc -S test.i -o test.s
#汇编
gcc -c test.s -o test.o
#链接
gcc test.o -o test.out
3_linux下编译与调试
gcc库选项 含义
-static 进行静态编译,即链接静态库,禁止使用动态库
-shared 1、可以生成动态库文件
2、进行动态编译,尽可能地链接动态库,只有没有动态库时才会链接同名的静态库(默认选项,可以省略)
-L dir 在库文件的搜索路径列表中增加dir目录
-lname 链接称为libname.a(静态库)或者libname.so(动态库)的库文件。若两个库都存在,则根据编译方式(-static或者-shared)而进行链接
-fPIC(-fpic) 生成使用相对地址的位置无关的目标代码。然后通常使用gcc的-static选项从PIC目标文件生成动态库文件

-静态库 链接器会将搜索静态库并直接拷贝到该程序的可执行二进制文件到当前文件

-动态库 在程序编译时并不会被链接到目标代码中,而是在程序运行时才被载入

阅读全文 »

线程的创建和退出

1
2
3
4
5
6
7
8
9
#include<pthread.h>
int pthread_create(pthread_t* thread,pthread_attr_t* attr,void *(*start_routine)(void *),void* arg);
void pthread_exit(void *retval);
//通常形式
pthread_t pthid;
pthread_create(&pthid,NULL,pthfunc,NULL);
thread_create(&pthid,NULL,pthfunc,(void*)3);
pthread_exit(NULL);
pthread_exit((void*)3);
  • thread是传入参数,保存新进程的标识

  • attr是一个结构体指针,可用pthread_attr_init初始化,一般为NULL

  • start_routine是一个函数指针,指向新线程入口点函数,线程入口点函数带有一个void*的参数由pthread_create的第4个参数传入

  • arg用于传递给第三个参数指向的入口点函数的参数,可以为NULL,表示不传递 # 线程的等待退出

    1
    2
    3
    4
    #include<pthread.h>
    int pthread_join(pthread_t th,void **thread_return)
    //thread_return是一个传出参数,接收线程的返回值
    //若前程使用pthread_exit()终止,该函数内参数则为返回值
    # 线程的取消

    int pthread_cancel(pthread_t thread);

根据POSIX标准,pthread_join(),pthread_testcancel(),pthread_cond_wait(),pthread_cond_timedwait(),sem_wait(),sigwait(),read(),write()等会相应cancel信号

进程终止清理函数

阅读全文 »

数据存储优先顺序转换

1
2
3
4
5
6
#include<arpa/inet.h>
uint16_t htons(uint16_t hostshort); //16位主机序转网络序
uint32_t htonl(uint32_t hostlong);//32位主机序转网络序
uint16_t ntohs(uint16_t netshort);//16位网络序转主机序
uint32_t ntohl(uint32_t netlong);//32位网络序转主机序
//出错返回-1

#地址格式转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
int inet_aton(const char *srraddr,struct in_addr *addrptr);
//将点分十进制数的ip地址转换位网络字节序的32位二进制数,成功返回1,不成功返回0
char *inet_ntoa(struct in_addr inaddr);
//将网络字节序的32位二进制数值转化为点分法的十进制ip地址
in_addr_t inet_addr(const char *straddr);
//功能与inet_aton相同,传递方式不同
const chat* inet_pton(int family,const char *src,char *dst,socklen_t len);
//与inter_ntoa类似,其中len表示转换之后的长度(字符串长度)
int inet_pton(int family,const char *src,void *dst);
//和inet_aton类似,多了family函数,该参数指定为AF_INET, 表示为ipv4协议,如果为AF_INET6表示IPV6协议


# TCP
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
//服务端:socket--bind--listen--while(1){accept--recv--send--close}--close
//客户端:socket--connect--send--recv--close
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
int socketFd=socket(AF_INET,SOCKSTREAM,0);
//AF_INET:ipv4 AF_INET6:ipv6
struct sockaddr_in serAddr;
memset(&serAddr,0,sizeof(serAddr);
serAddr.sin_family=AF_INET;
serAddr.sin_port=htons(atoi(port));
serAddr.sin_addr.s_addr=inet_addr(ip);
int resuce=1;
setsockopt(socketFd,SOL_SOCKET,SO_REUSEADDR,&resue,sizeof(int));
bind(socketFd,(struct sockaddr*)&serAddr,sizeof(struct sockaddr);
listen(socketFd,10);
//listen第二个参数为最大连接数
recv(socketFd,&buf,sizeof(buf),0);
//接收消息至缓冲区
send(int s,const void *msg,int len,unsigned int flags);
//s为accept的返回值,new_fd
//msg一般为字符串常量,len表示长度,flags一般为0
close(int fd);
1
2
3
4
5
6
7
8
//sockaddr_in结构体
struct sockaddr_in
{
usigned short int sin_family;
uint16_t sin_port;
struct in_addr sin_addr;
unsigned char sin_zero[8];//未使用
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//客户端
int connect(int sockfd,struct sockaddr *ser_addr,int addrlen);
//sockfd:socket的返回值
//serv_addr:结构体指针变量,存储着远程服务器的IP与端口号
//addrlen:结构体变量的长度

struct sockaddr_in seraddr;
memset(&seraddr,0,sizeof(struct sockaddr);
seraddr.sin_family=AF_INET:
seraddr.sin_port=htons(2345);
seraddr.sin_addr.s_addr=inet_addr(ip);
if(connect(sfd,(struct sockaddr*)&seraddr,sizeof(struct sockaddr))==-1){
perror("connect");
close(sfd);
exit(-1);
}
#UDP
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
int main()
{
int sfd=socket(AF_INET<SOCK_DGRAM,0);
if(-1==sfd)
{
perror("socket");
exit(-1);
}
struct sockaddr_in saddr;
bzero(&saddr,sizeof(saddr));
saddr.sin_family=AF_INET;
saddr.sin_port=htons(2345);
saddr.sin_addr.s_addr=INADDR_ANY;
if(bind(sfd,(struct sockaddr*)&saddr,sizeof(struct sockaddr))==-1)
{
perror("bind");
close(sfd);
exit(-1);
}
char buf[512]={0};
while(1)
{
struct sockaddr_in fromaddr;
bzero(&fromaddr,sizeof(fromaddr));
int fromaddrlen=sizeof(struct sockaddr);
if(recvfrom(sfd,buf,sizeof(buf),0,(struct sockaddr*)&fromaddr,&fromaddrlen)==-1)
{
perror("recvfrom);
close(sfd);
exit(-1);
}
printf("receive from %s:%d,the message is %s\n",inet_ntoa(fromaddr.sin_addr),ntohs(fromaddr.sin_port),buf);
sendto(sfd,"world",6,0,(struct sockaddr*)&fromaddr,sizeof(struct sockaddr));
}
close(sfd);
}

进程概论

进程标识及用户id、组id

1
2
3
4
5
6
7
8
9
10
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
int main()
{
printf("pid:%d ppid:%d euid:%d egid:%d\n",getpid(),getppid(),geteuid(),getegid());
return 0;
}
//进程的pid和ppid(父进程)可以分别通过函数getpid()和getppid()获得
//geteuid(),getegid() 获取有效用户和有效组id

Linux高级权限控制

1
2
3
chmod u+s a.out #设置使文件在执行阶段具有文件所有者的权限. 典型的文件是 /usr/bin/passwd. 如果一般用户执行该文件, 则在执行过程中, 该文件可以获得root权
chmod g+s /home/xxxx #该权限只对目录有效.目录被设置该位后,任何用户在此目录下创建的文件都具有和该目录所属的组相同的组.
chmod o+t /temp #(粘滞位) 该位可以理解为防删除位.一个文件是否可以被某用户删除, 主要取决于该文件所属的组是否对该用户具有写权限. 如果没有写权限, 则这个目录下的所有文件都不能被删除, 同时也不能添加新的文件. 如果希望用户能够添加文件,但同时不能删除文件,则可以对文件使用sticky bit位. 设置该位后, 就算用户对目录具有写权限,也不能删除该文件。
阅读全文 »

节点定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum color_t {RED,BLACK};

typedef int Type;

typedef struct RBTreeNode{
struct RBTreeNode *left;
struct RBTreeNode *right;
struct RBTreeNode *parent;
enum color_t color;
Type key;
}Node;

//根节点
typedef struct RBRoot{
Node* root;
Node *nil;//叶子(空指针)
}rb_root;

插入

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
//插入与AVL树完全相同,最后调整即可
//新插入指针初始化颜色为红色
void rb_insert(rb_root* T,Node* z){
Node* y=T->nil;
Node* x=T->root;
while(x!=T->nil){
y=x;
if(x->key<z->key){
x=x->right;
}else x=x->left;
}
z->parent=y;
if(y==T->nil) T->root=z;
else if(z->key<y->key) y->left=z;
else y->right=z;
z->left=z->right=T->nil;
z->color=RED;
rb_insert_fix(T,z); //修正红黑树
}
//创建新节点
void rb_insert_type(rb_root* T,Type key){
Node *p=(Node*)malloc(sizeof(Node));
p->color=RED;
p->key=key;
p->left=p->right=p->parent=T->nil;
rb_insert(T,p);
}

插入修正函数

阅读全文 »

程序开始与注释

1
#!/bin/bash

变量

shell变量

shell变量没有数据类型,都是字符串,即使数值也是字符串

阅读全文 »

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#列出文件系统的整体磁盘空间情况
df[选项][文件名]
-h:--human-readable
#显示每个文件和目录的磁盘使用情况
du[选项][文件名]
du --max-depth=0 /
#<重定向输入 >重定向输出 >> 添加输出 2>错误重定向输出 &>错误和信息重定向输出
cat >file1<file2
./main text1.txt >text5.txt 2>&1
#显示前几行
head -n 10 main.cc
#显示文件后几行
tail -n 10 main.cc
#汉字编码转换
iconv -f utf-8 -t gb2312 hanzi>hanzi1
#搜索文件内容
grep
#管道查询程序
#将a.txt中的aa替换为bb输出到b.txt
cat a.txt|sed 's/aa/bb'>b.txt
0%