c笔记08---变量,栈,秒表练习,关键字 static,指针变量和变量的指针

1.    变量分成三种:全局变量,局部变量和块变量
    变量的作用域指的是“变量名“的作用域,而非变量;生命周期和作用域一致;
    变量和变量名是不一样的;
    全局变量在程序开始前就默认初始化为 0;static 静态变量在编译的时候,初始化为 0;
    若是多个变量同名,调用最近的那个变量(就近原则);

2.    栈是由一组变量组成,用数组表示,栈使用变量方式遵循后进先出。
    操作栈需要一个 int num 变量,一个 int stack[10] 数组,和以下四个函数:
    int num;
    int stack[10];
    void push(int value);    // 放入变量
    {
        stack[num] = value;
        num++;
    }
    int pop();            // 取出变量
    {
        num--;
        stack[num];
    }
    int empty();        // 查看栈是否为空
    {
        return 0 == num;
    }
    int full();            // 查看栈是否满了
    {
        return 10 == num;
    }


3.    秒表练习
    #include <stdio.h>
    #include <time.h>
    #include <unistd.h>                // sleep(1)语句调用
     int main()
    {
        int start = time(0);        // 获取当前时间
        while(1)//死循环
        {
            printf("%d\r", time(0) - start);    // \r指删除之前显示的,重新显示
            fflush(stdout);            // 强制显示
            sleep(1);                // 让程序休息一秒再运行,不精确,可能差几毫秒;
        }
        return 0;
    }

4.    程序在内存中运行是分段存储的。
    代码段用来存储所有语句,在运行时,代码段是不可以更改的。
    栈:数据段/局部变量段,(全局变量除外)
    堆:用来处理手动创建和销毁的变量

5.    变量关键字:
    auto 所有局部变量默认都为 auto,所以不需要特别声明;
    static 用来声明静态变量。
        静态全局变量,作用域变小;不能在不同的文件中使用;
        静态局部变量,作用域不变,上次运行的结果被保存下来,生命周期类似于全局变量,
            但是作用域没有全局变量大(生命周期和作用域不一致,生命周期长了,作用域不变),即变量名在其他函数中不能用。
        静态函数与普通函数作用域不同;仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),
            内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,
            应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件;
            静态函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝;

    register 寄存器变量,位于 cpu 里面,数量少,非常重要,一般不使用。
    volatile 声明易变变量。
    const 声明不可变变量,也可以定义指针。
        const int *p = &value;    // 也可以写为:int const *p = &value
        *p = 3;                    // 编译错误,内容不可以修改
        p = NULL;                // 地址可以修改
        value = 3;                // const定义的是p,对value没影响
        另外一种定义:
        int * const p1 = &value;
        *p1 = 3;                // 内容可以修改
        p1 = 3;                    // 编译错误,地址不能修改
        
        还可以两边都加 const,
        const int * const p = &value;
        这样 *p 和 p 都不可以被修改;

6.    变量的指针就是指变量的地址,咱平时在程序里用的是指针变量:
    指针变量:
        int *p = & value;
        *p = value; 或者  *p = 5;
    注意第一句里的“&”;第一句为初始化,第二句为赋值;
    给指针变量初始化,必须用地址,例如上面第二句赋值语句写成 p = 5; 是错误的;
    同时被赋值的指针变量前也不能再加“&”,例如上面第二行赋值语句写成 *p = & value; 是错误的;

    通过指针,把 5,7 赋值给数组 value[2];
    int value[2];
    int *p_value = value;            // 指针地址必须初始化,若无法初始化,就初始化为:*p_value = NULL;
    *p_value = 5;                    // value[0] = 5
    p_value++;
    *p_value = 7;                    // value[1] = 7
    *(p_value - 1) += *p_value;        // value[0] += value[1]

    可以用指针变量作为返回值:
    int *func()
    {
        static int value = 0;        // 此处要用static把value静态化,否则函数结束,value生命周期结束,return返回的是野指针
        return &value;
    }
    int main()
    {
        int *p = NULL;
        *p = 7;
        p = fun();
    }

7.    NULL 表示空地址,其实是数字 0 ,记录空地址的指针叫做空指针。
    未初始化的指针为无效指针,所有无效指针必须初始化为空指针,即 *p = NULL;
    记录无效地址的指针叫做野指针,程序中不应该出现野指针;
    野指针也叫悬空指针。

8.    通过指针 *p,用 for 循环表示数组 value[4] 的遍历:for(p = value; p < value + 4; p++)

9.    把 int *p 转换为无符号字符指针:*(unsigned char *)p;
    指针可以强制类型转换,转换后地址和原地址相同,但他们的类型不同,所以使用方法也不一样。

10.    指针作形参,实参必须是地址,既当输入参数,又当输出参数。
    数组作形参,其实就是指针作形参。

11.    当指针变量要代表多个类型的参数时,可以如下声明:
    void *p = NULL;
    int i = 1;
    p = &i;
    但在输出或其他使用的时候,必须强制类型转换,如:
    printf("%d", *(int *)p);
    
12.    看书笔记:
    两个指针可以相减,一般用于数组;
    但是两个指针不可以相加,会得到不确定结果,甚至出错;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值