码神营地-C语言深度剖析

C语言中共有32个关键字,具体的就不说了
更多关于C语言学习视频教程请进码神营地官网:www.icodegod.com

声明和定义

  • 声明的含义:
    告诉编译器,该名字已经匹配到一块内存上了,后面代码中用到的变量或对象是在别的地方定义的。
    告诉编译器,这个名字已经被预定了,别的地方不能把它拿来作为变量名或者是对象名(函数的声明)

  • 声明和定义的区别:
    定义创建了对象并为这个对象分配了内存,而声明没有分配内存。
    同一个函数或者变量,声明可以多次,但是定义只有一次。

关键字

  • 最宽宏大量的关键字------》auto
    编译器默认情况下所有变量都是auto的

  • 最快的关键字------》register
    位于CPU和内存之间,起一个传递作用
    他所修饰的变量必须是被CPU接受的类型,这就意味着该register变量必须是单个的值,且长度必须小于整型或者等于整型的长度,register变量可能不放在内存中,所以不能用‘&’来取地址。

  • 最名不副实的关键字------》static
    在局部变量中,static局部变量的值总在内存区,所以局部函数结束,该变量的值仍然在,可以下次继续使用。
    修饰函数不能被其他文件访问。

  • 最冤枉的关键字------》sizeof
    它是一个关键字,不是函数

  • 最易变的关键字------》volatile
    防止编译器对代码的过度优化,从而可以提供对特殊地址的稳定访问。
    Volatile表示“易变的”,即在运行期对象可能在当前程序上下文的控制流以外被修改(例如多线程中被其它线程修改;对象所在的存储器可能被多个硬件设备随机修改等情况):被volatile修饰的对象,编译器不会对这个对象的操作进行优化。
    一个对象可以同时被const和volatile修饰,表明这个对象体现常量语义,但同时可能被当前对象所在程序上下文意外的情况修改。

    注 :被volatile这个关键字修饰的变量在每次访问的时候都要去相应内存地址去找,因为随时可能被修改。被const修饰只能说明这个i不能被程序员修改,但可能被系统所修改

综上

Void fun(const volatile int a)
Void fun(const volatile int *a)
Void fun(volatile int a)
均没有错误
  • 最会戴帽子的关键字------>extern

  • 命名规则中:所有的宏定义,枚举常量,只读变量全用大小写字母命名,用下划线分割单词。

  • 编译器在缺省默认情况下数据类型为unsigned类型的。

  • float变量和零值比较时:
    float ftestValue= 0.0;
    If((ftestValue>=-EPSINON) && (ftestValue<=EPSINON))
    //其中EPSINON为编译器定义好的精度
    也不要在很大的浮点数和很小的浮点数之间进行运算,结果可能很惊奇。
    case关键字后面的值有什么要求:
    switch后面跟的表达式也只能是整型(包括字符型)
    case后面的只能是整型或者字符型的常量或常量表达式(想想字符型数据在内存中怎么存的)。Case 的先后顺序和default的先后顺序没有关系,可以随便排,但一般还是按照顺序把default放在最后面。

  • void的作用:
    对函数返回的限定。
    对函数参数的限定。
    如果函数没有没有返回值应该用void,而不是不写,因为编译器默认的返回值类型是整型。
    如果函数不接受参数,一定要写为void。如果不写,则在C语言中编译可以通过,且可以给它传送任何类型的参数,但是在C++中则编译不通过。
    不能对void的指针进行操作(包括++,–,&操作),GNU除外。
    return语句不可以返回指向“栈内存”中的“指针”,因为函数结束,指针就被销毁了。

  • const在C中的用法和在C++中的用法不太一样
    Const int Max = 100;
    在C语言中,const修饰的只读变量不能用来作为定义数组的维数,
    也不能放在 c as e 关键字后面。
    Int Array[Max];//在C中不可以,在C++中可以
    Case Max: 在C++中是可以的。
    C++中const的变量通常编译器不会为它开辟内存,而是将它存在符号表里。
    const修饰指针时候的用法:

[柔性数组]:结构体中最后一个元素允许是一个未知大小的数组,这就叫做柔性数组,但是在柔性数组成员前面必须有至少一个其他成员。并且sizeof结构体大小时候,不包含柔性数组的大小,包含柔性数组的结构体用malloc开辟内存且开辟的内存大小应该大于结构体大小,以适应柔性数组预期的大小。
不论程序在后面为柔性数组开辟了多大的内存空间,再次计算该结构体大小时,依然不变,柔性数组还是不占结构体的大小,因为它从本质上来说与结构体是两个不相关的东西,跟结构体无关。
大小端模式对union类型数据的影响:
大小端的概念:

  • 用union检验大小端模式。
    枚举和#define的宏区别:

  • 注意 #define a int[10]和typedef int a[10]区别(这里有些没太理解)

符号

  • 注释
    编译器会把注释剔除掉,并不是简单的剔除,而是用空格代替掉,所以注释也不是简单的删除。
    双引号引起来的都是字符串常量,当然双斜杠也不例外。
    段注释的嵌套使用是不合法的,即/* …//…*/是错误的。
    注释的几条规则:
    • 对于全局数据(全局变量,常量定义)必须要加注释
  • .注释必须要用英文。
  • .代码较长时,应该把注释放在程序结束处,便于阅读。
  • .注释代码时应当注重why(为什么)而不是How(怎么做)。
  • .数值的单位,变量的范围,对于函数的入口出口数据都必须给出注释。

逻辑运算符:&&,||
当他们出现在条件语句中时:

           int  i = 0;
           int  j = 0;
           if((++i)||(++j))
            {
                printf(“%d\n%d\n”,i,j);
            }

打印结果是:i= 1,J= 0;因为||,&&运算符都是从左向右判断的,所以当左边第一个成立了,那么后面的将不再进行判断。
位运算符
左移和右移:左移和右移的位数不能超过数据的长度,不能小于0。
逗号表达式中的++.–以最后一个表达式为最终结果。
a++b这中类型的,从左向右依次看最变量大的合法运算符结合,即a++ +b,也就是说一个符号要求包含尽可能多的字符,这就是C语言中的“贪心法”。

预处理

用#define来定义注释符号?
都是不可以的,因为注释先于预处理指令被处理
用#define定义宏表达式时,不要吝啬括号,一定要加上。
Eg:
宏定义中不要加空格,否则意思改变

  • 预编译#pragma
    pragma hdrstop表示预编译头文件到此为止,后面的头文件不进行预编译
    pragma warning
    pragma comment

  • pragma pack 表示内存对齐
    我们可以利用 #pragma pack()来改变编译器的默认对齐方式(当然一般编译器也提供了一些改变对齐方式的选项)

指针和数组

  • 关于NULL的操作

  • 数组
    单纯的数组名代表的是数组这个部分,当数组作为左值时a = 10;这是错误的表达,a[2] = 10;是可以的。
    数组和指针的区别和联系
    定义成数组,声明为指针。
    定义成指针,声明为数组。
    指针数组和数组指针。
    地址的强制转换。
    多维数组和多级指针。
    C语言中,当一位数组作为函数的参数时,编译器总是会把它解析成指向首元素首地址的指针。
    函数本身是没有类型的,只有函数的返回值才有类型。
    二维数组参数和二维指针参数的等效关系

  • 函数指针的应用及好处
    使用函数指针的好处在于,可以将实现同一功能的多个模块统一起来标识,这样一来更
    容易后期的维护,系统结构更加清晰。或者归纳为:便于分层设计、利于系统抽象、降低耦
    合度以及使接口与实现分开。

(*(void(*) ()) 0)()------这是什么?
( * ( c ha r ** ( * ) ( c h ar * * ,c h ar * * ) ) 0 ) ( c h ar * * ,c ha r * *) ;

这又是什么??
函数指针数组 char *(*pf[3])(char *p)
函数指针数组是一个指针数组,它是一个数组中存储了3 个指向函数的指针。
函数指针数组的指针 char * ( *(*pf )[3])( char * p );

内存管理
常见的内存错误及其对策
指针没有指向一块合法的内存
结构体指针成员未初始化
没有为结构体指针分配足够内存
函数的入口校验
为指针分配的内存太小
内存分配成功但是并未初始化
内存越界
内存泄露
用Malloc申请0字节大小的内存
开辟会成功,返回一个正常的地址,但是你无法使用这块内存
如果一个NULL指针被多次free会有什么情况发生??可以编译通过,但是会有警告。

文件结构
注意文件头部的书写规范,包括头文件和源文件的头部书写

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章