C语言基础知识总结

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.++和--

自增运算符和自减运算符:前缀和后缀两种情况

1)表达式++n先将n的值递增1,然后再使用变量n的值:如果n的值为5,x = n++; 执行后的结果,x的值置为5, n=6

2)表达式n++先使用变量n的值,然后再将n的值递增1:如果n的值为5,x = ++n; 执行后的结果,x的值置为6, n=6

在不需要使用任何具体值且仅需要递增变量的情况下,前缀方式和后缀方式效果相同。

2.return、exit区别

调用一个函数,此函数的入口地址会被保存起来,放在某个确定的寄存器中,函数结束前的return语句会找到函数地址,

然后在被调用函数结束后,执行其下一条语句。

exit使进程直接终止

3.结构体相关知识点(重点)

1)聚合数据类型:能够同时存储超过一个的单独数据。C语言提供两种类型的聚合数据类型,数组和结构体。

结构体也是一些值的集合,这些值称为它的成员,一个结构体的各个成员可以有不同的类型。每个结构体有

自己的名字,它们通过名字访问结构体成员。

2)结构体声明与定义:

声明的一般形式:

a.struct student{int num;char sex[5];char addr[10];}; struct student s1,s2;

b.在声明类型的同时定义变量struct 结构体名{ 成员列表}变量名表列;

c.直接定义结构体类型变量:struct {成员表列}变量名表列;(即不出现结构体名)

注意:声明结构时,可以使用另一种良好的技巧,即用typedef 创建一种新的数据类型,如: typedef struct{int num;char name[10];char sex;}Person;

此时Person是个类型名而不是一个结构标签,所以后续的声明可以是:Person x; Person y[20],*z;

3)结构体成员的访问

struct COMPLEX{ float f;int a[20];long *lp;struct SIMPLE s;

struct SIMPLE sa[10];struct SIMPLE *sp; };

a)结构成员的直接访问:通过点操作符(.),例如:struct COMPLEX comp;我们要访问comp这个结构体变量

中int a[20]这个成员,可以用:comp.a; 点操作符的结合性是自左向右,如((comp.sa)[4]).f,可以直接comp.sa[4].f;

b)结构体成员的间接访问:如果我们拥有一个指向结构体的指针,如void func(struct COMPLEX *cp); 我们要访问这个

结构体的成员f,那么(*cp).f;=====>>.操作符的优先级高于*,所以我们必须要加(),这个

操作有点麻烦,所以C语言定义了一个

更为方便的操作符:->(箭头操作符),cp->f就可以达到同样效果。

注意:->的左操作数必须是一个指向结构体的指针。

c)结构体的自引用

例1:struct SELF1{ 这个结构体的自引用是非法的,因为成员b是另一个

int a; 完整的结构,其内部还包含它自己的成员b,然后它的第二

struct SELF1 b; 个成员又是一个完整的结构b,这样一直重复下去。

};

例2:struct SELF1{ 这个是合法的,区别在于:b现在是一个指针而不是int a; 结构。编译器在结构长度确定之前就已经知道了指针的长

struct SELF1 *b; 度,所以这种类型的自引用是合法的。

};

例3:typedef struct{ typedef struct SELF_REF1{

int a; int a;

SELF1 *b;(此处SELF1尚未定义)struct SELF_REF1 *b;//解决方案:定义一个结构标签来声明b

}SELF1; }SELF1;

这个是错误的。这个是正确的。

4)结构体的初始化

结构体初始化和数组初始化很相似。一个位于一对{}花括号内部、由逗号(,)分割的初始值列表可用于结构体各个成员的初始化.

如果初始列表的值不够,剩余的结构成员将使用缺醒值进行初始化。

例如:struct INIT_EX{

int a;

short b[10];

Simple c;

}x = {10,{1,2,3,4,5},{25,'x',1.9}};

也可以使用一条简单的赋值语句将一个结构体变量的值赋给另一个相同类型的结构体变量。例如:如果book1和book2是同一类型结构体变量,

则book2 = book1;此语句有效。

5)结构体的内存分配

struct ALIGN{ struct ALIGN2{

char a; 1个字节int b; 4个字节

int b; 4个字节char a; 1个字节

char c; 1个字节一共用去12个字节char c; 1个字节一共用去8个字节。

}; };

注意:我们在声明中对结构体列表重新排列,让那些边界要求最为严格的成员首先出现,对边界要求最弱的成员最后出现。

sizeof操作符能够得出一个结构体的整体长度,包括因边界对齐而跳过的那些字节。如果你必须确定结构某个成员的实际

位置,应该考虑边界对齐的因素,可以使用offsetof宏(stddef.h):

一般格式:offsetof(type,member) type 是结构的类型;member 是你需要的那个成员名;表达式的结果

是一个size_t 值,表示这个指定成员开始存储的位置距离结构开始存储的位置偏移几个字节。

offserof(struct ALIGN,b) 返回值为4.

6)结构体作为函数参数的结构

4.realloc() calloc() malloc() memset()

动态内存分配:为什么使用动态内存分配?

当我们声明数组时,我们必须指定数组的下标,即数组的长度。但是有些时候我们无法提前知道数组的长度,它所需

要的内存空间取决于输入数据,所以此时,我们就可以使用动态内存分配来解决这个问题!

1)void realloc(void *ptr,size_t new_size);

realloc函数用于修改一个原先已经分配的内存块的大小。使用这个函数,可以使一个内存扩大或缩小。如果它用于扩大一个

内存块,那么这块内存原先的内容依然保留,新增加的内存添加到原先内存的后面,新内存并未以任何方法进行初始化。如果缩小,

该内存尾部内存被拿掉,剩余部分内存是原先内容依然保留。

如果原先内存块无法改变大小,realloc将分配另一块正确大小的内存,并把原先那块内存的内容复制到新的块上。

如果realloc函数的第一个参数为NULL,那么它的行为就和malloc一模一样。

2)malloc 和free (都在头文件stdlib.h中声明)

void *malloc(size_t size);

size 为所需要的内存字节数,成功的话malloc 返回一个指向被分配的内存块起始位置的指针。否则,返回一个NULL指针。

另外,malloc分配一块连续的内存,且实际分配的可能会比请求的多点,但不确定。

void free(void *pointer);

free参数要么是NULL,要么是malloc,calloc,realloc返回的值,为NULL时,不产生任何效果。

3)calloc

void *calloc(size_t nelem,size_t el_size);

calloc也用于分配内存,它与malloc的区别在于它在返回指向被分配内存的指针之前,先把这块内存初始化为0.

nelem表示所需元素的数量,el_size表示每个元素的字节数。

5.字符串相关操作

相关文档
最新文档