页面“Eclipse”与“C基础”之间的差异

来自linux中国网wiki
(页面间的差异)
跳到导航 跳到搜索
 
→‎ls
 
第1行: 第1行:
=下载=
+
 
[https://www.eclipse.org/downloads/packages/release/Oxygen/2  eclipse c 下载地址]
+
 
最新版的漂亮还快哦
+
 
 +
 +
good
 +
http://akaedu.github.io/book/
 +
 
 +
 
 +
[https://zhuanlan.zhihu.com/p/90971489 C语言编程学习必备的一些网站,干货收藏!]
 +
 
 +
[https://www.bilibili.com/video/BV17s411N78s/?spm_id_from=333.788.videocard.0 带你学C带你飞》]
 +
=如何学习C=
 +
 
 +
[https://blog.csdn.net/qwe6620692/article/details/88107248  学习C语言,如何看懂及掌握一个程序]
 +
 
 +
=2021学习C APUE=
 +
http://www.apuebook.com/
 +
 
 +
[https://www.zhihu.com/topic/19705459/hot UNIX环境高级编程(书籍)笔记什么都 有呀 ]
 +
 
 +
[https://www.zhihu.com/question/19939011 《UNIX环境高级编程》这本书怎么看?怎么学习]
 +
 
 +
 
 +
 
 +
==看法  ==
 +
第二章和第六章可以跳跳,回头看
 +
 
 +
7.中文版翻译有瑕疵,但是整体还是不错,不至于对阅读产生影响(信号量那章有细节问题,但是信号量那张和csapp第八章几乎重复)
 +
 
 +
首先,不要抱着一口气把这本书学完的心态去看。      尝试根据自己的兴趣,选择一个规模适当的开源项目,去阅读它的源代码。(例如我选择的就是一个小型的http服务器--Mongoose)当在某一方面发现自己有很多问题时,很希望去弄清楚时,这时候就可以去翻开手中的APUE,带着问题去阅读。这时候学习的效率必然比盲目地去看书更高,而且遗忘率也会降低。但是,仅仅读完是不够的。      很多时候,你看书的时候,会感觉自己看懂了,但是没过多久,又会发现自己忘了。或者,有时候你根本没看懂,而只是囫囵吞枣地看过去。所以,看完后,最好的方法就是写博客。尝试按照自己的理解以及逻辑,去将你学到的知识系统地阐述出来。这样,就算你以后忘了,再去翻翻博文,也能很快就捡起来。
 +
 
 +
十个最值得阅读学习的C开源项目代码
 +
 
 +
    Webbench
 +
    Tinyhttpd
 +
    cJSON
 +
    CMockery
 +
    Libev
 +
    Memcached
 +
    Lua
 +
    SQLite
 +
    UNIX v6
 +
    NETBSD
 +
 
 +
建议先看 >> Unix/Linux编程实践教程
 +
 
 +
https://book.douban.com/subject/1219329/
 +
 
 +
http://item.kongfz.com/book/32040616.html?push_type=2&min_price=57.00&utm_source=101004009001
 +
 
 +
https://detail.tmall.com/item.htm?spm=a1z10.1-b.w9858442-8055933095.4.fH3HiL&id=19729431809
 +
 
 +
[https://github.com/woai3c/recommended-books 常用计算机书的下载]
 +
 
 +
[https://blog.csdn.net/qwe6620692/article/details/88107248  学习C语言,如何看懂及掌握一个程序!]
 +
 
 +
[https://blog.51cto.com/chinalx1/2143904 十个经典的C开源项目代码]
 +
 
 +
[https://developer.51cto.com/art/201903/593703.htm 初学玩转C语言,这17个小项目收下不谢]
 +
 
 +
https://zhuanlan.zhihu.com/p/83185476
 +
 
 +
== tinyhttpd C 语言实现最简单的 HTTP 服务器 学习 ==
 +
 
 +
[https://www.shuzhiduo.com/A/ZOJPY9Ge5v/ tinyhttpd ------ C 语言实现最简单的 HTTP 服务器]
 +
 
 +
https://github.com/nengm/Tinyhttpd
 +
 
 +
[https://blog.csdn.net/baiwfg2/article/details/45582723  tinyhttpd源码详解]
 +
 
 +
[https://blog.csdn.net/konghhhhh/article/details/103752962  tinyhttp整理(一)]
 +
 
 +
[https://blog.csdn.net/weixin_30387663/article/details/99664160  tinyhttp源码阅读(注释)]
 +
 
 +
[https://juejin.cn/post/6870760453619122183  Tinyhttp源码分析及知识点总结 ]
 +
 
 +
[https://www.bilibili.com/video/BV1hy4y1C71M/?spm_id_from=333.788.videocard.1 b站 C/C++ tinyHttp服务器小项目及源码讲解1]
 +
 
 +
[https://blog.csdn.net/wwxy1995/article/details/99362666  tinyhttpd深入解析与源码剖析]
 +
 
 +
[https://blog.csdn.net/qq_40677350/article/details/90201758  Tinyhttpd-master 源码学习笔记1]
 +
 
 +
[https://blog.csdn.net/yzhang6_10/article/details/51534409  Tinyhttp源码分析]
 +
 
 +
[https://github.com/EZLippi/Tinyhttpd Tinyhttpd非官方镜像,Fork自sourceForge,仅供学习]
 +
 
 +
 
 +
 
 +
 
 +
[https://www.jianshu.com/p/18cfd6019296 tinyhttp源码分析]
 +
 
 +
我把一些核心代码和相应的注释贴在这里,如果你感兴趣全部,可以移步我的github。
 +
https://github.com/zhaozhengcoder/rebuild-the-wheel/tree/master/tinyhttpd
 +
 
 +
 
 +
[https://www.google.com/search?q=Tinyhttp+%E4%BB%A3%E7%A0%81%E5%AE%8C%E5%85%A8%E8%AE%B2%E8%A7%A3&newwindow=1&safe=active&sxsrf=ALeKk00sI_LE3rix9st768kTRNvSLADqfQ%3A1616990574286&source=hp&ei=blFhYIrjDoTcswW95aqACg&iflsig=AINFCbYAAAAAYGFffrh-H2QmmZeV5OlApkx5kRBpdYOT&oq=Tinyhttp+%E4%BB%A3%E7%A0%81%E5%AE%8C%E5%85%A8%E8%AE%B2%E8%A7%A3&gs_lcp=Cgdnd3Mtd2l6EANQ0QhY0Qhg2gpoAHAAeACAAQCIAQCSAQCYAQCgAQKgAQGqAQdnd3Mtd2l6&sclient=gws-wiz&ved=0ahUKEwiK0qGmz9TvAhUE7qwKHb2yCqAQ4dUDCAY&uact=5 Tinyhttp 代码完全讲解]
 +
 
 +
==Mongoose-基于C的Web服务器代码学习 ==
 +
 
 +
[https://www.jianshu.com/p/745c03a8864a Mongoose-基于C的Web服务器 介绍和使用]
 +
 
 +
 
 +
[https://blog.csdn.net/hnzwx888/article/details/84971205  Web服务器----mongoose]
 +
 
 +
https://github.com/cesanta/mongoose
 +
 
 +
[https://www.cnblogs.com/skynet/archive/2010/07/24/1784110.html  Mongoose源码剖析:外篇之web服务器 ]
 +
 
 +
[https://blog.csdn.net/lixiaogang_theanswer/article/details/102753370  Mongoose-6.14源码剖析之基础篇]
 +
 
 +
== 我的笔记 ==
 +
apue.3e/include/apue.h
 +
=== chapter 1===
 +
[https://zhuanlan.zhihu.com/p/136700729 APUE读书笔记-01UNIX系统概述]
 +
 
 +
这是原文学不过是 Second Edition  firefox 放大 就可以看  找一下 第三版本吧 Third Edition
 +
https://vaqeteart.gitee.io/file_bed/shared/books/APUE2/toc.html
 +
 
 +
 
 +
=== ?===
 +
 
 +
[https://www.jb51.net/article/55257.htm C语言实现的ls命令源码分享-apue]
 +
 
 +
[https://blog.nowcoder.net/n/9a48a7f697864e3bbdae2fe5bfcb0ef9 C 语言实现 Linux ls 命令]
 +
 
 +
=understanding_unix_programming =
 +
 
 +
==chapter 2  who ==
 +
 
 
<pre>
 
<pre>
pkg install openjdk8
+
/* 再看一下书 非常 好的啦 
  sudo pkg install eclipse-cdt
+
who命令的实现过程是先打开一个系统文件UTMP_FILE,创建对应的格式struct utmpfd变量,读取数据到这个结构体中,作相应格式输出即可
   pkg install eclipse-cdt # freebsd
+
*/
 +
#include<stdio.h>
 +
#include<utmp.h>
 +
#include<fcntl.h>
 +
#include <time.h>
 +
#include<unistd.h>
 +
#define SHOWHOST
 +
void showtime(long);
 +
void showtime(long timeval){
 +
    char *cp;
 +
    cp = ctime(&timeval);
 +
    //cp[strlen(cp)-1]='\0';
 +
    printf("%s",cp+4 ); //wed jun 21:40:09 +4是因为*cp所指的一串字符前4个字符表示为“星期”,可以忽略此信息
 +
}
 +
// 指向结构体 utmp 的指针 utbufp
 +
void show_info(struct utmp *utbufp)
 +
{
 +
    printf("%-8.8s",utbufp->ut_name) ;
 +
    printf(" ");
 +
   printf("%-8.8s",utbufp->ut_line);
 +
  printf("");
 +
  printf("% 10ld",utbufp->ut_time );
 +
 
 +
  printf(" ");
 +
 
 +
  printf(" ");
 +
 
 +
}
 +
 
 +
int main()
 +
{
 +
  struct utmp current_record;
 +
  int  utmpfd;
 +
  int reclen = sizeof(current_record);
 +
 
 +
  if (( utmpfd = open (UTMP_FILE, O_RDONLY)) == -1) {
 +
  perror(UTMP_FILE);
 +
  return 1;
 +
  }
 +
  while ( read(utmpfd, &current_record, reclen) == reclen )
 +
  show_info(&current_record);
 +
  close(utmpfd);
 +
  return 0;
 +
 
 +
}
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
C 库函数 void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。
 +
memset(str,'$',7);
 +
 
 +
This is string.h library function
 +
$$$$$$$ string.h library function
 
</pre>
 
</pre>
  
==icon==
+
参考 和书 chapter 2  这个最接近原书的了
 +
 
 +
https://www.cnblogs.com/20145221GQ/p/6060420.html
 +
 
 +
[https://blog.csdn.net/u010307522/article/details/72862589  who命令实现]
 +
 
 +
[https://blog.csdn.net/qq_33850438/article/details/60762519  unix/linux who命令的实现]
 +
 
 +
https://www.runoob.com/cprogramming/c-function-memset.html
 +
===别人实现1===
 +
https://www.cnblogs.com/20145221GQ/p/6060420.html
 +
 
 +
https://gitee.com/20145221/linux-besti-is-2016-2017-1-20145221/blob/master/src/week09/who.c?dir=0&filepath=src%2Fweek09%2Fwho.c&oid=6ca54191e2a046c9de2e42cfc5eb895ff665b429&sha=6cd302d6cb4f0d36f667754e972ce63963483044#
 
<pre>
 
<pre>
  
evan@myxps:/usr/share/applications$ cat eclipse.desktop
+
#include <stdio.h> 
[Desktop Entry]
+
#include <utmp.h>
Name=eclipse  
+
#include <fcntl.h> 
Comment=c ide
+
#include <unistd.h> 
GenericName[bg]=Интернет браузър
+
#include <time.h>  
GenericName[ca]=Navegador web
+
#include <string.h>
GenericName[cs]=Webový prohlížeč
+
 
GenericName[de]=Webbrowser
+
#define SHOWHOST 
GenericName[sk]=Internetový prehliadač
+
 
GenericName[sv]=Webbläsare
+
void showtime(long timeval){ 
X-GNOME-FullName=Firefox ESR Web Browser
+
    char* cp; 
Exec=/home/evan/apps/eclipse/eclipse %u
+
    cp = ctime(&timeval); 
Terminal=false
+
    cp[strlen(cp)-1] = '\0';
X-MultipleArgs=false
+
    printf("%s",cp+4); 
Type=Application
+
}  
Icon=/home/evan/apps/eclipse/icon.xpm
+
 
Categories=Network;WebBrowser;
+
void show_info(struct utmp* utbufp){ 
MimeType=text/html;text/xml;application/xhtml+xml;application/xml;application/vnd.mozilla.xul+xml;application/rss+xml;application/rdf+xml;image/gif;image/jpeg;image/png;x-scheme-handler/http;x-scheme-handler/https;
+
    if(utbufp->ut_type != USER_PROCESS){ 
StartupWMClass=Firefox-esr
+
        return ; 
StartupNotify=true
+
    } 
 +
 
 +
    printf("%-8.8s",utbufp->ut_name); 
 +
    printf(" ");
 +
    printf("%-8.8s",utbufp->ut_line);
 +
    printf(" ");
 +
    showtime(utbufp->ut_time);
 +
    printf(" ");
 +
 
 +
#ifdef SHOWHOST 
 +
    if(utbufp->ut_host[0] != '\0'){ 
 +
        printf("(%s)",utbufp->ut_host);
 +
    } 
 +
#endif 
 +
    printf("\n");
 +
}
 +
 
 +
int main(){ 
 +
    struct utmp current_record;
 +
    int utmpfd;
 +
    int reclen = sizeof(current_record);
 +
 
 +
    if((utmpfd = open(UTMP_FILE,O_RDONLY)) == -1){ 
 +
        perror(UTMP_FILE);
 +
 
 +
        return 1;
 +
    } 
 +
 
 +
    while( read(utmpfd,&current_record,reclen) == reclen ){ 
 +
        show_info(&current_record);
 +
    } 
 +
 
 +
    close(utmpfd);
 +
 
 +
    return 0; 
 +
  
 
</pre>
 
</pre>
 +
===see also===
 +
[https://blog.csdn.net/u010307522/article/details/72862589  who命令实现]
  
=usage=
+
 
 +
===cp===
 
<pre>
 
<pre>
Eclipse中添加多行注释的快捷键 
 
  
第一种 //注释
+
#include        <stdio.h>//标准输入输出
选择你要注释的那一行或多行代码,按 Ctrl+/ 即可,取消注释也是选中之后按 Ctrl+/ 即可。此快捷键是 //注释 而不是 /**/注释。
+
#include        <stdlib.h>//C标准函数库
 +
#include        <unistd.h>//Unix类系统定义符号常量
 +
#include        <fcntl.h>//定义了很多宏和open,fcntl函数原型
  
第二种 /**/注释
+
#define BUFFERSIZE      4096//定义存储器容量
 +
#define COPYMODE        0644//定义复制的长度
  
Ctrl+Shift+/  
+
void oops(char *, char *);
说明:添加/* */注释
+
/*注意main函数的两个参数:
 +
  argc记录了用户在运行程序的命令行中输入的参数的个数。
 +
  arg[]指向的数组中至少有一个字符指针,即arg[0].它通常指向程序中的可执行文件的文件名。 */
 +
main(int ac,char *av[])
 +
{
 +
    int in_fd, out_fd,n_chars;    //三个描述符值 in_fd为open返回的描述符 ,create out_fd为open返回的描述符  n_chars  读取的数据 function 见上个who  read的
 +
    char buf[BUFFERSIZE]; //存储器位置
 +
/*cp的参数有两个,分别是要复制的文件,和目的目录,这样一共应该是有三个操作数
 +
  所以要先检查argc的值是否为三,如果不是,返回标准错误*/
 +
        if(ac !=3) {
 +
            fprintf(stderr, "usage:%s source destination\n",* av);
 +
            exit(1);
 +
        }
 +
        /* open files 检查cp的第一个参数,要复制的文件,用open打开,in_fd为open返回的描述符 如果返回-1,代表打开失败,提示错误
 +
          why CP 第一个参数是 av[1],  av[0] 是程序中的可执行的文件名也就是自己
 +
        */
 +
        if ((in_fd=open(av[1],O_RDONLY)) == -1)
 +
            oops("Cannot open",av[1]);
  
Ctrl+Shift+\
+
/*检查cp的第二个参数,复制的目的地址,用create在目的地址创建新文件,out_fd为open返回的描述符
说明:消除/* */注释
+
  如果返回-1,代表创建失败,提示错误 ; create 创建的位置就是av[2] 目标文件的位置是也
 +
  为什么是 av[2]  就是 cp 命令的 第二个参数 也就是 目标文件 ,本来不存在 所以要create
 +
*/
 +
if(out_fd=creat(av[2],COPYMODE)== -1)
 +
    oops("Cannot creat",argv[2])
 +
}
 +
/*copyfiles  cp指令的动作就是读取一个文件的内容到存储器,在新的地址创建空白文件,再从存储器将内容写入新文件。
 +
  这里判断复制是否成功:
 +
  如果能读取顺利,而读取的位数和写的位数不同,是写错误;
 +
  如果读取失败,是读错误。
 +
  why n_chars 是什么
 +
  内核从utmpfd所指定的文件中读取了 reclen字节的数据,存放到 current_record所指定的内存空间中
 +
  while ( read(utmpfd, &current_record, reclen) == reclen )
  
要修改在eclispe中的命令的快捷键方式我们只需进入windows -> preference -> General -> key设置就行了
+
  write out_fd 文件描述符  buf 内存数据, n_chars 要写的字节数
 +
 
 +
循环的把源文件写入目标文件
 +
*/
 +
while ((n_chars= read(int __fd,buf,BUFFERSIZE))>0) {
 +
    if(write(out_fd,buf,n_chars) != n_chars)
 +
        oops("Write error to ", av[2]);
 +
    if (n_chars== -1)
 +
 
 +
        oops("Read error from ",argv[1]);
 +
/*这里执行的是关闭文件的动作,in_fd open的 和out_fd create的两个文件描述符
 +
  所指向的文件只要有一个关闭错误,就提示关闭错误。*/
 +
    if (close(in_fd) == -1 || close(out_fd)== -1)
 +
        oops("Error closing files","");
 +
}
 +
 
 +
/*不太明白为什么是指针了这里 evan  这个是用来输出错误信息的函数*/
 +
void oops(char *s1, char *s2)
 +
{
 +
    fprintf(stderr, "Error:%s", s1);
 +
    perror(s2); // 用来将上一个函数发生错误的原因输出到标准设备(stderr)
 +
    exit(1)
 +
 
 +
        }
  
 
</pre>
 
</pre>
==[https://stackoverflow.com/questions/43623643/how-to-open-terminal-inside-eclipse How to open Terminal inside Eclipse]==
+
 
 +
 
 +
[https://www.cnblogs.com/cxy1616/p/6063463.html cp命令的编写最接受原书的了]
 +
 
 +
[https://blog.csdn.net/hejishan/article/details/2250995  Unix程序设计:实现cp命令]
 +
 
 +
[https://blog.csdn.net/XSL1990/article/details/8250039 linux自己编写的 cp 命令像os的那个了 ]
 +
 
 +
http://bbs.chinaunix.net/thread-247946-1-1.html
 +
 
 +
[https://blog.csdn.net/byxbai1989/article/details/17371197  linux cp命令源码]
 +
 
 +
=== ls===
 +
data/c/example/unixeg/ls/
 +
 
 +
 
 +
 
 +
 
 +
====第二版本的参考 ====
 +
[https://www.cnblogs.com/ghostwu/p/8253623.html  linux系统编程:自己动手写一个ls命令 ]
 +
 
 +
 
 +
[https://blog.csdn.net/zhangxb35/article/details/42222037?utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-3.control&dist_request_id=1331645.10707.16183847242193639&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7Edefault-3.control  Linux下的 ls 命令的简单实现]
 +
 
 +
[https://www.cnblogs.com/ikaros-521/p/11254332.html 高仿linux下的ls -l命令——C语言实现]
 +
 
 +
 
 +
[http://www.doczj.com/doc/54bc4a27a5e9856a56126086.html 在linux下编写一个LS命令的小程序]
 +
 
 +
[https://www.cnblogs.com/lularible/p/14386358.html  Linux系统编程【3.1】——编写ls命令 ]
 +
 
 +
[https://blog.csdn.net/lularible/article/details/113776163  Linux系统编程【3.2】——ls命令优化版和ls -l实现]
 +
 
 +
[https://blog.nowcoder.net/n/9a48a7f697864e3bbdae2fe5bfcb0ef9 C 语言实现 Linux ls 命令]
 +
 
 +
====简单版本的参考 ====
 +
https://github.com/fupengfei058/ls
 +
 
 +
http://www.voidcn.com/article/p-bzocmlpx-bxd.html
 +
 
 +
https://blog.csdn.net/qingshui23/article/details/53931555
 +
 
 +
https://blog.csdn.net/aonaigayiximasi/article/details/54019964
 +
 
 +
=C IDE=
 +
 
 +
https://www.jetbrains.com/zh-cn/clion/
 +
 
 +
[[Eclipse]]
 +
 
 +
[[Anjuta on linux]]
 +
 
 +
https://atom.io/
 +
 
 +
=pre main =
 
<pre>
 
<pre>
 +
init main( int argc, char *argv[]);
 +
argc 是命令行参数的数目 也包括自身 没有后台的参数 那么 argc=1
 +
 +
argv 指向参数的各个指针所构成的数组, argv[0]表示命令本身,argv[1] 表示第一个参数
 +
 +
argc 是argument count的缩写表示传入main函数中的参数个数,包括这个程序本身
 +
 +
argv 是 argument vector的缩写表示传入main函数中的参数列表,其中argv[0]表示这个程序的名字; *argv[] 其实是地址
 +
 +
第二个参数,char*型的argv[],为字符串数组,用来存放指向的字符串参数的指针数组,每一个元素指向一个参数。各成员含义如下:
 +
        argv[0]指向程序运行的全路径名
 +
        argv[1]指向在DOS命令行中执行程序名后的第一个字符串
 +
 +
char  *argv[]是一个字符数组,其大小是int  argc,主要用于命令行参数  argv[]  参数,数组里每个元素代表一个参数;
 +
 +
看代码的时候我最先不理解的就是main函数的定义:
 +
 +
int main(int argc, char *argv[]){}
 +
 +
经查阅得知,argc是用来表示在命令行下输入命令时的参数个数,包括指令本身;argv[]是用来取得你输入的参数。针对具体指令分析如下(每一步解释由注释形式给出)。
 +
 +
由于main函数不能被其它函数调用, 因此不可能在程序内部取得实际值。那么,在何处把实参值赋予main函数的形参呢? 实际上,main函数的参数值是从操作系统命令行上获得的。当我们要运行一个可执行文件时,在DOS提示符下键入文件名,再输入实际参数即可把这些实参传送到main的形参中去。
 +
 +
ls1.c中的 就是这个了啦
 +
DOS提示符下命令行的一般形式为: C:\>可执行文件名 参数 参数……; 但是应该特别注意的是,main 的两个形参和命令行中的参数在位置上不是一一对应的。因为,main的形参只有二个,而命令行中的参数个数原则上未加限制。argc参数表示了命令行中参数的个数(注意:文件名本身也算一个参数),argc的值是在输入命令行时由系统按实际参数的个数自动赋予的。例如有命令行为: C:\>E6 24 BASIC dbase FORTRAN由于文件名E6 24本身也算一个参数,所以共有4个参数,因此argc取得的值为4。argv参数是字符串指针数组,其各元素值为命令行中各字符串(参数均按字符串处理)的首地址。 指针数组的长度即为参数个数。数组元素初值由系统自动赋予。其表示如图6.8所示:
 +
 +
main(int argc,char *argv){
 +
while(argc-->1)
 +
printf("%s\n",*++argv);
 +
}
 +
 +
本例是显示命令行中输入的参数如果上例的可执行文件名为e24.exe,存放在A驱动器的盘内。
 +
因此输入的命令行为: C:\>a:e24 BASIC dBASE FORTRAN 
 +
则运行结果为:
 +
BASIC
 +
dBASE
 +
FORTRAN
 +
  该行共有4个参数,执行main时,argc的初值即为4。argv的4个元素分为4个字符串的首地址。执行while语句,每循环一次 argv值减1,当argv等于1时停止循环,共循环三次, 因此共可输出三个参数。在printf函数中,由于打印项*++argv是先加1再打印, 故第一次打印的是argv[1]所指的字符串BASIC。第二、 三次循环分别打印后二个字符串。而参数e24是文件名,不必输出。
 +
 +
另外一个例子
 +
 +
 +
</pre>
 +
[https://blog.csdn.net/zhaozhiyuan111/article/details/104050729  c语言中argc和argv[ <nowiki>]</nowiki>的作用及用法]
  
不用安装 用自带的就行了 
+
[https://blog.csdn.net/weixin_40539125/article/details/82585792 good和ls1.c差不多 C语言中 int main(int argc,char *argv[<nowiki>]</nowiki>)的两个参数详解]
  
 +
https://zhuanlan.zhihu.com/p/267822985
  
右下角  open cons  --  command shell-- 填写自己的IP
+
https://blog.csdn.net/LYJ_viviani/article/details/51873961
  
 +
[https://www.bilibili.com/video/av246420003/ c语言之argc和argv]
  
这个也可以用ssh 感觉界面更加友好
+
=基础=
  
linux tools --> TM Terminal 4.3.0.201706140544
+
==计算机为什么要用二进制==
 +
Everything over Binary 模拟路转换成为数字电路
 +
 
 +
https://blog.csdn.net/weixin_44296862/article/details/95277924
 +
 
 +
https://blog.csdn.net/c46550/article/details/90951557
 +
 
 +
[https://wenku.baidu.com/view/77074002e009581b6ad9eb2c.html 一位全加器]
 +
=== signed char 类型的范围为 -128~127===
 +
<pre>
 +
按八位来算:
 +
在计算机里面是用补码表示的,128的二进制码是:10000000,这个东西在计算里面并不是128,因为最高位是符号,它是个负数,那么负数的原码是多少呢,我们知道如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取反,然后再整个数加1。
 +
所以,10000000取反后就是11111111,把符号位去了就是01111111再加1就是10000000就是-128了。
 +
其实你看-127是10000001,这个很好理解,-128加1不就是-127
 +
[https://blog.csdn.net/zy986718042/article/details/71699079 浅谈char类型范围]
 +
 
 +
补码表示时,-0和+0补码相同都是0 000 0000,所义导致可以多表示一个负数,...这个负数是最小的那个..
 
</pre>
 
</pre>
 +
[https://blog.csdn.net/czg13548930186/article/details/52602279?ops_request_misc=&request_id=&biz_id=102&utm_term=%25E6%25B5%2585%25E6%259E%2590%25E4%25B8%25BA%25E4%25BB%2580%25E4%25B9%2588char%25E7%25B1%25BB%25E5%259E%258B%25E7%259A%2584%25E8%258C%2583%25E5%259B%25B4%25E6%2598%25AF%2520%25E2%2580%2594128~%2520127&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-52602279.pc_search_result_no_baidu_js  浅析为什么char类型的范围是 —128~+127]
  
=Eclipse安装中文语言包(官方汉化)=
 
  
[https://zhuanlan.zhihu.com/p/342692825 Eclipse安装中文语言包(官方汉化)]
+
[https://wenwen.sogou.com/z/q871193299.htm?ch=fromnewwenwen.pc char 其数值表示 范围的计算]
=trouble shooting=
+
 
 +
[https://www.bilibili.com/video/BV1Gt4y1D73z?from=search&seid=13506202580160943636 b站 C语言数据类型及数值范围]
 +
 
 +
===原码 补码 反码 ===
 
<pre>
 
<pre>
launch failed Binary not found 每个项目都是改一下 不然不行
+
1.原码
 +
最高位表示符号位。剩下的位数,是这个数的绝对值的二进制
 +
 
 +
就比方说 一个完整的int型变量在内存中占的是4个字节,32位的编译器中 那么这时候他的二进制表示是00000000 00000000 00000000 00000000
 +
 
 +
所以
 +
 
 +
10的原码就是00000000 00000000 00000000 00001010
 +
 
 +
那么负数的原码就是例如
 +
 
 +
-10的原码10000000 00000000 00000000 00001010
 +
 
 +
  符号位是第一位 0为正数 1为负数
 +
 
 +
2.反码
 +
    正数的反码就是其原码.
 +
 
 +
    负数的反码就是在其原码的基础之上 符号位不变,其他位取反.
 +
   
 +
3.补码
 +
 
 +
    正数的补码就是其原码.
 +
 
 +
    负数的补码就是在其反码的基础之上+1
 +
   
 +
</pre>
 +
 
 +
[https://www.cnblogs.com/wangxiaoqi/p/6419676.html  C语言中的原码、反码和补码 ]
 +
 
 +
[https://www.cnblogs.com/burningc/p/10741253.html  C语言之原码、反码和补码 ]
 +
 
 +
[https://blog.csdn.net/liuyangsyouxiang/article/details/6050525  C语言——源码、反码、补码]
 +
 
 +
[https://www.bilibili.com/video/BV1Wx411g7Jg/?spm_id_from=333.788.videocard.1 b站原码 反码 补码]
 +
 
 +
=gdb=
 +
<pre>
 +
 
 +
 
 +
 
 +
start  st 开始执行程序,在main函数的第一条语句前面停下来
 +
step      s  下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句
 +
next    n  执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
 
 +
使用例子  结合他看C代码 爽到不行了
 +
184
 +
185gcc -g 11.2.c -o 11.2
 +
186gdb 11.2
 +
187
 +
188(gdb) start
 +
189(gdb) s  #一直用step命令(简写为s)进入函数中 ,n命令呢
 +
190
 +
191
 +
192step s  下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句
 +
193next n  执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)
 +
 
 +
</pre>
 +
 
 +
=c=
 +
<pre>
 +
 
 +
/*                                                                                                                                                                                         
 +
20答案是 Tuesday  因为列数定了是10                                                                                                                                                           
 +
21days[2] === days[2][10]                                                                                                                                                                   
 +
22                                                                                                                                                                                           
 +
23解说                                                                                                                                                                                       
 +
24days[2][0]=T                                                                                                                                                                               
 +
25days[2][1]=u                                                                                                                                                                               
 +
26days[2][2]=e                                                                                                                                                                               
 +
27days[2][3]=s                                                                                                                                                                               
 +
28days[2][4]=d                                                                                                                                                                               
 +
29days[2][5]=a                                                                                                                                                                               
 +
30days[2][6]=y                                                                                                                                                                               
 +
31days[2][7]=                                                                                                                                                                               
 +
32days[2][8]=                                                                                                                                                                               
 +
33days[2][9]=                                                                                                                                                                               
 +
34                                                                                                                                                                                           
 +
35               
 +
</pre>
 +
==eg ==
 +
=== 石头剪刀布===
 +
<pre>
 +
#include <stdio.h>
 +
#include <stdlib.h>
 +
#include <time.h>
 +
 
 +
int main(void)
 +
{
 +
char gesture[3][10] = { "scissor", "stone", "cloth" };
 +
int man, computer, result, ret;
 +
 
 +
srand(time(NULL));
 +
while (1) {
 +
computer = rand() % 3;
 +
  printf("\nInput your gesture (0-scissor 1-stone 2-cloth):\n");
 +
ret = scanf("%d", &man);
 +
  if (ret != 1 || man < 0 || man > 2) {
 +
printf("Invalid input! Please input 0, 1 or 2.\n");
 +
continue;
 +
}
 +
printf("Your gesture: %s\tComputer's gesture: %s\n",
 +
gesture[man], gesture[computer]);
 +
 
 +
result = (man - computer + 4) % 3 - 1;
 +
if (result > 0)
 +
printf("You win!\n");
 +
else if (result == 0)
 +
printf("Draw!\n");
 +
else
 +
printf("You lose!\n");
 +
}
 +
return 0;
 +
}
 +
 
 +
 
 +
/*
 +
0、1、2三个整数分别是剪刀石头布在程序中的内部表示,用户也要求输入0、1或2,然后和计算机随机生成的0、1或2比胜负。这个程序的主体是一个死循环,需要按Ctrl-C退出程序。以往我们写的程序都只有打印输出,在这个程序中我们第一次碰到处理用户输入的情况。在这里只是简单解释一下,以后再细讲。scanf("%d", &man)这个调用的功能是等待用户输入一个整数并回车,这个整数会被scanf函数保存在man这个整型变量里。如果用户输入合法(输入的确实是整数而不是字符串),则scanf函数返回1,表示成功读入一个数据。但即使用户输入的是整数,我们还需要进一步检查是不是在0~2的范围内,写程序时对用户输入要格外小心,用户有可能输入任何数据,他才不管游戏规则是什么。
 +
 
 +
和printf类似,scanf也可以用%c、%f、%s等转换说明。如果在传给scanf的第一个参数中用%d、%f或%c表示读入一个整数、浮点数或字符,则第二个参数的形式应该是&运算符加一个相应类型的变量名,表示读进来的数存到这个变量中;如果在第一个参数中用%s读入一个字符串,则第二个参数应该是数组名,数组名前面不加&,因为数组类型做右值时自动转换成指针类型,而scanf后面这个参数要的就是指针类型,在第 10 章 gdb有scanf读入字符串的例子。&运算符的作用也是得到一个指针类型,这个运算符以后再详细解释。
 +
 
 +
留给读者的思考问题是:(man - computer + 4) % 3 - 1这个神奇的表达式是如何比较出0、1、2这三个数字在“剪刀石头布”意义上的大小的
 +
*/
 +
 
 +
</pre>
 +
 
 +
[https://wenku.baidu.com/view/55e520da5022aaea998f0f5e.html 石头剪刀布_C语言]
 +
 
 +
https://blog.csdn.net/guoqingchun/article/details/8104197
 +
 
 +
 
 +
===Linux下C语言获取目录中的文件列表 ===
 +
<pre>
 +
/*
 +
* dir.c
 +
*
 +
Linux下C语言获取目录中的文件列表  https://www.cnblogs.com/dgwblog/p/12158373.html
 +
http://c.biancheng.net/cpp/html/1548.html  怎样使用C语言列出某个目录下的文件?
 +
*  Created on: 2020年11月2日
 +
*      Author: evan
 +
*/
 +
#include <sys/types.h>
 +
#include <dirent.h>
 +
#include <unistd.h>
 +
#include <stdio.h>
 +
int main(){
 +
DIR *dir;
 +
struct  dirent *ptr;
 +
dir = opendir("/home/evan/t1/");
 +
while((ptr = readdir(dir)) != NULL)
 +
printf("d_name:%s\n",ptr->d_name);
 +
closedir(dir);
 +
return 0;
 +
}
 +
 
 +
 
 +
/* 结果
 +
*
 +
d_name:.
 +
d_name:..
 +
d_name:1.py
 +
d_name:22.py
 +
 
 +
*/
 +
 
 +
 
 +
</pre>
 +
 
 +
=排序与查找=
 +
==插入排序 ==
 +
<pre>
 +
#include <stdio.h>
 +
#define LEN 5
 +
int a[LEN] = { 10, 5, 2, 4, 7 };
 +
void insertion_sort(void)
 +
{
 +
int i, j, key;
 +
for (j = 1; j < LEN; ++j) {
 +
printf("%d, %d, %d, %d, %d\n",
 +
      a[0], a[1], a[2], a[3], a[4]);
 +
key = a[j];  //key 标记为未排序的第一个元素
 +
i = j - 1;
 +
                // key  与已排序元素从大到小比较,寻找key应插入的元素 a[i+1]一般就是key 起初的值
 +
////采用顺序查找方式找到插入的位置,在查找的同时,将数组中的元素进行后移操作,给插入元素腾出空间 ?
 +
 
 +
while (i >= 0 && a[i] > key) {
 +
a[i+1] = a[i];
 +
--i; //跳出while
 +
}
 +
a[i+1] = key; ////插入到正确位置
 +
}
 +
printf("%d, %d, %d, %d, %d\n",
 +
      a[0], a[1], a[2], a[3], a[4]);
 +
}
 +
int main(void)
 +
{
 +
insertion_sort();
 +
return 0;
 +
}
 +
/* 就是key 一直和前面排好的比,找到正确的位置
 +
10, 5, 2, 4, 7
 +
5, 10, 2, 4, 7
 +
2, 5, 10, 4, 7
 +
2, 4, 5, 10, 7
 +
2, 4, 5, 7, 10 */
 +
</pre>
 +
 
 +
 
 +
===算法的时间复杂度分析===
 +
则总的执行时间粗略估计是(n-1)*(c1+c2+c5+m*(c3+c4))。 #怎么来的呢  线性函数  不记得了 要补一下
 +
 
 +
[https://blog.csdn.net/qq_25775935/article/details/88724130 插入排序算法及C语言实现]
 +
 
 +
 
 +
==11.4 归并排序==
 +
递归实现 归并排序
 +
 
 +
 
 +
 
 +
 
 +
===see also===
 +
 
 +
 
 +
还有下一节 ?
 +
 
 +
[https://www.bilibili.com/video/av73101599?from=search&seid=6748303640916868853 4-5 通过归并排序算法深入理解递归]
 +
 
 +
 
 +
非递归
 +
https://blog.csdn.net/zjy900507/article/details/80530336
 +
 
 +
=chapter 12 栈与队列=
 +
==堆栈==
 +
http://docs.linuxtone.org/ebooks/C&CPP/c/ch12s02.html
 +
==3. 深度优先搜索 ==
 +
未看
 +
http://akaedu.github.io/book/ch12s03.html
 +
 
 +
 
 +
=第 13 章 计算机中数的表示=
 +
==1. 为什么计算机用二进制计数==
 +
 
 +
=第 14 章 计算机中数的表示=
 +
 
 +
[http://c.biancheng.net/cpp/html/437.html c语言基本数据类型short、int、long、char、float、double]
 +
 
 +
[https://www.cnblogs.com/luofay/p/6070613.html  C语言的基本数据类型 ]
 +
 
 +
 
 +
[https://www.php.cn/csharp-article-443107.html c语言char是什么意思]
 +
== 二进制制转十进制==
 +
<pre>
 +
在 C 语言中, signed char 类型的范围为 -128~127,每本教科书上也这么写,但是没有哪一本书上(包括老师)也不会给你为什么是 -128~127,这个问题貌似看起来也很简单容易, 以至于不用去思考为什么,不是有一个整型范围的公式吗:  -2^(n-1)~2^(n-1)-1 (n为整型的内存占用位数),所以 int 类型 32 位那么就是 -(2^31) ~ 2^31-1 即 -2147483648~2147483647,但是为什么最小负数绝对值总比最大正数多 1 ,这个问题甚至有的工作几年的程序员都模棱两可,因为没有深入思考过,只知道书上这么写。于是,我不得不深入思考一下这个被许多人忽视的问题。
 +
 
 +
对于无符号整数,很简单,全部位都表示数值,比如 char 型,8位,用二进制表示为 0000 0000 ~ 1111 1111,1111 1111 最大即为十进制255,所以 unsigned char 的范围为 0~ 255,在这里普及一下 2 进制转十进制的方法, 二进制每一位的数值乘以它的位权(2^(n-1),n为自右向左的位),再相加,可得到十进制数,比如 :1111 1111 = 1*2^7 + 1*2^6 + 1*2^5 + 1*2^4 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0 = 255 。
 +
 
 +
 
 +
但是对于有符号整数,二进制的最高位表示正负,不表示数值,最高位为 0 时表示正数,为 1 时表示负数,这样一来,能表示数值的就剩下( n-1 )位了,
 +
比如 char a = -1;  那么二进制表示就为 1 0000001,1 表示为 0 0000001,所以 signed char 型除去符号位剩下的 7 位最大为 1111 111 = 127,再把符号加上,0 1111111 = 127,1 1111111 = -127,范围应该为 -127~127 ,同理 int 类型也一样,但是问题出来了,教科书上是 -128~127 啊,下面就剖析一下这个惊人的奇葩。 加上反码 看到这里
 +
 
 +
 
 +
再普及一下计算机内部整数存储形式,大家都知道计算机内部是以二进制来存贮数值的,无符号整数会用全部为来存储,有符号的整数,最高位当做符号位 ,其余为表示数值。
 +
</pre>
 +
 
 +
=第 17 章=
 +
==3. 设备==
 +
http://akaedu.github.io/book/ch17s03.html
 +
 
 +
=4. MMU=
 +
按照离CPU由近到远的顺序依次是CPU寄存器、Cache、内存、硬盘,越靠近CPU的存储器容量越小但访问速度越快
 +
http://akaedu.github.io/book/ch17s04.html
 +
 
 +
=Memory Hierarchy=
 +
http://akaedu.github.io/book/ch17s05.html
 +
 
 +
=附录 A. 字符编码=
 +
20191112
 +
字符编码的高位 左边是也
 +
 
 +
=如何学习c=
 +
 
 +
== mongoose 开源http库==
 +
有空学习这个作为C的入门例子
 +
 
 +
Mongoose是一个用C编写的网络库。它为客户端和服务器模式实现TCP,UDP,HTTP,WebSocket,CoAP,MQTT的事件驱动的非阻塞API。
 +
[https://www.cnblogs.com/gardenofhu/p/6961343.html  mongoose 开源http库 ]
 +
 
 +
[https://www.cnblogs.com/lifan3a/articles/7478295.html  Mongoose 利用实现HTTP服务 ]
 +
=funciton=
 +
== ==
 +
<pre>
 +
时间搞定
 +
头文件:#include <time.h>
 +
 
 +
定义函数:char *ctime(const time_t *timep);
 +
 
 +
函数说明:ctime()将参数timep 所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为"Wed Jun 30 21 :49 :08 1993\n"。
 +
 
 +
注意:若再调用相关的时间日期函数,此字符串可能会被破坏。
 +
 
 +
https://www.runoob.com/cprogramming/c-function-ctime.html
 +
</pre>
 +
==strcmp  ==
 +
<pre>
 +
C/C++函数,比较两个字符串
 +
 
 +
strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数
 +
 
 +
设这两个字符串为str1,str2,
 +
 
 +
若str1==str2,则返回零;
 +
 
 +
若str1<str2,则返回负数;
 +
 
 +
若str1>str2,则返回正数。
 +
</pre>
 +
[https://baike.baidu.com/item/strcmp/5495571 strcmp]
 +
 
 +
https://baike.so.com/doc/61175-64376.html
 +
 
 +
==C library function - remove()==
 +
<pre>
 +
/*
 +
* remvoe.c
 +
*
 +
*  Created on: 2020年11月30日
 +
*      Author: evan
 +
*/
 +
#include <stdio.h>
 +
#include<string.h>
 +
 
 +
int main() {
 +
int ret;
 +
FILE *fp;
 +
char filename[] = "file.txt";  // 这个是什么意思  定义一个 数组 ? 是的 
 +
 
 +
fp = fopen(filename,"w");
 +
 
 +
fprintf(fp,"%s", "THis is tutor \n");
 +
fprintf(fp,"%s", "ln2 THis is tutor");
 +
fclose(fp);
 +
 
 +
//ret = remove(filename);
 +
/*
 +
cat file.txt
 +
THis is tutor*/
 +
 
 +
if(ret == 0) {
 +
printf("file deleted successfully");
 +
}else {
 +
printf("Error: unable to delte the file");
 +
}
 +
return(0);
 +
 
 +
}
 +
 
 +
 
 +
</pre>
 +
 
 +
== C语言perror函数的作用 ==
 +
<pre>
 +
 不可以掉了这个头文件,perror是包含在这个文件里的//编辑本段perror表头文件完善版定义函数
 +
  void perror(const char *s); perror ("open_port");
 +
函数说明
 +
  perror ( )用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到 标 准 设备 (stderr) 。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量errno 的值来决定要输出的字符串。   在库函数中有个errno变量,每个errno值对应着以字符串表示的错误类型。当你调用"某些"函数出错时,该函数已经重新设置了errno的值。perror函数只是将你输入的一些信息和现在的errno所对应的错误一起输出。
 +
 
 +
void perror(const char *str)
 +
 
 +
参数
 +
 
 +
    str -- 这是 C 字符串,包含了一个自定义消息,将显示在原本的错误消息之前
 +
 
 +
#include <stdio.h>   
 +
int main(void)   
 +
{   
 +
FILE *fp ;   
 +
fp = fopen( "/root/noexitfile", "r+" );   
 +
if ( NULL == fp )  ?
 +
{   
 +
perror("/root/noexitfile");   //下面有这个输出
 +
}   
 +
return 0;   
 +
}
 +
 
 +
运行结果
 +
[root@localhost io]# gcc perror.c   
 +
[root@localhost io]# ./a.out   
 +
/root/noexitfile: No such file or directory
 +
 
 +
</pre>
 +
 
 +
 
 +
 
 +
[https://blog.csdn.net/ypist/article/details/7886209  linux下 C语言perror函数的作用]
 +
 
 +
https://www.cnblogs.com/yujianfei/p/8973867.html
 +
 
 +
https://www.runoob.com/cprogramming/c-function-perror.html
 +
 
 +
 
 +
==c语言实现rm命令 or 删除==
 +
<pre>
 +
头文件:#include <stdio.h>
 +
 
 +
remove()函数用于删除指定的文件,其原型如下:
 +
    int remove(char * filename);
 +
 
 +
【参数】filename为要删除的文件名,可以为一目录。如果参数filename 为一文件,则调用unlink()处理;若参数filename 为一目录,则调用rmdir()来处理。
 +
 
 +
【返回值】成功则返回0,失败则返回-1,错误原因存于errno。
 +
</pre>
 +
 
 +
[https://blog.csdn.net/teleger/article/details/80537229?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.pc_relevant_is_cache&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.pc_relevant_is_cache  C语言remove()函数:删除文件或目录]
 +
 
 +
[https://blog.csdn.net/piaoliangjinjin/article/details/80707139?utm_medium=distribute.pc_relevant.none-task-blog-title-7&spm=1001.2101.3001.4242  linux下实现rm()函数删除文件或目录]
 +
 
 +
[https://blog.csdn.net/qq_38074673/article/details/98047329  c语言实现rm命令,删除指定文件或目录]
 +
 
 +
==C语言access()函数:判断是否具有存取文件的权限==
 +
 
 +
 
 +
[http://c.biancheng.net/cpp/html/303.html C语言access()函数:判断是否具有存取文件的权限]
 +
 
 +
[https://blog.csdn.net/eager7/article/details/8131169  C语言中access函数]
 +
 
 +
[https://www.runoob.com/cprogramming/c-arrays.html C 数组]
 +
 
 +
 
 +
=进阶=
 +
==十个经典的C开源项目代码==
 +
[https://blog.51cto.com/chinalx1/2143904 十个经典的C开源项目代码]
 +
 
 +
 
 +
=2021=
 +
 
 +
 
 +
[https://www.cnblogs.com/wucongzhou/p/12498740.html#%E4%B8%80%E3%80%81%E8%8E%B7%E5%8F%96%E5%BD%93%E5%89%8D%E5%B7%A5%E4%BD%9C%E7%9B%AE%E5%BD%95 C语言目录操作]
 +
 
 +
[http://www.freecplus.net C语言技术网]
  
select "Run". -> Run Configurations. ->Choose "C++ Application". ->   build  configuration  --> select debug    auto build#is me
+
[https://www.cnblogs.com/qigaohua/p/5838263.html      博客园   C语言中关于对目录的操作 ]
  
Click on the "New Launch Configuration" icon on the top left of the open window.
+
=书=
Select "Browse" under the C/C++ Application.
+
[https://www.codetd.com/article/2162329 《Linux环境C程序设计(第2版)徐诚》pdf 附下载链接]
Browse to the folder where you made your project initially.
 
Enter the Debug folder.
 
Click on the binary file with the same name as the project.
 
Select "OK".
 
Click "Apply" to confirm the link you just set.
 
Close that window.</pre>
 
  
=参考=
+
http://www.txtepub.com/105693.html
[http://blog.linuxchina.net/?p=1019 eclipse 简单使用]
 
  
[http://blog.linuxchina.net/?p=2911 eclipse使用]
+
=see also=
 +
[https://wiki.ubuntu.com.cn/C%E8%AF%AD%E8%A8%80%E7%AE%80%E8%A6%81%E8%AF%AD%E6%B3%95%E6%8C%87%E5%8D%97 C语言简要语法指南]
  
[https://blog.csdn.net/qq_33850438/article/details/81071102  Linux Eclipse C++安装以及日常使用]
+
https://wiki.ubuntu.com.cn/Compiling_C
  
[https://blog.csdn.net/faihung/article/details/60780646 用Eclipse完成C语言编程的几个简单步骤]
+
[https://wiki.ubuntu.com.cn/Gcchowto Gcc-howto]
  
[https://linuxhint.com/install_eclipse_ide_debian_10/ Installing Eclipse IDE on Debian 10]
+
=c++=
  
[https://blog.csdn.net/u012861467/article/details/79281112?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-2.control  Eclipse 配置C/C++开发环境]
+
[https://zh.wikipedia.org/wiki/C%2B%2B c++ zh.wikipedia.org]
  
[[category:c]]  [[category:ops]]
+
https://isocpp.org/
 +
[[category:c]]

2021年4月16日 (五) 01:41的版本



good http://akaedu.github.io/book/


C语言编程学习必备的一些网站,干货收藏!

带你学C带你飞》

如何学习C

学习C语言,如何看懂及掌握一个程序

2021学习C APUE

http://www.apuebook.com/

UNIX环境高级编程(书籍)笔记什么都 有呀

《UNIX环境高级编程》这本书怎么看?怎么学习


看法

第二章和第六章可以跳跳,回头看

7.中文版翻译有瑕疵,但是整体还是不错,不至于对阅读产生影响(信号量那章有细节问题,但是信号量那张和csapp第八章几乎重复)

首先,不要抱着一口气把这本书学完的心态去看。 尝试根据自己的兴趣,选择一个规模适当的开源项目,去阅读它的源代码。(例如我选择的就是一个小型的http服务器--Mongoose)当在某一方面发现自己有很多问题时,很希望去弄清楚时,这时候就可以去翻开手中的APUE,带着问题去阅读。这时候学习的效率必然比盲目地去看书更高,而且遗忘率也会降低。但是,仅仅读完是不够的。 很多时候,你看书的时候,会感觉自己看懂了,但是没过多久,又会发现自己忘了。或者,有时候你根本没看懂,而只是囫囵吞枣地看过去。所以,看完后,最好的方法就是写博客。尝试按照自己的理解以及逻辑,去将你学到的知识系统地阐述出来。这样,就算你以后忘了,再去翻翻博文,也能很快就捡起来。

十个最值得阅读学习的C开源项目代码

   Webbench
   Tinyhttpd
   cJSON
   CMockery
   Libev
   Memcached
   Lua
   SQLite
   UNIX v6
   NETBSD

建议先看 >> Unix/Linux编程实践教程

https://book.douban.com/subject/1219329/

http://item.kongfz.com/book/32040616.html?push_type=2&min_price=57.00&utm_source=101004009001

https://detail.tmall.com/item.htm?spm=a1z10.1-b.w9858442-8055933095.4.fH3HiL&id=19729431809

常用计算机书的下载

学习C语言,如何看懂及掌握一个程序!

十个经典的C开源项目代码

初学玩转C语言,这17个小项目收下不谢

https://zhuanlan.zhihu.com/p/83185476

tinyhttpd C 语言实现最简单的 HTTP 服务器 学习

tinyhttpd ------ C 语言实现最简单的 HTTP 服务器

https://github.com/nengm/Tinyhttpd

tinyhttpd源码详解

tinyhttp整理(一)

tinyhttp源码阅读(注释)

Tinyhttp源码分析及知识点总结

b站 C/C++ tinyHttp服务器小项目及源码讲解1

tinyhttpd深入解析与源码剖析

Tinyhttpd-master 源码学习笔记1

Tinyhttp源码分析

Tinyhttpd非官方镜像,Fork自sourceForge,仅供学习



tinyhttp源码分析

我把一些核心代码和相应的注释贴在这里,如果你感兴趣全部,可以移步我的github。 https://github.com/zhaozhengcoder/rebuild-the-wheel/tree/master/tinyhttpd


Tinyhttp 代码完全讲解

Mongoose-基于C的Web服务器代码学习

Mongoose-基于C的Web服务器 介绍和使用


Web服务器----mongoose

https://github.com/cesanta/mongoose

Mongoose源码剖析:外篇之web服务器

Mongoose-6.14源码剖析之基础篇

我的笔记

apue.3e/include/apue.h

chapter 1

APUE读书笔记-01UNIX系统概述

这是原文学不过是 Second Edition firefox 放大 就可以看 找一下 第三版本吧 Third Edition https://vaqeteart.gitee.io/file_bed/shared/books/APUE2/toc.html


?

C语言实现的ls命令源码分享-apue

C 语言实现 Linux ls 命令

understanding_unix_programming

chapter 2 who

/* 再看一下书 非常 好的啦  
who命令的实现过程是先打开一个系统文件UTMP_FILE,创建对应的格式struct utmpfd变量,读取数据到这个结构体中,作相应格式输出即可
*/
#include<stdio.h>
#include<utmp.h>
#include<fcntl.h>
#include <time.h>
#include<unistd.h>
#define SHOWHOST
void showtime(long);
void showtime(long timeval){
    char *cp;
    cp = ctime(&timeval);
    //cp[strlen(cp)-1]='\0';
    printf("%s",cp+4 ); //wed jun 21:40:09  +4是因为*cp所指的一串字符前4个字符表示为“星期”,可以忽略此信息
}
// 指向结构体 utmp 的指针 utbufp
void show_info(struct utmp *utbufp)
{
    printf("%-8.8s",utbufp->ut_name)	;
    printf(" ");
  printf("%-8.8s",utbufp->ut_line);
  printf("");
  printf("% 10ld",utbufp->ut_time );

  printf(" ");

  printf(" ");

}

int main()
{
   struct utmp current_record;
   int  utmpfd;
   int reclen = sizeof(current_record);

   if (( utmpfd = open (UTMP_FILE, O_RDONLY)) == -1) {
	   perror(UTMP_FILE);
	   return 1;
   }
   while ( read(utmpfd, &current_record, reclen) == reclen )
	   show_info(&current_record);
   close(utmpfd);
   return 0;

}
















C 库函数 void *memset(void *str, int c, size_t n) 复制字符 c(一个无符号字符)到参数 str 所指向的字符串的前 n 个字符。
memset(str,'$',7);

This is string.h library function
$$$$$$$ string.h library function

参考 和书 chapter 2 这个最接近原书的了

https://www.cnblogs.com/20145221GQ/p/6060420.html

who命令实现

unix/linux who命令的实现

https://www.runoob.com/cprogramming/c-function-memset.html

别人实现1

https://www.cnblogs.com/20145221GQ/p/6060420.html

https://gitee.com/20145221/linux-besti-is-2016-2017-1-20145221/blob/master/src/week09/who.c?dir=0&filepath=src%2Fweek09%2Fwho.c&oid=6ca54191e2a046c9de2e42cfc5eb895ff665b429&sha=6cd302d6cb4f0d36f667754e972ce63963483044#


#include <stdio.h>  
#include <utmp.h>
#include <fcntl.h>  
#include <unistd.h>  
#include <time.h>  
#include <string.h>
  
#define SHOWHOST  
  
void showtime(long timeval){  
    char* cp;  
    cp = ctime(&timeval);  
    cp[strlen(cp)-1] = '\0';
    printf("%s",cp+4);  
}  
  
void show_info(struct utmp* utbufp){  
    if(utbufp->ut_type != USER_PROCESS){  
        return ;  
    }  
  
    printf("%-8.8s",utbufp->ut_name);  
    printf(" ");  
    printf("%-8.8s",utbufp->ut_line);  
    printf(" ");  
    showtime(utbufp->ut_time);  
    printf(" ");  
  
#ifdef SHOWHOST  
    if(utbufp->ut_host[0] != '\0'){  
        printf("(%s)",utbufp->ut_host);  
    }  
#endif  
    printf("\n");  
}

int main(){  
    struct utmp current_record;  
    int utmpfd;  
    int reclen = sizeof(current_record);  
  
    if((utmpfd = open(UTMP_FILE,O_RDONLY)) == -1){  
        perror(UTMP_FILE);  
  
        return 1;  
    }  
  
    while( read(utmpfd,&current_record,reclen) == reclen ){  
        show_info(&current_record);  
    }  
  
    close(utmpfd);  
  
    return 0;  
}  

see also

who命令实现


cp


#include        <stdio.h>//标准输入输出
#include        <stdlib.h>//C标准函数库
#include        <unistd.h>//Unix类系统定义符号常量
#include        <fcntl.h>//定义了很多宏和open,fcntl函数原型

#define BUFFERSIZE      4096//定义存储器容量
#define COPYMODE        0644//定义复制的长度

void oops(char *, char *);
/*注意main函数的两个参数:
  argc记录了用户在运行程序的命令行中输入的参数的个数。
  arg[]指向的数组中至少有一个字符指针,即arg[0].它通常指向程序中的可执行文件的文件名。 */
main(int ac,char *av[])
{
    int in_fd, out_fd,n_chars;    //三个描述符值 in_fd为open返回的描述符 ,create out_fd为open返回的描述符  n_chars  读取的数据 function 见上个who  read的
    char buf[BUFFERSIZE]; //存储器位置
/*cp的参数有两个,分别是要复制的文件,和目的目录,这样一共应该是有三个操作数
  所以要先检查argc的值是否为三,如果不是,返回标准错误*/
        if(ac !=3) {
            fprintf(stderr, "usage:%s source destination\n",* av);
            exit(1);
        }
        /* open files 检查cp的第一个参数,要复制的文件,用open打开,in_fd为open返回的描述符 如果返回-1,代表打开失败,提示错误
           why CP 第一个参数是 av[1],  av[0] 是程序中的可执行的文件名也就是自己
        */
        if ((in_fd=open(av[1],O_RDONLY)) == -1)
            oops("Cannot open",av[1]);

/*检查cp的第二个参数,复制的目的地址,用create在目的地址创建新文件,out_fd为open返回的描述符
  如果返回-1,代表创建失败,提示错误 ; create 创建的位置就是av[2] 目标文件的位置是也
  为什么是 av[2]  就是 cp 命令的 第二个参数 也就是 目标文件 ,本来不存在 所以要create
*/
if(out_fd=creat(av[2],COPYMODE)== -1)
    oops("Cannot creat",argv[2])
}
/*copyfiles  cp指令的动作就是读取一个文件的内容到存储器,在新的地址创建空白文件,再从存储器将内容写入新文件。
  这里判断复制是否成功:
  如果能读取顺利,而读取的位数和写的位数不同,是写错误;
  如果读取失败,是读错误。
  why n_chars 是什么
  内核从utmpfd所指定的文件中读取了 reclen字节的数据,存放到 current_record所指定的内存空间中
  while ( read(utmpfd, &current_record, reclen) == reclen )

  write out_fd 文件描述符  buf 内存数据, n_chars 要写的字节数

循环的把源文件写入目标文件
*/
while ((n_chars= read(int __fd,buf,BUFFERSIZE))>0) {
    if(write(out_fd,buf,n_chars) != n_chars)
        oops("Write error to ", av[2]);
    if (n_chars== -1)

        oops("Read error from ",argv[1]);
/*这里执行的是关闭文件的动作,in_fd open的 和out_fd create的两个文件描述符
  所指向的文件只要有一个关闭错误,就提示关闭错误。*/
    if (close(in_fd) == -1 || close(out_fd)== -1)
        oops("Error closing files","");
}

/*不太明白为什么是指针了这里 evan  这个是用来输出错误信息的函数*/
void oops(char *s1, char *s2)
{
    fprintf(stderr, "Error:%s", s1);
    perror(s2); // 用来将上一个函数发生错误的原因输出到标准设备(stderr)
    exit(1)

        }


cp命令的编写最接受原书的了

Unix程序设计:实现cp命令

linux自己编写的 cp 命令像os的那个了

http://bbs.chinaunix.net/thread-247946-1-1.html

linux cp命令源码

ls

data/c/example/unixeg/ls/



第二版本的参考

linux系统编程:自己动手写一个ls命令


Linux下的 ls 命令的简单实现

高仿linux下的ls -l命令——C语言实现


在linux下编写一个LS命令的小程序

Linux系统编程【3.1】——编写ls命令

Linux系统编程【3.2】——ls命令优化版和ls -l实现

C 语言实现 Linux ls 命令

简单版本的参考

https://github.com/fupengfei058/ls

http://www.voidcn.com/article/p-bzocmlpx-bxd.html

https://blog.csdn.net/qingshui23/article/details/53931555

https://blog.csdn.net/aonaigayiximasi/article/details/54019964

C IDE

https://www.jetbrains.com/zh-cn/clion/

Eclipse

Anjuta on linux

https://atom.io/

pre main

 init main( int argc, char *argv[]);
argc 是命令行参数的数目 也包括自身 没有后台的参数 那么 argc=1

argv 指向参数的各个指针所构成的数组, argv[0]表示命令本身,argv[1] 表示第一个参数

argc 是argument count的缩写表示传入main函数中的参数个数,包括这个程序本身

argv 是 argument vector的缩写表示传入main函数中的参数列表,其中argv[0]表示这个程序的名字; *argv[] 其实是地址 

第二个参数,char*型的argv[],为字符串数组,用来存放指向的字符串参数的指针数组,每一个元素指向一个参数。各成员含义如下:
        argv[0]指向程序运行的全路径名
        argv[1]指向在DOS命令行中执行程序名后的第一个字符串 

char   *argv[]是一个字符数组,其大小是int   argc,主要用于命令行参数   argv[]   参数,数组里每个元素代表一个参数;

看代码的时候我最先不理解的就是main函数的定义:

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

经查阅得知,argc是用来表示在命令行下输入命令时的参数个数,包括指令本身;argv[]是用来取得你输入的参数。针对具体指令分析如下(每一步解释由注释形式给出)。

由于main函数不能被其它函数调用, 因此不可能在程序内部取得实际值。那么,在何处把实参值赋予main函数的形参呢? 实际上,main函数的参数值是从操作系统命令行上获得的。当我们要运行一个可执行文件时,在DOS提示符下键入文件名,再输入实际参数即可把这些实参传送到main的形参中去。

ls1.c中的 就是这个了啦 
DOS提示符下命令行的一般形式为: C:\>可执行文件名 参数 参数……; 但是应该特别注意的是,main 的两个形参和命令行中的参数在位置上不是一一对应的。因为,main的形参只有二个,而命令行中的参数个数原则上未加限制。argc参数表示了命令行中参数的个数(注意:文件名本身也算一个参数),argc的值是在输入命令行时由系统按实际参数的个数自动赋予的。例如有命令行为: C:\>E6 24 BASIC dbase FORTRAN由于文件名E6 24本身也算一个参数,所以共有4个参数,因此argc取得的值为4。argv参数是字符串指针数组,其各元素值为命令行中各字符串(参数均按字符串处理)的首地址。 指针数组的长度即为参数个数。数组元素初值由系统自动赋予。其表示如图6.8所示:

main(int argc,char *argv){
while(argc-->1)
printf("%s\n",*++argv);
}

本例是显示命令行中输入的参数如果上例的可执行文件名为e24.exe,存放在A驱动器的盘内。
因此输入的命令行为: C:\>a:e24 BASIC dBASE FORTRAN  
则运行结果为:
BASIC
dBASE
FORTRAN
  该行共有4个参数,执行main时,argc的初值即为4。argv的4个元素分为4个字符串的首地址。执行while语句,每循环一次 argv值减1,当argv等于1时停止循环,共循环三次, 因此共可输出三个参数。在printf函数中,由于打印项*++argv是先加1再打印, 故第一次打印的是argv[1]所指的字符串BASIC。第二、 三次循环分别打印后二个字符串。而参数e24是文件名,不必输出。

另外一个例子


c语言中argc和argv[ ]的作用及用法

good和ls1.c差不多 C语言中 int main(int argc,char *argv[])的两个参数详解

https://zhuanlan.zhihu.com/p/267822985

https://blog.csdn.net/LYJ_viviani/article/details/51873961

c语言之argc和argv

基础

计算机为什么要用二进制

Everything over Binary 模拟路转换成为数字电路

https://blog.csdn.net/weixin_44296862/article/details/95277924

https://blog.csdn.net/c46550/article/details/90951557

一位全加器

signed char 类型的范围为 -128~127

 按八位来算:
在计算机里面是用补码表示的,128的二进制码是:10000000,这个东西在计算里面并不是128,因为最高位是符号,它是个负数,那么负数的原码是多少呢,我们知道如果补码的符号位为“1”,表示是一个负数,求原码的操作可以是:符号位为1,其余各位取反,然后再整个数加1。 
所以,10000000取反后就是11111111,把符号位去了就是01111111再加1就是10000000就是-128了。
其实你看-127是10000001,这个很好理解,-128加1不就是-127
[https://blog.csdn.net/zy986718042/article/details/71699079 浅谈char类型范围]

补码表示时,-0和+0补码相同都是0 000 0000,所义导致可以多表示一个负数,...这个负数是最小的那个..

浅析为什么char类型的范围是 —128~+127


char 其数值表示 范围的计算

b站 C语言数据类型及数值范围

原码 补码 反码

1.原码
最高位表示符号位。剩下的位数,是这个数的绝对值的二进制

就比方说 一个完整的int型变量在内存中占的是4个字节,32位的编译器中 那么这时候他的二进制表示是00000000 00000000 00000000 00000000

所以

10的原码就是00000000 00000000 00000000 00001010

那么负数的原码就是例如

-10的原码10000000 00000000 00000000 00001010

 符号位是第一位 0为正数 1为负数

2.反码
    正数的反码就是其原码.

    负数的反码就是在其原码的基础之上 符号位不变,其他位取反.
    
3.补码

    正数的补码就是其原码.

    负数的补码就是在其反码的基础之上+1
    

C语言中的原码、反码和补码

C语言之原码、反码和补码

C语言——源码、反码、补码

b站原码 反码 补码

gdb




start   st 开始执行程序,在main函数的第一条语句前面停下来
step       s   下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句
 next    n  执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)









使用例子  结合他看C代码 爽到不行了 
184
185gcc -g 11.2.c -o 11.2
186gdb 11.2
187
188(gdb) start
189(gdb) s   #一直用step命令(简写为s)进入函数中 ,n命令呢
190
191
192step s  下一条语句,如果该语句为函数调用,则进入函数执行其中的第一条语句
193next n  执行下一条语句,如果该语句为函数调用,不会进入函数内部执行(即不会一步步地调试函数内部语句)

c


/*                                                                                                                                                                                          
20答案是 Tuesday  因为列数定了是10                                                                                                                                                            
21days[2] === days[2][10]                                                                                                                                                                     
22                                                                                                                                                                                            
23解说                                                                                                                                                                                        
24days[2][0]=T                                                                                                                                                                                
25days[2][1]=u                                                                                                                                                                                
26days[2][2]=e                                                                                                                                                                                
27days[2][3]=s                                                                                                                                                                                
28days[2][4]=d                                                                                                                                                                                
29days[2][5]=a                                                                                                                                                                                
30days[2][6]=y                                                                                                                                                                                
31days[2][7]=                                                                                                                                                                                 
32days[2][8]=                                                                                                                                                                                 
33days[2][9]=                                                                                                                                                                                 
34                                                                                                                                                                                            
35                 

eg

石头剪刀布

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

int main(void)
{
	char gesture[3][10] = { "scissor", "stone", "cloth" };
	int man, computer, result, ret;

	srand(time(NULL));
	while (1) {
		computer = rand() % 3;
	  	printf("\nInput your gesture (0-scissor 1-stone 2-cloth):\n");
		ret = scanf("%d", &man);
	  	if (ret != 1 || man < 0 || man > 2) {
			printf("Invalid input! Please input 0, 1 or 2.\n");
			continue;
		}
		printf("Your gesture: %s\tComputer's gesture: %s\n", 
			gesture[man], gesture[computer]);

		result = (man - computer + 4) % 3 - 1;
		if (result > 0)
			printf("You win!\n");
		else if (result == 0)
			printf("Draw!\n");
		else
			printf("You lose!\n");
	}
	return 0;
}


/*
0、1、2三个整数分别是剪刀石头布在程序中的内部表示,用户也要求输入0、1或2,然后和计算机随机生成的0、1或2比胜负。这个程序的主体是一个死循环,需要按Ctrl-C退出程序。以往我们写的程序都只有打印输出,在这个程序中我们第一次碰到处理用户输入的情况。在这里只是简单解释一下,以后再细讲。scanf("%d", &man)这个调用的功能是等待用户输入一个整数并回车,这个整数会被scanf函数保存在man这个整型变量里。如果用户输入合法(输入的确实是整数而不是字符串),则scanf函数返回1,表示成功读入一个数据。但即使用户输入的是整数,我们还需要进一步检查是不是在0~2的范围内,写程序时对用户输入要格外小心,用户有可能输入任何数据,他才不管游戏规则是什么。

和printf类似,scanf也可以用%c、%f、%s等转换说明。如果在传给scanf的第一个参数中用%d、%f或%c表示读入一个整数、浮点数或字符,则第二个参数的形式应该是&运算符加一个相应类型的变量名,表示读进来的数存到这个变量中;如果在第一个参数中用%s读入一个字符串,则第二个参数应该是数组名,数组名前面不加&,因为数组类型做右值时自动转换成指针类型,而scanf后面这个参数要的就是指针类型,在第 10 章 gdb有scanf读入字符串的例子。&运算符的作用也是得到一个指针类型,这个运算符以后再详细解释。

留给读者的思考问题是:(man - computer + 4) % 3 - 1这个神奇的表达式是如何比较出0、1、2这三个数字在“剪刀石头布”意义上的大小的
*/

石头剪刀布_C语言

https://blog.csdn.net/guoqingchun/article/details/8104197


Linux下C语言获取目录中的文件列表

/*
 * dir.c
 *
Linux下C语言获取目录中的文件列表  https://www.cnblogs.com/dgwblog/p/12158373.html
http://c.biancheng.net/cpp/html/1548.html  怎样使用C语言列出某个目录下的文件?
 *  Created on: 2020年11月2日
 *      Author: evan
 */
#include <sys/types.h>
#include <dirent.h>
#include <unistd.h>
#include <stdio.h>
int main(){
	 DIR *dir;
	 struct  dirent *ptr;
	 dir = opendir("/home/evan/t1/");
	 while((ptr = readdir(dir)) != NULL)
		 printf("d_name:%s\n",ptr->d_name);
	 closedir(dir);
	 return 0;
}


/* 结果
 *
d_name:.
d_name:..
d_name:1.py
d_name:22.py

*/


排序与查找

插入排序

#include <stdio.h>
#define LEN 5
int a[LEN] = { 10, 5, 2, 4, 7 };
void insertion_sort(void)
{
	int i, j, key;
	for (j = 1; j < LEN; ++j) {
		printf("%d, %d, %d, %d, %d\n",
		       a[0], a[1], a[2], a[3], a[4]);
		key = a[j];  //key 标记为未排序的第一个元素
		i = j - 1;
                // key  与已排序元素从大到小比较,寻找key应插入的元素 a[i+1]一般就是key 起初的值
////采用顺序查找方式找到插入的位置,在查找的同时,将数组中的元素进行后移操作,给插入元素腾出空间 ?

		while (i >= 0 && a[i] > key) {
			a[i+1] = a[i];
			--i; //跳出while 
		}
		a[i+1] = key; ////插入到正确位置
	}
	printf("%d, %d, %d, %d, %d\n",
	       a[0], a[1], a[2], a[3], a[4]);
}
int main(void)
{
	insertion_sort();
	return 0;
}
/* 就是key 一直和前面排好的比,找到正确的位置 
10, 5, 2, 4, 7
5, 10, 2, 4, 7
2, 5, 10, 4, 7
2, 4, 5, 10, 7
2, 4, 5, 7, 10 */ 


算法的时间复杂度分析

则总的执行时间粗略估计是(n-1)*(c1+c2+c5+m*(c3+c4))。 #怎么来的呢  线性函数  不记得了 要补一下

插入排序算法及C语言实现


11.4 归并排序

递归实现 归并排序



see also

还有下一节 ?

4-5 通过归并排序算法深入理解递归


非递归 https://blog.csdn.net/zjy900507/article/details/80530336

chapter 12 栈与队列

堆栈

http://docs.linuxtone.org/ebooks/C&CPP/c/ch12s02.html

3. 深度优先搜索

未看 http://akaedu.github.io/book/ch12s03.html


第 13 章 计算机中数的表示

1. 为什么计算机用二进制计数

第 14 章 计算机中数的表示

c语言基本数据类型short、int、long、char、float、double

C语言的基本数据类型


c语言char是什么意思

二进制制转十进制

 在 C 语言中, signed char 类型的范围为 -128~127,每本教科书上也这么写,但是没有哪一本书上(包括老师)也不会给你为什么是 -128~127,这个问题貌似看起来也很简单容易, 以至于不用去思考为什么,不是有一个整型范围的公式吗:  -2^(n-1)~2^(n-1)-1 (n为整型的内存占用位数),所以 int 类型 32 位那么就是 -(2^31) ~ 2^31-1 即 -2147483648~2147483647,但是为什么最小负数绝对值总比最大正数多 1 ,这个问题甚至有的工作几年的程序员都模棱两可,因为没有深入思考过,只知道书上这么写。于是,我不得不深入思考一下这个被许多人忽视的问题。

对于无符号整数,很简单,全部位都表示数值,比如 char 型,8位,用二进制表示为 0000 0000 ~ 1111 1111,1111 1111 最大即为十进制255,所以 unsigned char 的范围为 0~ 255,在这里普及一下 2 进制转十进制的方法, 二进制每一位的数值乘以它的位权(2^(n-1),n为自右向左的位),再相加,可得到十进制数,比如 :1111 1111 = 1*2^7 + 1*2^6 + 1*2^5 + 1*2^4 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^0 = 255 。


但是对于有符号整数,二进制的最高位表示正负,不表示数值,最高位为 0 时表示正数,为 1 时表示负数,这样一来,能表示数值的就剩下( n-1 )位了,
比如 char a = -1;   那么二进制表示就为 1 0000001,1 表示为 0 0000001,所以 signed char 型除去符号位剩下的 7 位最大为 1111 111 = 127,再把符号加上,0 1111111 = 127,1 1111111 = -127,范围应该为 -127~127 ,同理 int 类型也一样,但是问题出来了,教科书上是 -128~127 啊,下面就剖析一下这个惊人的奇葩。 加上反码 看到这里 


再普及一下计算机内部整数存储形式,大家都知道计算机内部是以二进制来存贮数值的,无符号整数会用全部为来存储,有符号的整数,最高位当做符号位 ,其余为表示数值。

第 17 章

3. 设备

http://akaedu.github.io/book/ch17s03.html

4. MMU

按照离CPU由近到远的顺序依次是CPU寄存器、Cache、内存、硬盘,越靠近CPU的存储器容量越小但访问速度越快

http://akaedu.github.io/book/ch17s04.html

Memory Hierarchy

http://akaedu.github.io/book/ch17s05.html

附录 A. 字符编码

20191112

字符编码的高位 左边是也

如何学习c

mongoose 开源http库

有空学习这个作为C的入门例子

Mongoose是一个用C编写的网络库。它为客户端和服务器模式实现TCP,UDP,HTTP,WebSocket,CoAP,MQTT的事件驱动的非阻塞API。 mongoose 开源http库

Mongoose 利用实现HTTP服务

funciton

时间搞定 
头文件:#include <time.h>

定义函数:char *ctime(const time_t *timep);

函数说明:ctime()将参数timep 所指的time_t 结构中的信息转换成真实世界所使用的时间日期表示方法,然后将结果以字符串形态返回。此函数已经由时区转换成当地时间,字符串格式为"Wed Jun 30 21 :49 :08 1993\n"。

注意:若再调用相关的时间日期函数,此字符串可能会被破坏。

https://www.runoob.com/cprogramming/c-function-ctime.html

strcmp

C/C++函数,比较两个字符串

strcmp函数是string compare(字符串比较)的缩写,用于比较两个字符串并根据比较结果返回整数

设这两个字符串为str1,str2,

若str1==str2,则返回零;

若str1<str2,则返回负数;

若str1>str2,则返回正数。

strcmp

https://baike.so.com/doc/61175-64376.html

C library function - remove()

/*
 * remvoe.c
 *
 *  Created on: 2020年11月30日
 *      Author: evan
 */
#include <stdio.h>
#include<string.h>

int main() {
	int ret;
	FILE *fp;
	char filename[] = "file.txt";  // 这个是什么意思  定义一个 数组 ? 是的  

	fp = fopen(filename,"w");

	fprintf(fp,"%s", "THis is tutor \n");
	fprintf(fp,"%s", "ln2 THis is tutor");
	fclose(fp);

	//ret = remove(filename);
/*
	 cat file.txt
	THis is tutor*/

	if(ret == 0) {
		printf("file deleted successfully");
	}else {
		printf("Error: unable to delte the file");
	}
	return(0);

}


C语言perror函数的作用

 不可以掉了这个头文件,perror是包含在这个文件里的//编辑本段perror表头文件完善版定义函数
  void perror(const char *s); perror ("open_port");
函数说明
  perror ( )用 来 将 上 一 个 函 数 发 生 错 误 的 原 因 输 出 到 标 准 设备 (stderr) 。参数 s 所指的字符串会先打印出,后面再加上错误原因字符串。此错误原因依照全局变量errno 的值来决定要输出的字符串。   在库函数中有个errno变量,每个errno值对应着以字符串表示的错误类型。当你调用"某些"函数出错时,该函数已经重新设置了errno的值。perror函数只是将你输入的一些信息和现在的errno所对应的错误一起输出。

void perror(const char *str)

参数

    str -- 这是 C 字符串,包含了一个自定义消息,将显示在原本的错误消息之前

#include <stdio.h>   
int main(void)   
{   
	FILE *fp ;   
	fp = fopen( "/root/noexitfile", "r+" );   
	if ( NULL == fp )  ?
	{   
		perror("/root/noexitfile");   //下面有这个输出
	}   
	return 0;   
}

运行结果
[root@localhost io]# gcc perror.c   
[root@localhost io]# ./a.out   
/root/noexitfile: No such file or directory


linux下 C语言perror函数的作用

https://www.cnblogs.com/yujianfei/p/8973867.html

https://www.runoob.com/cprogramming/c-function-perror.html


c语言实现rm命令 or 删除

头文件:#include <stdio.h>

remove()函数用于删除指定的文件,其原型如下:
    int remove(char * filename);

【参数】filename为要删除的文件名,可以为一目录。如果参数filename 为一文件,则调用unlink()处理;若参数filename 为一目录,则调用rmdir()来处理。

【返回值】成功则返回0,失败则返回-1,错误原因存于errno。

C语言remove()函数:删除文件或目录

linux下实现rm()函数删除文件或目录

c语言实现rm命令,删除指定文件或目录

C语言access()函数:判断是否具有存取文件的权限

C语言access()函数:判断是否具有存取文件的权限

C语言中access函数

C 数组


进阶

十个经典的C开源项目代码

十个经典的C开源项目代码


2021

C语言目录操作

C语言技术网

博客园 C语言中关于对目录的操作

《Linux环境C程序设计(第2版)徐诚》pdf 附下载链接

http://www.txtepub.com/105693.html

see also

C语言简要语法指南

https://wiki.ubuntu.com.cn/Compiling_C

Gcc-howto

c++

c++ zh.wikipedia.org

https://isocpp.org/