C语言随集

1、FILE 像Int一样是一个类型名,而不是结构标记,是通过typeof定义的。在读写一个文件前,必须通过库函数fopen打开该文件。

FILE *fp;//指向结构FILE的指针。
FILE *fopen(char *name, char *mode);//文件指针是指向一个包含文件信息的结构。
//文件信息:包含缓冲区位置、缓冲区当前字符位置、文件的读或写状态,是否出错或是否已经到达文件结尾等

2、cat可用来在屏幕上打印文件。

cat x.c y.c //将在标准输出上打印文件x.c和y.c的内容。

3、typedef 类似于#define语句,但于typedef是由编译器解释的,因此它的文件替换功能要超过预处理的能力。
union联合:不同时刻保存不同类型和长度的对象的变量。编译器负责跟踪对象的长度和对齐要求。以在单块存储区中管理不同类型的数据。类似Pascal语言中变体记录。
union的访问语法:(1)、联合名.成员;(2)、联合成员->成员。
4、位字段:字段不是数组,并且没有地址,因此对他们不能使用&运算符。
5、结构数组:C语言提供了一个编译时一元运算符sizeof。它可用于计算任一对象的长度表达式:sizeof(类型名)或 sizeof 对象
它等价于指定对象或类型占用的字节的存储空间。
size_t是一个无符号整型值。
6、对字符串的书写方式比较:

char amessage[] = "now is the time";
char *pmessage = "now is the time";

amessage仅仅是一个以存放初始化字符串以及空字符串'\0'的一维数组。数组中单个字符可以进行修改,但是amessage始终指向同一个存储位置。
pmessage是一个指针,其初始值指向一个字符串常量,之后可以被修改指向其他地址。
7、

int (*cmp)(void*, void*) ;//指向函数的指针
int *cmp (void*, void*); 返回整型指针的函数
struct {
  int len;
char str;
} *p;

p->str读取的是指针str所指向的对象的值;
p->str++先读取指针str指向的对象值,然后再将str加 1(与s++相同);
p->str)++将指针str指向的对象的值加1;
*p++->str先读取指针str指向的对象的值,然后再将p加1。
++p->len将增加len的值;
(++p)->len将先执行p的加1操作,再对len执行操作。
(p++)->len则先对len执行操作,然后再对p加1。
8、alloc(n)返回一个指向n个连续字符串存储单元的指针;free(x)释放已分配的存储空间。这两个函数处理的都是指针而不是数目下标。以栈方式进行存储空间管理。
9、程序员经常用符号常量NULL代表常量0。C语言保证,0永远不是一个有效的数据地址。因此返回值为0,表示发生了异常事件。指针和整数之间不能相互转换。0是唯一的例外。常量0可以赋值给指针。指针也可以和常量0进行比较。
10、当把数组名传递给一个函数,实际上传递的是一个数组第一个元素的地址,在被调用函数中,该参数是一个局部变量。数组各参数必须是一个指针,也就是一个存储地址值的变量。C语言是以传值的方式将参数值传递给被调用函数。
11、如果a是数组,那么f(&a[i])<=>f(a+z)都将把起始于a[z]的函数组的地址传递给函数f。
12、#undef表示取消#define的宏定义。预处理器运算符 ##宏提供了一种连接实际参数的手段,如果替换文件中的参数与##相邻,则该参数将被实际参数替换。##与前后的空格都被删除。并对替换后的结果重新扫描。

#define paste(front, back) front ## back
//宏调用paste(name, 1)即是name1;

13、C语言专门定义了两个预处理语句,#ifdef与#ifndef,他们用来测试某个名字是否已经定义。地址运算符&只能运用于内存对象,即变量与数组元素。它不能用作表达式、常量、或register类型变量。
14、x = p; 若pa指向a[0],那么(pa+1)引用的是数组元素a[1]的内容。pa+i是数组元素a[i]的地址, *(pa+i)引用的事数组元素a[i]的内容。
a[i] <=> *(a+i);

15、register声明只适用于自动变量以及函数的形式参数与。register声明告诉编译器,它所声明的变量在程序中,使用率较高,其思想是将register变量放在机器的寄存器中,使程序更小,执行速度更快,但编译器可以忽略此选项。
16、'\0'表示值为0的字符,也就是空字符null。strlen(s)可以返回字符串参数s的长度,但长度不包括末尾的'\0';
存储字符串的物理存储单元数比括在双引号中的字符串多1个。这说明c语言对字符串的长度没有限制,但必须程序扫描整个字符串,才能确定字符串长度。
17、对数组而言,const限定符指定数组所有元素的值都不能被修改。

const char msg[] = "xxxxxx"; 
//const限定符也可配合数组参数使用,它表明函数不能修改数组元素的值,如果试图修改const限定符限定值,其结果取决于具体实现。

