Socket網絡編程--小小網盤程序(2)

http://www.cnblogs.com/wunaozai/p/3887728.html

 這一節將不會介紹太多的技術的問題,這節主要是搭建一個小小的框架,為了方便接下來的繼續編寫擴展程序。本次會在上一小節的基礎上加上一個身份驗證的功能。

  因為網盤程序不像聊天程序,網盤是屬于主動向服務器拉取信息,而聊天程序有可能要被動獲取信息,所以為了減輕服務器壓力,每次要向服務器獲取服務就建立一個短連接,而不像聊天程序一樣的長連接,微信的公眾平臺,輸入指令獲取服務,就是這個樣子了。具體看一下代碼就知道了。

  還有為了方便處理,我增加了一個控制信號,這個控制信號在以前的聊天程序中講到過,但是當時為了簡單就沒有實現,現在就簡單實現一些,方便以后可以參考。

  還有就是這次的網盤程序我將盡量實現下面的這些功能:

  (1) file push filename ?         //用戶上傳文件到服務器上

  (2) file pull filename ? ?        //用戶下載文件到本地上

  (3) file list              //列出用戶在服務器中的所有文件

  (4) file sendto ?filename username //共享文件給其他用戶

  (5) file delete filename        //刪除服務器中的文件

  (6) 用戶登錄,自動完成

  本次數據庫名為filetranslate,目前有表user

1 create table user
2 (
3     uid int;
4     username varchar(64);
5     password varchar(64);  
6 );

?

  修改后的client.cpp

