C/C++static的巧妙用法

本文介绍了C/C++中static关键字用于定义静态局部变量的特性,包括其在整个源程序中的生存期和仅在定义函数内的作用域。静态局部变量在函数多次调用时只会初始化一次,保存前次调用的值,适合需要保留变量状态的场景。文中通过链表回文检查的例子,展示了如何利用静态变量写出简洁高效的代码。

C/C++static的巧妙用法

学过C或者C++的想必都知道static定义静态变量。但是通过书中的例题实在是想不明白它到底有什么用途,本编文章将通过一个例子来介绍static的巧妙用法,让你对static定义的静态变量用更深层的认识。

首先先来复习一下什么是静态变量(会的可以直接略过)

  • 静态变量的类型说明符是static。 静态变量当然是属于静态存储方式,但是属于静态存储方式的量不一定就是静态变量, 例如外部变量虽属于静态存储方式,但不一定是静态变量,必须由 static加以定义后才能成为静态外部变量,或称静态全局变量。 对于自动变量,前面已经介绍它属于动态存储方式。 但是也可以用static定义它为静态自动变量,或称静态局部变量,从而成为静态存储方式。

  • 静态局部变量属于静态存储方式,它具有以下特点:
    (1)静态局部变量在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。
    (2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。
    (3)允许对构造类静态局部量赋初值。若未赋以初值,则由系统自动赋以0值。
    (4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点, 可以看出它是一种生存期为整个源程序的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。

总结起来就是由static定义的静态局部变量在函数的多次被调用中只会在第一次被调用中定义一次,而生存期为整个源程序。

下面通过一个例子加深理解

  • 题目描述
    请编写一个函数,检查链表是否为回文。
    给定一个链表ListNode* pHead,请返回一个bool,代表链表是否为回文。
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Palindrome {
public:
    bool isPalindrome(ListNode* pHead) {
        // write code here
    }
};
  • 测试样例:
    {1,2,3,2,1}
    返回:true
    {1,2,3,2,3}
    返回:false

这道题其实很简单,遍历一遍链表把数据存储下来在判断。(代码如下 :)

class Palindrome {
public:
    bool isPalindrome(ListNode* pHead) {
        // write code here
        vector<int> vint;
        while(pHead) {
            vint.push_back(pHead->val);
            pHead = pHead->next;
        }
        vector<int> vint2(vint.rbegin(),vint.rend());
        return vint == vint2;
    }
};

也可以通过快慢指针来实现。(代码如下:)

class Palindrome {
public:
    bool isPalindrome(ListNode* pHead) {
        // write code here
        if(!pHead || !pHead->next) return true;
        stack<int> sint;
        ListNode *ptr_fast = pHead;
        while(ptr_fast && ptr_fast->next) {
            sint.push(pHead->val);
            pHead = pHead->next;
            ptr_fast = ptr_fast->next->next;
        }
        if(ptr_fast)
            pHead = pHead->next;
        while(pHead) {
            if(pHead->val != sint.top())
                return false;
            pHead = pHead->next;
            sint.pop();
        }
        return true;
    }
};

但是这些都不能体现出我们的水平,上面的代码冗长复杂。

接下来通过静态变量写出让人眼前一亮的代码

class Palindrome {
public:
    bool isPalindrome(ListNode* pHead) {
        if(!pHead) return true;
        static ListNode *ptr = NULL;
        if(!ptr) ptr = pHead;
        while(isPalindrome(pHead->next) && pHead->val == ptr->val) {
            ptr = ptr->next;
            return true;
        }
        ptr = NULL;
        return false;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值