18、函数在使用外部变量之前,必须要知道外部变量的名字,实现该目的的做法,一种方式是在extern类型的声明。
习惯性把变量和函数的extern声明放在一个单独的文件中,并在每一个原文件中的开头使用#include语句放在一个单独的文件中。
19、define定义表示创建变量或分配存储单元。decalaration声明指的是说明变量的性质但并不分配存储单元。
20、int通常表示特定机器中整数的自然长度。
u代表unsigned,其类型的变量值总是正值或0.
21、预处理指令有预处理器解释的,预处理读入源代码,根据预处理指令对进行修改,然后把修改过的源代码递交给编译器。

int ch;//未初始化的变量,其初始化值将是一个不可预料的值,也就是垃圾。

22、ANSIC的两种不同环境:
(1)翻译环境->源代码翻译成可执行的机器指令;
(2)执行环境。
翻译是预处理器处理,用实际值代替由#define指令定义的符号以及读入由#include指令包含的文件的内容。
源代码解析(产生绝大多数错误和警告信息的地方)->产生目标代码->机器代码的初步形式。
23、当编译并连接多个C源文件时,目标文件不会被删除。

xxx.c->program.o目标文件(但在链接过程完成后,可能被删除)->a.out可执行文件
//终端输入
cc -c program.c //编译单个c源文件,并生成一个目标文件

cc -c main.c hello.c world.c -o name
//-c表示生成中间文件, main.o hello.o world.o

cc -c main.o hello.o world.c 

24、静态变量只是在程序开始执行前初始化一次。对自动变量除非进行显式初始化,否则当自动变量创建时,他们的值总是垃圾。
25、右移位操作对象必须是整数,从左边移入新位时,有两种移位操作,逻辑移位(左边填补0)和算术移位(左边移入的位由原先该值的符号位决定符号位为1,则移入的位均为1否则为0)。
26、

char ch = 'a';
char *cp = &ch;
当表达式&ch进行求值时,它的结果肯定会存储于计算机的什么地方,但你无法知道它位于何处。这个表达式并未标识任何机器内存的特定位置,所以不是一个合法的左值。

27、后缀++操作符:
(1)++操作符产生cp的一份拷贝;(2)然后++操作符增加cp的值;(3)最后在cp的拷贝上,执行间接访问操作。

28、static可以限制对那些非接口的函数和数据的访问。声明为寄存器变量的指针比位于静态内存和堆栈中的指针效率高。
29、->的优先级高于&的优先级。
30、sizeof操作符能够得出一个结构的整体变量,包括因边界对齐而跳过的那些字节。offset of(type, member)确定结构某个成员的实际位置。

31、当一个结构特别小(长度和指针相同或更小)时,结构传递方案才不会输给指针传递方案。对于绝大多数结构,传递指针显然效率更高。如果希望函数修改结构任何成员,也应该使用指针传递方案。

32、位段的声明必须是int、signed int或unsigned int类型,在成员名的后面是一个冒号和一个整数,指定该位段所占用的位的数目。用signed或unsigned整数显示声明位段是一个好主意。如果把位段声明为int类型,它究竟被解释为有符号数,还是无符号数是由编译器决定的。使用位段只是基于方便的目的,任何可以用位段实现的任务都可以使用移位和屏蔽来使用。
33、union联合的所有成员引用的是内存的相同位置。
34、malloc函数向操作系统请求内存时,如果系统无法向malloc提供更多的内存,malloc将返回一个NULL指针。
calloc也用于分配内存。malloc和calloc之间的区别是后者在返回内存的指针之前把它初始化为0;还有一点区别是他们请求内存的方式不同。

void *calloc(size_t num_elements, size_t element_size);
void realloc (void *ptr, size_t new_size);

realloc用于修改原先已经分配的内存块的大小。分以下一种情况:
(1)扩大内存时——>新增加内存添加到原先内存块的后面;
(2)缩小内存时——>该内存尾部部分内存被拿掉,剩余部分内存的原先内容依然保留;
(3)若原先内存块无法改变大小,realloc将分配一块正确大小的内存,并把原先那块内存的内容复制到新的块上,因此在使用realloc之后,不能再使用旧的内存指针,而是应该改用realloc所返回的新指针。
35、转换表就是一个函数指针数组,把数据写入文件效率最高的方法是用二进制形式写入,因为二进制避免了在数值转换为字符串过程中所涉及的开销和精神损失。

int (*f[])(); //首先求值,f是一个元素为某种类型的指针的数组

36、volatie关键字告诉编译器,信号可能发生在任何时候,所以由信号处理函数修改的变量的值可能会在任何时候发生改变。因此你不能指望这些变量在两条相邻的程序语句中肯定具有相同的值。

37、因为!=运算符的优先级高于&运算符,所以if(flag&FLAG != 0)等价于if(flag & (FLAG != 0))。
'+'运算符的优先级要比移位运算符的优先级高,因此
r = hi<<4 + low 等价于 r = hi<<(4+low)

38、BSS(Block Started Symbol)段由符号开始的块只保存没有值的变量。C语言把数组下标改写成指标偏移量的根本原因是指针和偏移量是底层硬件所使用的基本模型。

39、else会产生悬挂。

int *a[9];
//实际上,由a+i和i+a的含义是一样的,因此a[i]与i[a]具有同样的含义。

40、

