• c语言的头文件-不是c++类的头文件?


    下面的概述是参考的这篇文章:http://blog.csdn.net/bingxx11/article/details/7771437

    c语言编程中也有,也需要头文件,

    头文件不只是C++的类才需要!

    比如: c中的string.h,  内存操作的头文件 #include <mem.h>

    即是: c语言中, 函数/变量的声明和实现, 也可以像c++一样,

    头文件中, 哪些函数/变量需要使用extern来说明?

      c语言有一个约定: 凡是在对应的.c文件中, 有那个函数的实现的, 就不加extern, 凡是没有对应实现的, 就需要加extern.

    extern的解决,相当于一个口头承诺, 一个口头约定, 口头答应,  在linker连接时, 由连接器(链接器)自动去找.不用我们去管的!!

    ---------------------------------------------

    exten的头文件如何区分"定义声明" - "引用声明"?

    (引用自: http://blog.csdn.net/bingxx11/article/details/7771437)

    两种方式:

      1. 顶层声明中,存在初始化语句是,表示这个声明是定义声明,其他声明是引用声明。C语言的所有文件之中,只能有一个定义声明。按照这个模型,我们可以在first.h中定义如下TPYE G_test=1;那么就确定在first中的是定义声明,在其他的所有声明都是引用声明。

    2、省略存储类型说明
      在这个模型中,所有引用声明要显式的包括存储类extern,而每个外部变量的唯一定义声明中省略存储类说明符。
     
    c语言中 数组并没有和char*  指针完全等同起来:
    int G_glob[100];
     在另一个文件中引用声明如下:
    int * G_glob; // 这个错误!
    在vc中,是可以编译通过的,这种情况大家都比较模糊并且需要注意,数组与指针类似,但并不等于说对数组的声明起变量就是指针。上面所说的的程序在运行时发现了问题,在引用声明的那个文件中,使用这个指针时总是提示内存访问错误,原来我们的连接程序并不把指针与数组等同,连接时,也不把他们当做同一个定义,而是认为是不相关的两个定义,当然会出现错误。正确的使用方法是在引用声明中声明如下:
     int G_glob[100];
     并且最好再加上一个extern,更加明了。
     extern int G_glob[100]; 或者: extern int G_glob[];  引用声明不需要分配内存, 所以不需要指明数组大小.

     

    --------------------------------------------

    C语言程序在内存中的存储区域:

      代码区;

      常量区;

      全局/静态(变量)区;

      堆区/自由存储区: malloc, free | new, delete

      栈区(是一段公共内存区, 公共的: 是指所有的函数运行时,都是使用的这个区域, 这个区域被反复的使用,

          前一个函数使用后, 退出时, "函数内的栈区被释放", 什么叫释放, 并没有内存清零这个动作,只是栈区

          的栈顶指针退回到栈顶,下一次,另外一个函数执行时,仍然使用这个内存区, 而且,局部变量的值可能是上一次

          函数运行时留下的值, 这个值的类型是各种各样的...但是由于字节数的长度不同, 所以组合起来的值,完全

          不可控, 所以是随机的, 需要对其进行初始化)

      关于函数的返回值问题?

        返回值无非有两种: 一是返回地址的, 比如数组地址, 指针, 对象的地址, 也就是, 一般"非内部数据类型"

          的返回值,最好用返回引用的方式;

          另一种是返回拷贝传值类型的, 一般, 返回的是"内部/基本"数据类型的,用这个传值, 不要用传引用.

    那么, 对于传值的函数 的返回值, 函数退出时, 其内存被回收, 也就是,程序无法引用得到, 那么这个值怎么传出来呢?

      网上的说法, 我比较相信的一种是: "函数退出 时,将返回值拷贝到" eax" 这个cpu内的寄存器中, 后面的函数,你要

      这个返回值, 你就去取, 你不要就算了, 但是过后的话,你就取不到,因为这个寄存器随时都可能被覆盖.

    const 修饰函数?

      修饰函数的返回值 const one_class_type * foo(..) , 表示这个函数的返回值是一个常量指针, 因此它的

        返回值只能付给 同类型的const 指针变量, 不能付给非const的.. 因为要强制保证const变量的值不被

          直接/甚至修改!

      const修饰类的成员函数的动作: 这时const要放在函数的最后: type foo(...) const {....} , 它表示, foo函数不能修改它之外的成员变量, 但可以引用/调用外部的成员变量, 但是不能调用非const的成员函数.

    ------------------------------------------------

    sizeof 和 strlen 的列出几个重要的区别:

    1.sizeof是算符,strlen是函数。

    2.sizeof可以用类型做参数(必须加括号)/普通变量,strlen只能用char*做参数,且必须是以''/0''结尾的。

    sizeof还可以用函数做参数,比如:
    short f();
    printf("%d/n", sizeof(f()));
    输出的结果是sizeof(short),即2。

    3.strlen计算的是字符串的长度,sizeof计算的是变量使用的内存大小,不受里面存储的内容改变

    4.strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。

    5.sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。

    6.当适用了于一个结构类型时或变量, sizeof 返回实际的大小, 当适用一静态地空间数组, sizeof归还全部数组的尺寸。 sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸 。

    6.数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:

    fun(char [8])
    fun(char [])
    都等价于 fun(char *)
    在C++里参数传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小
    如果想在函数内知道数组的大小, 需要这样做:
    进入函数后用memcpy拷贝出来,长度由另一个形参传进去
    fun(unsiged char *p1, int len)
    {
      unsigned char* buf = new unsigned char[len+1]
      memcpy(buf, p1, len);
    }

    我们能常在用到 sizeof 和 strlen 的时候,通常是计算字符串数组的长度

  • 相关阅读:
    自己写的基类:Forms身份验证类、客户端事件类,序列化类下载
    毕业设计上线啦!跳蚤部落与基于Comet的WebIM系统开发
    域名解析碎片整理 《不同的子域名解析到同一服务器下不同的网站》
    Mac 命令行大全
    position 事件 zindex
    vue 微信公众号网页开发 跳转小程序 踩坑
    React 笔记
    我对架构师的理解(如何成为一个合格的架构师)
    听过我爸是李刚,你听说过我妈是上海人不?
    Lucene.NET打造站内搜索引擎
  • 原文地址:https://www.cnblogs.com/bkylee/p/4957939.html
Copyright © 2020-2023  润新知