Linux C下面遇到的坑

  1. xshell与Linux系统文件编码的不同所造成的乱码问题,如果不能修改Linux的编码,那么可以试着修改xshell的编码。

  2. addr.sin_portInt并不是同一种结构,htons就是用来进行网络字节顺序和主机字节顺序转换的。

  3. 一定要看好括号的范围
    例如:connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length)<0
    错误:connect(client_socket, (struct sockaddr*)&server_addr, server_addr_length<0)
    例如:(fd=open(filebag.data, O_WRONLY|O_CREAT)) < 0
    错误:(fd=open(filebag.data, O_WRONLY|O_CREAT) < 0)还是不会报错,但是最后fd会为0
    虽然并不会报错,但是connect就会一直失败,erron会提示参数错误。

  4. erron全局错误变量可以起到错误提示作用,包含于erron.h中。

  5. 变量名要与类名区分开来,标准的命名规则还是很有用的。

  6. sdout会有缓存,printf中的内容并不会及时输出,这时可以加上"\n"或者fflush(sdout),就会强制刷新缓存区。

  7. openfopen有很大区别,返回值和参数都不一样。

  8. open函数还有第四个参数,用来设置创建的文件的权限。有时候不设置没问题,有时候有问题,所以还是设置一下吧。

  9. testLinux的一个指令,所以$test没有输出,而$./test指明了为文件,所以可以输出。

  10. 直接在case后面定义变量会报错,如果不加这种限制,可能就会出现这种情况 :

case 1:
int x;
case 2:
x = 0;

因为case的域实际上是连在一起的,所以在编译器编译时,并不会认为有错误,但是程序在实际运行时,直接跳到了case2,那么x明明没有被定义,却被使用,就会出错。解决方法:在case后面加上花括号。

  1. C里面并没有bool类型

  2. C中的if非零为真,零为假。指针实际上也为一个int数值,所以可以进行真or假判断。

  3. FILE * 类型的指针实际上是指向一个结构体。

  4. perror(s)会优先输出s,再根据errno的值输出错误信息。

  5. 只有char类型数组才需要‘/0’

  6. 区分开'r'"r" 前者其实为int类型,而后者可以视为一个指针。fopen的参数就应该使用"r"

  7. 区分开"\0"'\0',前者是一个指针,后者是一个字符。但是如果使用"\0",会警告将指针赋给整数,而有时候结果却并不会出错。使用%d输出"\0",会输出符号+部分数字。或许是因为char的长度为1,Int的长度为4??

  8. malloc地址一定要memset,要不然错误free会报错。

  9. 只要使用mallocchar *ptr申请哪怕1个字节的空间,你就可以将一个很长的字符串给他,而且还可以正常输出,但是free的时候会报错。

  10. epoll_event.data 是一个union,fdptr只能选一个!

  11. epoll_ctl的时候,一定要确保epoll_event.dataepoll_event.events的值是正确的。

typedef struct queryStruct
{
    char type[10];
    char id[10];
    char name[30];
    char pass[30];
    char *sendMess;
} queryDataStruct;

//用来向线程中传入相关信息
typedef struct threadStruct
{
    int epollfd;
    int clienfd;
    struct  epoll_event stev;
    queryDataStruct *query;
} threadDataStruct;

//教训:向epoll_event stev.events中加入了数据,但是却没有管stev.data.ptr,所以虽然开头用
epoll_ctl(epollfd, EPOLL_CTL_ADD, clienfd, &(events[i]));  
//添加成功,因为前面把threadDataStruct的指针给了events[i].data.ptr

//但是后面,在其他函数中,只能使用自己的结构体作为参数
epoll_ctl(threadData->epollfd, EPOLL_CTL_DEL, threadData->clienfd,&(threadData->stev));
//又没有往threadData->stev.data.ptr中放值,造成地址类型的错误
  1. 不能把一个公用的全局指针从epoll读取块直接拿到epoll写入块中使用。因为读取块是用的clienfd=1,而写入块可能就是用的clienfd=22。一个客户端连接时没有影响,多个客户端连接,应该就会出现数据误传的情况。

  2. 结构体可以直接包含非自身结构体变量。

  3. 只要是C风格的char字符串,那么最后必然会带上一个\0。而strlen计算,碰到\0就会停止计数。所以在send数据,要使用sizeof(但是对指针只计算指针的大小,不计算数据大小)或者strlen(str)+1

  4. epoll事件使用ET读写模式,在服务端将缓存区数据读取完毕之后,当缓存区有新数据可读时,又会再次触发事件通知。ET只通知一次,指的是服务端自己缓存区取得一次数据(即有数据,然后读完算一次),而和客户端怎么取的没有关系。如果在处理读事件时,将数据的读取交给另外的线程处理,主线程继续循环处理监听到的events事件,那么就可能出现一个fd被放入多个线程的情况。这时就要在结构体中加一个判断变量,在将其放入线程前判断其前面是否已经被放入。

  5. send函数的参数如果超过发送数据的实际大小,那么就会发送重复的数据。所以最好将参数设置为数据的大小。

  6. send函数每次发送都会从参数的开头地址发送,recv接收时也是这样。(和文件的读取不一样)。所以C在循环读取数据并放入同一个字符数组中时,记得移动指针。

  7. sprintf函数的格式化功能还是挺强的,使用时要把参数确定好。例如:

