Head first C
cppcourse c part K&R C Bible##Head first C P6:如果想检查program的exit status, windows使用echo %ErrorLevel%, Linux使用echo $? (钱的问题) P9:顺序执行两条命令 gcc zork.c -o zork && ./zork --Linux gcc zork.c -o zork && zork --WindowsP32: 给gcc加上-std=99以支持C99标准.
续1:
P56: sizeof是一个操作符而不是函数,sizeof在编译时就已经完成计算 P59: char s[] = "How big is it?" 对s取地址就是s自身 --> &s == s sizeof(s) is 15 什么是Pointer decay 当你把array赋值给pointer的时候,pointer仅包含了array的地址信息! pointer并不知道array的大小, 信息在传递/赋值过程中丢失了,这种现象叫做pointer decay, 当你把array传递给function的时候,array自动转成pointer(也就是function中的形参array实质上变成了pointer),产生了一次pointer decay. sizeof(array)是数组实际占用空间的大小, sizeof(pointer)总是4或8 续2: P61: An array variable can be used as a pointer to the first element in an array. array变更名可以看作是指向数组中第一个元素的指针, 因此s[0]和*s是等价的P65:
scanf char name[40]; int age; scanf("%39s %i",name, &age)如果不加39,则可能导致buffer overflow,同时可输入两个变量的值,以space分隔.fgets -> 更安全的scanf char food[5]; fgets(food,sizeof(food),stdin): 参数1:指向buffer的pointer, 参数2:buffer的大小(和scanf不一样,它是算上\0的总大小,无需减1), 参数3:数据从哪儿来 区别: scanf可以一次输入多组数据,fgets不行,scanf胜出 scanf %s不接受空格所以不能一下输入多个单词,fgets胜出 fgets强制你必须指定大小,scanf大小是可选的, fgets胜出 P72,73. char[] cards= "JQK" 与char* cards= "JQK"的区别 1)做为形参,它们没区别 2)如果是在函数内部 char* cards在栈区保存了常量区"JQK"的地址, char[]在栈区新拷贝了一份常量区"JQK"的内容Geek怎么做? 不要让char*指向字符串常量或者总是加上const关键字const char *s = "some string",这样编译时就可以发现错误. P111重定向input ./geo2json < gpsdata.csv 重定向input & output ./geo2json < gpsdata.csv > output.json P122fscanf(stdin, "%s", s) == scanf("%s",s)fprintf(stdout, s) == printf(s)重定向input & stdout & stderr
./geo2json < gpsdata.csv > output.json 2> errors.txt P135 可以把使用|(管道)连接的两个程序看成一个整体,和先前一样使用输入和输出重定向 (./bermuda | ./geo2json) < spooky.csv > output.json 使用|连接的程序是同时执行的,第2个进程并不一定要等到第1个执行完再开始, 一连串用pipe连接的进程叫pipeline <仅作为第1个进程的标准输入, >仅作为最后一个进程的标准输出,()是必须的. P138文件流 每个data stream用指向文件的指针表示: r,w,a分别表示read,write, append FILE *in_file = fopen("input.txt","r"); FILE *out_file = fopen("input.txt","w"); FILE *out_file = fopen("input.txt","a"); P149 getopt用法,见我的另一篇博客 P191gcc -c *.c //create object code for every filegcc *.o -o launch //link everything together
生成 .o文件以节省下次的编译时间
每种rule包含一行dependencies(冒号前的部分叫做target) 和 一行以tab开头的recipe,(to be continued)
##cppcourse c part
Episode 24: 以下演示了指针只不过是地址(将结构体拷贝到字符数组中,然后将数组名强制转换成结构体指针)#include#include #include typedef struct student{ char sno[5]; char sname[32]; int sage;} student_t;int main(void){ student_t stu; strcpy(stu.sno, "1001"); strcpy(stu.sname,"cyper"); stu.sage = 20; char str[sizeof(stu)]; memcpy(str,&stu,sizeof(stu)); student_t* p = (student_t*)str; printf("%s %s %d\n",p->sno,p->sname,p->sage); return 0;}
不能像这样给sno赋值,
stu.sno="1001" 报错: 24_1.c:13:13: error: incompatible types when assigning to type ‘char[5]’ from type ‘char *’ 原因:在定义申明完数组后数组名具有常量特性,表示数组存储空间的开始地址,而C语言中不能对常量赋值。 结构体定义时不能定义自身结构体变量,但可以定义自身的指针.Episode25:
void (*f)(int) 函数指针, void* f(int)函数f返回值为指针 等价关系 -> &f == f,类似于数组首地址, 调用时(*f)(100) == f(100)