復制代碼
  1 #include <netinet/in.h> // sockaddr_in
  2 #include <sys/types.h> //socket
  3 #include <sys/socket.h> //socket
  4 #include <netdb.h> //gethostbyname
  5 #include <unistd.h> //close
  6 #include <stdio.h>
  7 #include <stdlib.h>
  8 #include <string.h>
  9 #include <time.h>
 10 #include <arpa/inet.h> //inet_addr
 11 
 12 #define SERVVER_PORT 12138
 13 #define LISTEN_QUEUE 20
 14 #define BUFFER_SIZE 1024
 15 
 16 //傳輸控制信號宏定義
 17 //struct Control中control的取值
 18 #define USER_CHECK_LOGIN 1
 19 #define FILE_PUSH 2
 20 #define FILE_PULL 3
 21 #define FILE_LIST 4
 22 #define FILE_SENDTO 5
 23 #define FILE_DELECT 6
 24 
 25 struct Addr
 26 {
 27     char host[64];
 28     int port;
 29 };
 30 struct User
 31 {
 32     int uid;
 33     char username[64];
 34     char password[64];
 35 };
 36 struct Control
 37 {
 38     int uid;
 39     int control;
 40 };
 41 
 42 void print_time(char *ch);//打印時間
 43 int file_push(struct Addr addr,struct User user,char *filenames);
 44 int check_login(struct Addr addr,struct User * user);
 45 
 46 
 47 int main(int argc,char *argv[])
 48 {
 49     char orderbuf[BUFFER_SIZE];
 50     struct Addr addr;
 51     char arg1[32],arg2[32],arg3[32],arg4[32];
 52     struct User user;
 53 
 54     if(argc!=5)
 55     {
 56         perror("usage: ./client [serverhost] [serverport] [username] [password]");
 57         exit(-1);
 58     }
 59     strcpy(addr.host,argv[1]);
 60     addr.port=atoi(argv[2]);
 61     strcpy(user.username,argv[3]);
 62     strcpy(user.password,argv[4]);
 63     int uid=check_login(addr,&user);
 64     if(uid<=0)
 65     {
 66         perror("用戶驗證失敗");
 67         exit(-1);
 68     }
 69     printf("驗證登陸成功\n");
 70     while(1)
 71     {
 72         printf("\n請輸入操作指令:");
 73         fgets(orderbuf,BUFFER_SIZE,stdin);
 74         memset(arg1,0,sizeof(arg1));
 75         memset(arg2,0,sizeof(arg2));
 76         memset(arg3,0,sizeof(arg3));
 77         memset(arg4,0,sizeof(arg4));
 78         sscanf(orderbuf,"%s%s%s%s",arg1,arg2,arg3,arg4);
 79         if(strcmp(arg1,"file")==0)
 80         {
 81             if(strcmp(arg2,"push")==0)
 82             {
 83                 strcpy(orderbuf,arg3);
 84                 file_push(addr,user,orderbuf);
 85             }
 86             else if(strcmp(arg2,"pull")==0)
 87             {
 88                 ;
 89             }
 90             else if(strcmp(arg2,"list")==0)
 91             {
 92                 ;
 93             }
 94             else if(strcmp(arg2,"sendto")==0)
 95             {
 96                 ;
 97             }
 98             else if(strcmp(arg2,"delect")==0)
 99             {
100                 ;
101             }
102             else
103             {
104                 printf("該命令不支持\n");
105             }
106         }
107         else
108         {
109             printf("該命令不支持\n");
110         }
111     }
112 
113 
114     return 0;
115 }
116 
117 //驗證成功時返回大于0的uid號碼,錯誤返回-1
118 int check_login(struct Addr addr,struct User * user)
119 {
120     struct sockaddr_in servAddr;
121     struct hostent * host;
122     struct Control control;
123     int sockfd;
124 
125     host=gethostbyname(addr.host);
126     servAddr.sin_family=AF_INET;
127     servAddr.sin_addr=*((struct in_addr *)host->h_addr);
128     //servAddr.sin_addr.s_addr=inet_addr("127.0.0.1");
129     servAddr.sin_port=htons(addr.port);
130     if(host==NULL)
131     {
132         perror("獲取IP地址失敗");
133         exit(-1);
134     }
135     if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
136     {
137         perror("socket創建失敗");
138         exit(-1);
139     }
140     if(connect(sockfd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr_in))==-1)
141     {
142         perror("connect 失敗");
143         exit(-1);
144     }
145 
146     control.control=USER_CHECK_LOGIN;
147     control.uid=0;
148     if(send(sockfd,(char *)&control,sizeof(struct Control),0)<0)
149     {
150         perror("發送數據失敗");
151         exit(-1);
152     }
153 
154     if(send(sockfd,(char *)user,sizeof(struct User),0)<0)
155     {
156         perror("發送數據失敗");
157         exit(-1);
158     }
159     bzero(user,sizeof(struct User));
160     if(recv(sockfd,(char *)user,sizeof(struct User),0)<0)
161     {
162         perror("接收數據失敗");
163         exit(-1);
164     }
165     printf("獲取后用戶名:%s 密碼:%s ID號:%d\n",user->username,user->password,user->uid);
166 
167     close(sockfd);//關閉socket連接
168     return user->uid;
169 }
170 
171 int file_push(struct Addr addr,struct User user,char *filenames)
172 {
173     struct sockaddr_in servAddr;
174     struct hostent * host;
175     struct Control control;
176     int sockfd;
177     FILE *fp;
178 
179     host=gethostbyname(addr.host);
180     servAddr.sin_family=AF_INET;
181     servAddr.sin_addr=*((struct in_addr *)host->h_addr);
182     //servAddr.sin_addr.s_addr=inet_addr("127.0.0.1");
183     servAddr.sin_port=htons(addr.port);
184     if(host==NULL)
185     {
186         perror("獲取IP地址失敗");
187         exit(-1);
188     }
189     if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
190     {
191         perror("socket創建失敗");
192         exit(-1);
193     }
194 
195     if(connect(sockfd,(struct sockaddr *)&servAddr,sizeof(struct sockaddr_in))==-1)
196     {
197         perror("connect 失敗");
198         exit(-1);
199     }
200 
201     //打開文件
202     if((fp=fopen(filenames,"rb"))==NULL)
203     {
204         perror("文件打開失敗");
205         exit(-1);
206     }
207     //這里傳輸控制信號
208     control.control=FILE_PUSH;
209     control.uid=user.uid;
210     if(send(sockfd,(char *)&control,sizeof(struct Control),0)<0)
211     {
212         perror("控制信號發送失敗");
213         exit(-1);
214     }
215     char buffer[BUFFER_SIZE];
216     bzero(buffer,BUFFER_SIZE);
217     printf("正在傳輸文件");
218     int len=0;
219     //不斷的讀取文件直到文件結束
220     while((len=fread(buffer,1,BUFFER_SIZE,fp))>0)
221     {
222         if(send(sockfd,buffer,len,0)<0)
223         {
224             perror("發送數據失敗");
225             exit(-1);
226         }
227         bzero(buffer,BUFFER_SIZE);
228         printf(".");//1K打印一個點//如果要實現百分比,就要計算文件大小,然后再處理即可
229     }
230 
231     printf("傳輸完畢\n");
232     fclose(fp);//關閉文件流
233     close(sockfd);//關閉socket連接
234 
235     return 0;
236 }
237 
238 void print_time(char *ch)
239 {
240     time_t now;
241     struct tm * stm;
242     time(&now);
243     stm=localtime(&now);
244     sprintf(ch,"%02d:%02d:%02d\n",stm->tm_hour,stm->tm_min,stm->tm_sec);
245     return ;
246 }
復制代碼

  下面這個是server.cpp