sprintf(cLen, "%-10d", iLen);        //位数不够时用\0填充
sprintf(cLen, "%d", iLen);             //位数不够时用' '填充
  1. 例如下面这样:
    char *str1;
    char *str2;
    char *str3;

    str1 = (char *)malloc(11);
    str2 = (char *)malloc(100);

    strcpy(str1, "UUUUUUUUUU");
    strcpy(str2, "QQQQQQQQQQQQQQQQQQQQQQQ");

    str3 = str1 + 5;
    str3 = str2;

    printf("str1 = %s\n", str1);
    return 0;

是没有用的,因为以前学习数据结构时,经常使用例如

/*
struct queue 
{
    struct queue *next;
    int data;
}*/
struct queue *ptr = head;
ptr->next = 一个指针
head->next = 一个指针        //这两个是等效的
ptr = 一个指针
head = 一个指针              //这两个是不一样的

原因:head->nexthead自身包含的地址指向的一段内存,而head则是自身包含的地址。当ptr = head后,并不是说现在ptr就和head等价了(大学四年一直误以为此),只是prthead中包含的地址是一样的,当你用ptr->next进行操作的时候,是操作ptr包含的地址指向的空间,所以无论是对ptr还是对head进行操作,都是等同的。但是在对ptrhead进行操作的时候,你操作的就是两个完全不同的变量了,所以操作不等同。ptr = head,只是ptrhead中保存的地址一样了,而不是ptr本身的地址和head一样了。
就好像你把甲的仓库钥匙复制给了乙一份,那么甲和乙操作的仓库就是同一个仓库了,这时候你把乙的钥匙换了,那么甲的钥匙并不会跟着乙的一起变化。

  1. 可以使用realloc实现动态数组,虽然感觉并没有什么用。另外,为了减少realloc的次数,在分配空间和减少空间时,都可以预分配一定空间。

  2. char类型数组后面一定要有一个\0,如果你要用一个数组从一个字符串中复制出10个值,那么这个数组的大小起码要为11,如果大小为10,那么再你输出这个数组时,有可能连带输出后面地址的值。

  3. 能不用malloc就不要用,能不用多线程就不要用。

  4. 指针定义和free后指NULL是一个好习惯。

  5. str[i++]str[++i]也遵循先给后加和先加后给原则,即中括号并没有小括号的作用,它并没有优先级。

  6. 由于二进制不能精确表示小数,所以doublefloat有时候并不是精确的,只是在printf时会输出近似值。但是如果使用int强制转换,会完全丢失小数部分,然后就表现为比原数小1。解决办法:int(math + 0.5)

  7. C语言没有默认参数。

  8. 以前从来没有注意过,在C中不能单独输出一个中文字符串中的一个中文字符。一个中文字符占两个char。中文字符最小都是一个长度为2的字符串?

  9. const struct *head,那么head中变量值都不可以改变。

  10. math>>1math变为二进制,然后左移1位,位数不足补零。最好不要对有符号数使用,移位之后的位数不能超过有效位数。采用math+math>>1,符合条件的情况下等同于1.5*math,但是速度要块很多。

  11. 无锁数据结构的基本操作CAS,将一个变量的值与A值比较,如果相等,那么将变量的值变为B值。没有加锁和解锁过程,性能影响较小,避免死锁和活锁的情况。但是可能会产生ABA问题。

  12. C语言接口。一组回调函数(函数指针)+函数上下文(指向一个或一组数据)。根据自己的需要让接口内的函数指针指向不同的函数,而调用是统一调用接口的。

  13. C语言容器。其实也是一个接口,也就是说也有一组回调函数和函数上下文。先实现容器接口,然后再用实现了的容器实现需要的结构。原来是用双向链表和动态数组分别实现队列的接口,那么抽象出容器后,我们先用双线链表和动态数组实现容器,然后再用容器实现队列。虽然中间多了一步,但是下次要实现栈的是时候,就可以直接使用容器直接来实现了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容