C笔记

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 --Windows

P32: 给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

P122
fscanf(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用法,见我的另一篇博客

P191

gcc -c *.c //create object code for every file
gcc *.o -o launch //link everything together

生成 .o文件以节省下次的编译时间

每种rule包含一行dependencies(冒号前的部分叫做target) 和 一行以tab开头的recipe,

(to be continued)

##cppcourse c part
Episode 24:
以下演示了指针只不过是地址(将结构体拷贝到字符数组中,然后将数组名强制转换成结构体指针)

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

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)

转载于:https://my.oschina.net/uniquejava/blog/260687

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值