復制代碼
  1 #include <netinet/in.h>
  2 #include <sys/types.h>
  3 #include <sys/socket.h>
  4 #include <sys/select.h>
  5 #include <netdb.h>
  6 #include <stdlib.h>
  7 #include <time.h>
  8 #include <string.h>
  9 #include <unistd.h>
 10 #include <stdio.h>
 11 #include <arpa/inet.h> //inet_ntoa
 12 #include <mysql.h>
 13 
 14 #define SERVER_PORT 12138
 15 #define LISTEN_QUEUE 20
 16 #define BACKLOG 200
 17 #define BUFFER_SIZE 1024
 18 
 19 //傳輸控制信號宏定義
 20 //struct Control中control的取值
 21 #define USER_CHECK_LOGIN 1
 22 #define FILE_PUSH 2
 23 #define FILE_PULL 3
 24 #define FILE_LIST 4
 25 #define FILE_SENDTO 5
 26 #define FILE_DELECT 6
 27 
 28 struct User
 29 {
 30     int uid;
 31     char username[64];
 32     char password[64];
 33 };
 34 
 35 struct Control
 36 {
 37     int uid;
 38     int control;
 39 };
 40 
 41 void print_time(char *ch);//打印時間
 42 int MAX(int a,int b);
 43 int mysql_check_login(struct User user);
 44 
 45 
 46 int main(int argc,char *argv[])
 47 {
 48     struct sockaddr_in server_addr;
 49     struct sockaddr_in client_addr;
 50     struct User user;
 51     struct Control control;
 52     char ch[64];
 53     int clientfd;
 54     pid_t pid;
 55     socklen_t length;
 56     bzero(&server_addr,sizeof(server_addr));
 57     server_addr.sin_family=AF_INET;
 58     server_addr.sin_addr.s_addr=htons(INADDR_ANY);
 59     server_addr.sin_port=htons(SERVER_PORT);
 60 
 61     //創建套接字
 62     int sockfd=socket(AF_INET,SOCK_STREAM,0);
 63     if(sockfd<0)
 64     {
 65         perror("創建套接字失敗");
 66         exit(-1);
 67     }
 68 
 69     if(bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr))==-1)
 70     {
 71         perror("bind 失敗");
 72         exit(-1);
 73     }
 74 
 75     if(listen(sockfd,LISTEN_QUEUE))
 76     {
 77         perror("listen 失敗");
 78         exit(-1);
 79     }
 80 
 81     length=sizeof(struct sockaddr);
 82 
 83     while(1)
 84     {
 85         clientfd=accept(sockfd,(struct sockaddr *)&client_addr,&length);
 86         if(clientfd==-1)
 87         {
 88             perror("accept 失敗");
 89             continue;
 90         }
 91         printf(">>>>>%s:%d 連接成功,當前所在的ID(fd)號: %d \n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port),clientfd);
 92         print_time(ch);
 93         printf("加入的時間是:%s\n",ch);
 94 
 95         //來一個連接就創建一個進程進行處理
 96         pid=fork();
 97         if(pid<0)
 98         {
 99             perror("fork error");
100         }
101         else if(pid==0)
102         {
103             recv(clientfd,(char *)&control,sizeof(struct Control),0);
104             printf("用戶 %d 使用命令 %d\n",control.uid,control.control);
105             switch(control.control)
106             {
107                 case USER_CHECK_LOGIN:
108                     {
109                         //身份驗證處理
110                         recv(clientfd,(char *)&user,sizeof(struct User),0);
111                         printf("客戶端發送過來的用戶名是:%s,密碼:%s\n",user.username,user.password);
112                         if((user.uid=mysql_check_login(user))>0)
113                         {
114                             printf("驗證成功\n");
115                         }
116                         else
117                         {
118                             printf("驗證失敗\n");
119                         }
120                         send(clientfd,(char *)&user,sizeof(struct User),0);
121                         break;
122                     }
123                 case FILE_PUSH:
124                     {
125                         char buffer[BUFFER_SIZE];
126                         int data_len;
127                         FILE * fp=NULL;
128                         bzero(buffer,BUFFER_SIZE);
129                         if((fp=fopen("data","wb"))==NULL)
130                         {
131                             perror("文件打開失敗");
132                             exit(-1);
133                         }
134                         //循環接收數據
135                         int size=0;//表示有多少個塊
136                         while(data_len=recv(clientfd,buffer,BUFFER_SIZE,0))
137                         {
138                             if(data_len<0)
139                             {
140                                 perror("接收數據錯誤");
141                                 exit(-1);
142                             }
143                             size++;
144                             if(size==1)
145                                 printf("正在接收來自%s:%d的文件\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
146                             else
147                                 printf(".");
148                             //向文件中寫入
149                             int write_len=fwrite(buffer,sizeof(char),data_len,fp);
150                             if(write_len>data_len)
151                             {
152                                 perror("寫入數據錯誤");
153                                 exit(-1);
154                             }
155                             bzero(buffer,BUFFER_SIZE);
156                         }
157                         if(size>0)
158                             printf("\n%s:%d的文件傳送完畢\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
159                         else
160                             printf("\n%s:%d的文件傳送失敗\n",inet_ntoa(client_addr.sin_addr),ntohs(client_addr.sin_port));
161                         fclose(fp);
162                         //rename("data","asdf");//這里可以修改文件的名字
163                         exit(0);
164                         break;
165                     }
166                 case FILE_PULL:
167                     {
168                         break;
169                     }
170                 case FILE_LIST:
171                     {
172                         break;
173                     }
174                 case FILE_DELECT:
175                     {
176                         break;
177                     }
178                 default:
179                     {
180                         break;
181                     }
182             }
183             close(clientfd);//短連接結束
184             exit(0);//退出子進程
185         }
186     }
187 
188     return 0;
189 }
190 
191 
192 //函數定義
193 int mysql_check_login(struct User user)
194 {
195     MYSQL conn;
196     MYSQL_RES *res_ptr;
197     MYSQL_ROW result_row;
198     int res;
199     int row;
200     int column;
201     int uid;
202     char sql[256]={0};
203     strcpy(sql,"select uid from users where username=\"");
204     strcat(sql,user.username);
205     strcat(sql,"\" and password=\"");
206     strcat(sql,user.password);
207     strcat(sql,"\";");
208     printf("查詢的sql:%s\n",sql);
209     uid=-1;
210     mysql_init(&conn);
211     if(mysql_real_connect(&conn,"localhost","root","","filetranslate",0,NULL,CLIENT_FOUND_ROWS))
212     {
213         res=mysql_query(&conn,sql);
214         if(res)
215         {
216             perror("Select SQL ERROR!");
217             exit(-1);
218         }
219         else
220         {
221             res_ptr=mysql_store_result(&conn);
222             if(res_ptr)
223             {
224                 column=mysql_num_fields(res_ptr);//獲取列數
225                 row=mysql_num_rows(res_ptr)+1;//獲取行數,加1表示還有第一行字段名
226                 if(row<=1)
227                 {
228                     ;//驗證失敗
229                 }
230                 else
231                 {
232                     //這里先假定username是唯一
233                     result_row=mysql_fetch_row(res_ptr);
234                     printf("獲取到的uid是:%s\n",result_row[0]);
235                     uid=atoi(result_row[0]);
236                 }
237             }
238             else
239             {
240                 printf("沒有查詢到匹配的數據\n");
241             }
242         }
243     }
244     else
245     {
246         perror("Connect Failed!\n");
247         exit(-1);
248     }
249     mysql_close(&conn);
250     return uid;
251 }
252 
253 void print_time(char *ch)
254 {
255     time_t now;
256     struct tm * stm;
257     time(&now);
258     stm=localtime(&now);
259     sprintf(ch,"%02d:%02d:%02d\n",stm->tm_hour,stm->tm_min,stm->tm_sec);
260     return ;
261 }
262 
263 int MAX(int a,int b)
264 {
265     if(a>b)
266         return a;
267     return b;
268 }
復制代碼

  下面給張運行時的截圖

?

  關于c語言調用mysql:?http://www.cnblogs.com/wunaozai/p/3876134.html

  本文地址:?http://www.cnblogs.com/wunaozai/p/3887728.html


本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/384133.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/384133.shtml
英文地址,請注明出處:http://en.pswp.cn/news/384133.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linux下的重要目錄

1.bin目錄 主要防止系統下的各種必備可執行文件 2./proc 目錄 這個目錄相當于Windows下的計算機系統信息查看以及進程動態查看&#xff0c;可以查看計算機信息&#xff0c;用來存放當前計算機上的進程信息 3./sys 目錄 (1)其中block目錄用于存放塊設備文件 (2)bus存放總線類型…

HDU - 6278 Just $h$-index主席樹+二分

HDU - 6278 Just hhh-index 【題目描述】 【題目分析】 題目要求在區間[l,r][l,r][l,r]內大于h的數不少于h個&#xff0c;對于這種最大化問題&#xff0c;我們應該想到二分。 最小情況顯然是1.最大情況顯然是r?l1r-l1r?l1&#xff0c;對于一個hhh&#xff0c;我們如何判斷能…

Socket網絡編程--小小網盤程序(3)

http://www.cnblogs.com/wunaozai/p/3891062.html 接上一小節&#xff0c;這次增加另外的兩張表&#xff0c;用于記錄用戶是保存那些文件。增加傳上來的文件的文件指紋&#xff0c;使用MD5表示。 兩張表如下定義: 1 create table files(2 fid int,3 filename varchar(64),4 md…

LInux下du, df, top, free, pstack, su, sudo, adduser, password命令

1.du命令&#xff1a;du [選項] 文件 (1)功能該命令是顯示指定文件以及下的所有文件占用系統數據塊的情況&#xff0c;如果沒有文件&#xff0c;默認為是當前工作目錄 -a ???顯示所有文件對系統數據塊的使用情況 -b ???顯示數據塊大小時以字節為基本單位 -c ???除了顯…

HDU - 5919 Sequence II——主席樹+區間種類++逆序建樹

【題目描述】 HDU - 5919 Sequence II 【題目分析】 題目給定一個數組&#xff0c;每次查詢一個區間&#xff0c;找出區間內不同數字的個數x&#xff0c;然后輸出按出現順序第x/2向上取整個數字的位置。 按照要求&#xff0c;我們首先需要能夠找出給定區間不同的數字個數。 首…

Socket網絡編程--小小網盤程序(4)

http://www.cnblogs.com/wunaozai/p/3892729.html 在這一小節中實現了文件的下載&#xff0c;具體的思路是根據用戶的uid和用戶提供的文件名filename聯合兩張表&#xff0c;取得md5唯一標識符&#xff0c;然后操作這個標識符對應的文件發送給客戶端。 實現下載的小小網盤程序 …

靜態順序表的實現

實現對順序表的初始化&#xff0c;頭插&#xff0c;頭刪&#xff0c;尾插&#xff0c;尾刪&#xff0c; 任意下標的刪除&#xff0c; 任意下標處的的元素刪除&#xff0c;任意下標處的元素插入&#xff0c;任意元素的下標返回&#xff0c;任意下標處的元素返回&#xff0c; 刪除…

樹鏈剖分入門+HYSBZ - 1036樹的統計Count

今天學習了樹鏈剖分&#xff0c;記錄一下。 【題目背景】 HYSBZ - 1036樹的統計Count 【題目分析】 題目要求求任意結點之間路徑的和以及路徑上最大的結點&#xff0c;還有可能修改。如果正常做可能會很復雜&#xff08;我也不知道正常應該怎么做&#xff0c;應該要用到LCA什么…

Socket網絡編程--小小網盤程序(5)

http://www.cnblogs.com/wunaozai/p/3893469.html 各位好呀&#xff01;這一小節應該就是這個小小網盤程序的最后一小節了&#xff0c;這一節將實現最后的三個功能&#xff0c;即列出用戶在服務器中的文件列表&#xff0c;還有刪除用戶在服務器中的文件&#xff0c;最后的可以共…

進程相關概念

1.進程相關概念 進程是代碼的一次動態執行&#xff0c;擔當分配系統資源的角色&#xff0c;進程信息是被放在一個一個數據結構中&#xff0c;是一個結構體task_struct 2.進程控制塊內容 //linux下的進程控制塊 struct task_struct {volatile long state;// 說明了該進程是否可以…

SPOJ - QTREE3Query on a tree again!——樹鏈剖分

【題目描述】 SPOJ - QTREE3Query on a tree again! 【題目分析】 題目要求是輸出從111到xxx的路徑上遇到的第一個黑色的點。我們可以用樹鏈剖分&#xff08;不了解的同學請出門左拐&#xff0c;詳見樹鏈剖分入門&#xff09; 我們用線段樹維護每個區間第一次遇到黑點的位置&a…

C++中的函數指針和函數對象總結

http://www.cnblogs.com/lvpengms/archive/2011/02/21/1960078.html 篇一、函數指針 函數指針&#xff1a;是指向函數的指針變量&#xff0c;在C編譯時&#xff0c;每一個函數都有一個入口地址&#xff0c;那么這個指向這個函數的函數指針便指向這個地址。 函數指針的用途是很…

開發工具

1.編輯器 &#xff08;1&#xff09;vim ????vim是從vi發展出來的一個文本編輯器。代碼補完、編譯錯誤跳轉等方便編程的功能特別豐富&#xff0c;在程序員中被廣泛使用。 &#xff08;2&#xff09;sed ????sed是一種流編輯器&#xff0c;它一次處理一行內容。處理時…

575 div3RGB Substring (hard version)——思維-

【題目描述】 The only difference between easy and hard versions is the size of the input. You are given a string s consisting of n characters, each character is ‘R’, ‘G’ or ‘B’. You are also given an integer k . Your task is to change the minimum …

c++ 智能指針用法詳解

http://www.cnblogs.com/TenosDoIt/p/3456704.html 本文介紹c里面的四個智能指針: auto_ptr, shared_ptr, weak_ptr, unique_ptr 其中后三個是c11支持&#xff0c;并且第一個已經被c11棄用。 為什么要使用智能指針&#xff1a;我們知道c的內存管理是讓很多人頭疼的事&#xff0…

CodeForces - 786BLegacy——線段樹建圖+最短路

【題目描述】 CodeForces - 786BLegacy 【題目分析】 題目大概意思就是有三種操作&#xff1a; 從某個點到另一個點從某個點到另一個區間從某個區間到另一個點 然后詢問從其中一個點到其他所有點的距離——這很顯然是一個求單源最短路徑的。我們簡單的想法顯然是建一個圖&a…

自主編寫shell

1.替換原理 用fork創建子進程后執行的是和父進程相同的程序&#xff08;但有可能執行不同的代碼分支&#xff09;&#xff0c;子進程往往要調用一種exec函數以執行例外一個程序。當進程調用一種exec函數時&#xff0c;該進程的用戶空間代碼和數據完全被新程序替換&#xff0c;從…

HYSBZ - 2243染色——樹鏈剖分+線段樹建樹技巧

【題目描述】 HYSBZ - 2243染色 【題目分析】 我一直沒有看清楚題&#xff0c;以為求的是路徑上出現顏色的種類&#xff0c;然后就寫了一個區間染色的線段樹進行維護&#xff0c;過樣例的時候才發現題讀錯了&#xff0c;人家要求的是路徑上出現的顏色段&#xff0c;所以顏色的…

右值引用與轉移語義

https://www.ibm.com/developerworks/cn/aix/library/1307_lisl_c11/ 新特性的目的 右值引用 (Rvalue Referene) 是 C 新標準 (C11, 11 代表 2011 年 ) 中引入的新特性 , 它實現了轉移語義 (Move Sementics) 和精確傳遞 (Perfect Forwarding)。它的主要目的有兩個方面&#xff…

打動態庫和靜態庫

一.動態庫和靜態庫的定義 1.靜態庫 ????程序在編譯鏈接時把庫的代碼鏈接到可執行文件中。程序運行時就不再需要靜態庫 2.動態庫 ????程序在運行的時候才去鏈接動態庫的代碼&#xff0c;多個程序 共享使用代碼 3.動態鏈接 ????在執行文件之前&#xff0c;外部…