您的位置:首页 > 编程语言 > C语言/C++

C语言笔记

2016-01-27 12:35 323 查看
1、C语言关键字 32个

auto               局部变量(自动储存)
register           CPU内部寄存的变量
extern             在其它程序模块中说明了全局变量
static             定义静态变量
const              定义不可更改的常量值
volatile           该变量在程序中执行中可被隐含地改变
void               定义无类型数据
unsigned           定义无符号数据
signed             有符号数
char               单字节整型数据
short              短整型数据
int                基本整型数据
long               长整型数据
float              定义单精度浮点型数据
double             定义双精度浮点型数据
enum               枚举
union              联合类型数据
struct             定义结构类型数据
sizoef             计算表达式或数据类型的占用字节数
typedef            重新定义数据类型
switch             构成switch选择结构
case               switch语句中选择项
break              无条件退出程序最内层循环
default            switch语句中的默认选择项

if                 构成if....else选择结构
else               构成if.....else选择程序结构
for                构成for循环语句
continue           中断本次循环,并转向下一次循环
goto               构成goto转移结构
return             用于返回函数的返回值
do                 用于构成do.....while循环语句
while              用于构成do...while或while循环结构


关于声明定义的区别:定义会分配内存空间,声明表示别的地方已经定义,可以拿来用,不分配空间。

注:

<1>类型不统一,要特别注意可能会发生 -1 > 1 的情况;

unsigned i = 1;

singed j = -1;

j > i 为真,因为程序类型自动转换为unsigned类型。

<2> 对于float 或者double 型的变量,一般不要于0作比较,要与一个很小的精度作比较。

<3>
if .. else 中的else 就近匹配。在进行判断时,把可能运行情况概率大的放在前面,即满足可读性也满足程序执行效率的要求。

<4>在多重循环中,尽可能的把长的循环放在内循环中,减少内外循环跨越的次数。

<5>空结构体的大小为1

2、C语言动态内存

char *pStr = (char*)malloc(sizeof(char)*10);
memset(pStr, 0, 10*sizeof(char));


malloc和memset一般是一起使用的,malloc分配的内存是不进行初始化的,如果不用memset初始化在进行右值操作时很有可能出现错误。若申请了两段内存空间pStr1和pStr2,当pStr
= pStr2进行指针赋值操作时,pStr2所指向的内存空间就永远不能被访问到,就发生了内存泄露。用calloc分配的内存就会进行初始化。必须要注意的是分配空间不成功的情况,要加上对返回值为NULL的判断。每一个malloc都要对应一个free,切记。

realloc(void *__ptr, size_t __size):更改已经配置的内存空间,即更改由malloc()函数分配的内存空间的大小。

如果将分配的内存减少,realloc仅仅是改变索引的信息。

如果是将分配的内存扩大,则有以下情况:

1)如果当前内存段后面有需要的内存空间,则直接扩展这段内存空间,realloc()将返回原指针。

2)如果当前内存段后面的空闲字节不够,那么就使用堆中的第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据块释放掉,返回新的内存块位置。

3)如果申请失败,将返回NULL,此时,原来的指针仍然有效。

注意:如果调用成功,不管当前内存段后面的空闲空间是否满足要求,都会释放掉原来的指针,重新返回一个指针,虽然返回的指针有可能和原来的指针一样,即不能再次释放掉原来的指针。

3、指针和引用

(1)指针:指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。如:

int a=1;int *p=&a;

int a=1;int &b=a;

上面定义了一个整形变量和一个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址。

而下面2句定义了一个整形变量a和这个整形a的引用b,事实上a和b是同一个东西,在内存占有同一个存储单元。

(2)可以有const指针,但是没有const引用;

(3)指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的)

(4)指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化;

(5)指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变了。

(6)"sizeof引用"得到的是所指向的变量(对象)的大小,而"sizeof指针"得到的是指针本身的大小;

(7)指针和引用的自增(++)运算意义不一样;

4、const char *p、char const *p、char * const p的区别

由于C语言里没有const* 这一类型,const*表示const(type)*,const char *p和char const *p表示一个意思。

char const *p和char * const p主要是看const的位置,const p 表示指针本身为常量,const *p 表示指向的内容为常量。

5、注意区分表达式的值和变量的值

如 k = (a++)*(b++); ==> k = a*b; a++; b++;

a++ 表达式的值为a ,但变量a的值 为a+1。

6、函数参数校验问题

一般来说某个函数被多层调用则需要把参数校验(例如判断参数是否合法)放在外层函数里面。

7、int (* pfn)(); 或者int (*pData)[10]; 当碰到这些类型定义时,可以把他们看做int
(*)()
pfn;pfn为一个函数指针, int (*)[10] pData; pData为保存整数类型的二维数组。这样就好理解多了。

比如 分析

(1) int (*(*fn)[5])(int *p); ===> int (*)(int *p) (*fn)[5]; ====> int
(*)(int *p)
(*)[5] fn一个保存函数指针的二维数组

(2) int (* (*fn)(int *p))[5]; ====>
int (*)[5] (*fn)(int *p) =====> int (*)[5] (*)(int *p) fn
;fn是一个返回值为二维数组的函数指针

(3) 那么 int fn (int *p);中的fn可以理解为保存着整个函数体的变量,则不可以有fn[3]之类的情况,因为函数体大小不定。

8、清空输入缓冲区

while ( (c = getchar()) != '\n' && c != EOF ) ;


9、printf()输出函数。printf("%.2f\n",
a); .2输出精度(在这解释一下,在C语言中用%m.n加数据类型,表示以某种数据类型且宽度为m小数点后保留n位小数输出。)。\n表示光标移到下一列。所以%.2f就表示以实型(也成浮点型)输出且保留两位小数,如果小数点后不够两位用0表示或着随机的数字,如果超过2位,四舍五入
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: