• C:入门级积累(5)


    断言断言为我们提供了一种静态或动态地检查程序在目标平台上整体状态的能力,与它相关的接口由头文件assert.h提供
    错误处理错误处理则涉及C程序如何通过特定方式,判断其运行是否发生错误,以及错误的具体类型,头文件error.h中则定义了与此相关的宏
    对齐C语言还具有自定义数据对齐的能力,默认情况下,编译器会采用数据自然对齐,来约束数据在内存中的起始位置。但实际上,我们也可以使用C11提供的关键字_Alignas 来根据自身需求为数据指定特殊的对齐要求。并且,头文件stdalign.h还为我们提供了与其对应的宏alignas
    ANSI美国国家标准协会(ANSI)
    编译complie使用c,c++编写可执行文件,首先要把源文件编译成中间代码文件,linux下是.o文件,即object File 这个动作叫做编译
    参考:https://blog.csdn.net/qq_51604330/article/details/125056309
    链接link把大量的object File合成一个执行文件,这个动作叫做链接(link)
    参考:https://blog.csdn.net/qq_51604330/article/details/125056309
    Make工作原理如果这个工程没有被编译过,那么我们的所有C文件都要编译并被链接。如果这个工程的某几个C文件被修改过,那么我们只需要编译被修改过的那几个C文件,并链接生成可执行文件(链接目标程序)。如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接生成可执行文件(链接目标程序)
    参考:https://blog.csdn.net/qq_51604330/article/details/125056309
    Makefile规则target: 是一个目标文件,可以是object file 也可以是可执行文件,还可以是个标签
    prerequisite:先决条件,就是要生成那个target所需要的文件或是目标
    commend:就是make需要执行的命令(任意的shell命令)
    核心规则:这是一个文件依赖关系,也就是说,target这一个或者多个目标文件依赖于prerequisite中如果有一个以上的文件比target要新的话,commend所定义的命令就会被执行。
    参考:https://blog.csdn.net/qq_51604330/article/details/125056309
    Make工作流程make会在当前目录下找到名字叫做Makefile或者makefile的文件。如果找到,他会找文件中的第一个目标文件(target),如果第一个目标文件不存在,或者依赖文件修改时间比目标文件新,那么,他就会执行后面所定义的命令来重新生成目标文件,如果目标文件所依赖的.o文件也不存在,那么make会在当前文件中找目标为.o的文件的依赖,如果找到则根据那个规则生成.o文件。如果文件依赖都齐全,则会正常执行,先生成.o文件,再链接生成目标文件。
    参考:https://blog.csdn.net/qq_51604330/article/details/125056309
    struct sockaddr_in ad;
    struct hostent *hp;

    memset(&ad, 0, sizeof(ad));
    memset函数时内存赋值函数,用来给某一块内存空间进行赋值
    包含在string.h中,可以用它
    对一片内存空间逐字节进行初始化
    void *memset(void *s, int v, size_t n);

    这里s可以是数组名,也可以是指向某一内在空间的指针;v为要填充的值,n为要填充的字节数
    参考:http://www.codebaoku.com/it-c/it-c-191368.html
    memset是一个初始化函数,作用是将某一块内存中的全部设置为指定的值
    void *memset(void *s, int v, size_t n);
    s指向要填充的内存块,c是要被设置该值的字符数。返回类型是一个指向存储区s的指针
    参考:https://blog.csdn.net/weixin_44162361/article/details/115790452
    需要说明的几个地方:

    不能任意赋值,memset函数是按照字节对内存的进行初始化,所以不能用它将int数组初始化为0和-1之外的其他值(除非该值高字节和低字节相同)
    注意所要赋值的数组的元素类型:
    一:对char 类型的数组a初始化设置元素全为“1”
    正确
    二:对int类型的数组a初始化,设置元素值全为1 错误


     
    __attribute__ 机制
    先记着后续再深入研究
    #  define __THROW __attribute__ ((__nothrow__ __LEAF))
    -GNU C的一大特色就是__attribute__机制,attribute可以设置函数属性(Function attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)
    -attrbute书写特性是:attribute前后都有两个下划线,并且后面会紧跟一对圆括弧,括弧里面是相应的__attribute__参数:__attribute__((attribute-list))
    -关键字__attribute__也可以对结构体struct和共用体union进行属性设置。大致有6个参数可以被设定,即:aligned(对齐),packed(拥挤的),transparent_union(透明的父级联合体),unused(未使用的),deprecated(不赞成的)和may_alias(???)。
    -在使用__attribute__参数时,你也可以在参数的前后都加上“__”(两个下划线),例如使用__aligned__,而不是aligned,这样,你就可以在相应的头文件里面使用它而不用关心头文件里面是否有重命名的宏定义。
    参考:https://blog.csdn.net/weixin_37921201/article/details/119429391
    struct 结构体结构体是由一组数据组合而成的结构型数据组,成结构型数据的每个数据称之为结构数据的成员:
    结构体关键字:struct
    结构体标签:代表本次数据结构体的具体代号字符串
    成员变量:结构体的各组成部分
    结构体变量:如果说结构体就是一个数据结构的模板,那么结构体变量就是模板的实例
    memcpy(void *restrict dest, const void *restrict src, size_t n)memcpy():用于复制内存块,Copy N bytes of SRC to DEST.
    函数声明:void * memcpy(void * destnation,const void * source, sezi_t num)
    void * destnation:目的地,指向要在其中复制内容的目标数组的指针,类型转换为void*类型的指针。
    const void * source:源,指向要复制的数据源的指针,类型转换为const coid *类型的指针
    size_t num:数字,要复制的字节数。size_t是无符号的整数类型
    头文件:#include
    返回值:返回目的地
    参考:https://blog.csdn.net/m0_65601072/article/details/125904069

    memcpy():函数声明:void* memcpy(void* str1,const void* str2, size_t n)
    str2所指向的内容的n个字节复制到str1所指向的内容中,注意这里是n个字节,size_t是无符号整型
    int main(int argc,char* argv[])argc:参数个数,c就是count
    argv:参数值,v就是value
    int atoi (const char * str)
    extern void exit (int __status)
    extern int getopt_long (int ___argc, char *__getopt_argv_const *___argv,
       const char *__shortopts,
              const struct option *__longopts, int *__longind)
    长命令解析
    char是一个整数类型,一个字节(8)位
    int是一个整型,4个字节
    floatsingle precision(精度) floating-point value.Single precision is in the format of 1 sign, 8 exponent,and 23 dicimal places.
    变量变量其实只不过是程序可操作的存储区的名称,C中的每个变量都有特定的类型,类型决,定了变量存储的大小和布局,该范围内的值都可以存储在内存中,运算符可应用于变量上,C语言也允许定义各种其他类型的变量,比如枚举,指针,数组,结构,共用体等等。
    参考:https://www.runoob.com/cprogramming/c-variables.html
    变量声明声明一个变量(函数)只是表明这个变量(函数)存在于程序的某个地方,并没有为他们分配内存,但是声明变量和内存具有重要作用,那就是说明变量(函数)的类型,因此当一个变量声明,程序知道变量的类型,在函数声明的情况下,程序知道函数的参数和返回类型,这就是所谓的声明。
    参考:https://blog.csdn.net/xv1356027897/article/details/79594853
    变量定义变量定义就是告诉编译器在何处创建变量的存储,以及如何创建变量存储
    当我们定义一个变量(函数)除了声明的作用,他也为该变量分配内存,因此,我们也可以认为声明是定义的子集。
    声明可以多次重复,定义只能完成一次
    定义一个变量就包含了声明
    变量总结1.声明可以多次,定义只能一次
    2.关键字extern用于扩展变量和函数的可见性
    3.由于函数默认存在extern,不需要再定义和声明的时候使用extern
    4.当变量使用extern,它只是声明没有定义。
    5.当变量用extern声明并有初始化时,和变量的定义一样
    参考:https://blog.csdn.net/xv1356027897/article/details/79594853
    存储区c存储区主要分为栈,堆,静态存储区
    存储区-栈栈在程序中用于维护函数的调用上下文,且函数的参数和局部变量存储在栈上
    edp:当前函数的存取指针,即存储或读取数时的指针基地址
    esp:当前函数的栈顶指针

    每一次发生函数的调用(主函数调用子函数)时。在被调用函数初始化时,都会把当前函数(主函数(main))的ebp压栈,以便从子函数返回主函数时能够获取ebp.
    esp就是一直指向栈顶的指针,而ebp仅仅是存取某时某刻的栈顶指针,以方便对栈的操作,如获取函数参数,局部变量等。
  • 相关阅读:
    Nginx HTTP框架综述
    25. Python 字符串的切片方法
    SwiftUI Swift 5.7 新功能大全,告诉什么时候Swift直接调用C++
    智慧园区的首选:山海鲸可视化解决方案
    第六章 内存管理之实战案例分析
    我对需求分析的理解
    Qiankun框架对于微前端的解耦和沙盒与实战探索心得
    Java8 新特性之Stream(三)-- Stream的终结操作
    【JavaScript】LeetCode 383. 赎金信
    Task05|joyfulpandas|变形
  • 原文地址:https://blog.csdn.net/shunzi2016/article/details/130904479