当声明一个不想被修改的常量时,应当在声明中使用const关键字
int const *pci; //一个指向整型常量的指针。可以修改指针的值,但你不能修改它z所指向的值。
int *const cpi;//pci为一个指向整型的常量指针。此时指针是常量,它的值无法修改,但你可以修改它所指向的整型的值。
int const *const cpci; //无论是指针本身还是它所指向的值都是常量,不顺序修改。

#define MAX_ELEMENTS 50
int const max_elements = 50
//这两种情况,使用#define比使用const变量更好。因为只要允许使用字面值常量的地方都可以使用前者,比如声明数组的长度。 const变量只能用于允许使用变量的地方。

41、链接属性一共有三种:
external(外部),internal(内部),none(无)
没有链接属性的标志符(none)总被当做单独的个体,也就是说该标志符的多个声明被当作独立不同的实体。具有external链接属性的实体总是具有静态存储类型

static int  b;//这个变量b将为这个源文件私有。在其他源文件中,如果也能链接到一个叫做b的变量吗,那么它所引用的是另一个不同的变量。类似的函数也可以声明为static
static int c(int d); //可以防止它被其他源文件调用。
static 只对缺省链接属性为external的声明才有改变链接属性的效果。
当static用于代码块内部的变量声明时,static关键字用于修改变量的存储类型,从自动变量修改为静态变量,但变量的链接属性和作用域不受影响。用这种方式声明的变量在程序执行之前创建,在代码块执行完毕后销毁。
external关键字的规则比较复杂。一般而言,它为一个标志符指定external链接属性,这样就可以访问其他任何位置定义的这个实体。
对于在代码块内部声明的变量没如果给它加上关键字static,可以使它的存储类型从自动变为静态。具有静态存储类型的变量在整个程序执行过程中一直存在,而不是仅仅在声明它的代码块的执行时存在。
函树的形式参数并不能声明为静态,因为实参总是在堆栈中传递函数,用于支持递归。

42、register
用于自动变量的声明,提示他们应该存储在机器的硬件寄存器b而不是内存中,这类变量称为y寄存器变量。 通常寄存器变量比存储在内存的变量访问起来效率更高。
当有太多的变量被声明为register时,它只选取前几个实际存在寄存器中,其余的就按普通自动变量处理。

如果一个编译器具有一套寄存器优化方案,他也可能忽略register关键字,其依据是有编译器决定哪些变量存储于寄存器中比人脑的决定更为合理一些。

寄存器变量的创建和销毁时间和自动变量相同,但它需要一些额外的工作。

43、

int *b;//    声明一个指针变量时,编译器只为指针本身保留内存空间。并不会为所指向的整型值内容分配内存空间,而且指针变量并未被初始化为指向任何现有的内存空间

int matrix[2][10], *mp = matrix;//mp的初始化是不正确的,因为mattrix并不是一个指向整型的指针,而是一个指向整形数组的指针,如果想声明一个指向整形数组的指针的话,需要进行以下声明:
    
int [*p][10]; //下标引用的优先级高于间接访问,但由于括号的存在,首先执行的还是间接访问
    
int (*p)[10] = matrix; //p指向maxtrix的第一行

44、

任何类型的指针都可以转换为(void *)型指针。

45、

int fclose(FILE *p); //释放指针,断开由fopen函数建立的文件指针和外部名之间的连接,并释放文件指针以供其他文件使用。因为大多数操作系统都限制了一个程序员可以同时打开的文件数,所以文件指针不再需要时就应该释放,这是一个好的编程习惯。对输出文件执行fclose还有一个原因:它将把缓冲区中由putc函数正在收集的输出写到文件中。当程序正常终止时,程序会自动为每一个打开的文件调用fclose函数。

free(p)
//函数释放p指向的存储空间,其中,p是此前通过调用malloc或calloc函数得到的指针。存储空间的释放顺序没有什么限制,但是如果释放一个不是通过调用malloc或者calloc函数得到的指针的所指向的存储空间,将是一个很严重的错误。
system(char *s);
//命令执行函数执行包含在字符串s中的命令,然后继续执行当前程序。 s的内容在很大程度上与所有的操作系统有关。
system("date"); //它在标准输出上打印当天的日期和时间。system函数返回一个整型的状态值,其值来自于执行的命令,并同具体系统有关。

//随机访问--lseek
lseek系统调用返回一个long类型的值,此值表示文件的新位置,若发生错误,则返回-1.
系统调用lseek可以在文件中任何移动位置而不实际读写任何数据:
long lseek(int fd, long offset, int origin);

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

推荐阅读更多精彩内容

  • 指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构; ...
    朱森阅读 3,387评论 3 44
  • 版权声明:本文为 gfson 原创文章,转载请注明出处。注:作者水平有限,文中如有不恰当之处,请予以指正,万分感谢...
    gfson阅读 2,674评论 0 6
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy阅读 9,446评论 1 51
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,036评论 1 32
  • 1. 变量 不同类型的变量在内存中占据不同的字节空间。 内存中存储数据的最小基本单位是字节,每一个字节都有一个内存...
    C语言学习阅读 1,264评论 0 4