static&const

static

1、 关键字static的作用是什么?

在C语言中,关键字static有三个明显的作用:
1). 在函数体,一个被声明为静态的变量在这一函数被调用过程中维持其值不变。
2). 在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所用函数访问,但不能被模块外其它函数访问。它是一个本地的全局变量。
3). 在模块内,一个被声明为静态的函数只可被这一模块内的其它函数调用。那就是,这个函数被限制在声明它的模块的本地范围内使用。

2.static具体到修饰不同的变量函数对应的特点:

  • 修饰局部变量
    static修饰局部变量时,使得被修饰的变量成为静态变量,存储在静态区。存储在静态区的数据生命周期与程序相同,在main函数之前初始化,在程序退出时销毁。(无论是局部静态还是全局静态)

  • 修饰全局变量
    全局变量本来就存储在静态区,因此static并不能改变其存储位置。但是,static限制了其链接属性。被static修饰的全局变量只能被该包含该定义的文件访问(即改变了作用域)。

  • 修饰函数
    static修饰函数使得函数只能在包含该函数定义的文件中被调用。对于静态函数,声明和定义需要放在同一个文件夹中。

  • 修饰成员变量
    用static修饰类的数据成员使其成为类的全局变量,会被类的所有对象共享,包括派生类的对象,所有的对象都只维持同一个实例。 因此,static成员必须在类外进行初始化(初始化格式:int base::var=10;),而不能在构造函数内进行初始化,不过也可以用const修饰static数据成员在类内初始化。

  • 修饰成员函数
    用static修饰成员函数,使这个类只存在这一份函数,所有对象共享该函数,不含this指针,因而只能访问类的static成员变量。静态成员是可以独立访问的,也就是说,无须创建任何对象实例就可以访问。例如可以封装某些算法,比如数学函数,如ln,sin,tan等等,这些函数本就没必要属于任何一个对象,所以从类上调用感觉更好。

  • 最重要的特性:隐藏
    当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,其它的源文件也能访问。利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。static可以用作函数和变量的前缀,对于函数来讲,static的作用仅限于隐藏。

static修饰成员变量:同一个类的所有实例共享一个静态成员变量

#include<iostream>
 
using namespace std;
class S1
{
public:
	static int a;
	void say(){
		cout << a << endl;
	}
protected:
private:
};
int S1::a = 10;
void main(){
	S1 s1;
	S1 s2;
	s1.a = 5;
	s1.say();//5
	s2.say();//5
	s2.a = 6;
	s1.say();//6
	
	system("pause");
 
}

const

在C语言中const修饰一个全局变量,无论如何都无法修改变量的值
在C语言中如果const修饰一个局部变量,则只能通过指针变量来改变其值
const在最前面修饰得是指针变量的类型,不能通过指针变量修改对应的内容。
const在中间修饰的是指针变量,所指向的地址不能改变。

#include <stdio.h>

//在C语言construction修饰一个全局变量,无论如何都无法修改变量的值
const int a = 100;

void test1()
{
    printf("a = %d\n", a);

    //a = 200;
    //printf("a = %d\n", a);

    //int *p = &a;
    //*p = 200;
    //printf("a = %d\n", a);
}

void test2()
{
    //在C语言中如果const修饰一个局部变量,则只能通过指针变量来改变其值
    const int b = 200;
    printf("b = %d\n", b);

    //b = 666;
    //printf("b = %d\n", b);

    int *p = &b;
    *p = 888;
    printf("b = %d\n", b);
}

void test3()
{
    int c = 100;
    //int *p = &c;

    //如果const修饰指针变量的类型,则不能通过指针变量修改保存的地址里面的内容
    //const int *p = &c;

    //如果const修饰指针变量,则不能修改指针变量保存的地址
    //int *const p = &c;

    //如果既修饰指针变量的类型又修饰指针变量,则只能通过原本的变量修改内容,无法通过指针变量修改
    const int * const p = &c;

    printf("*p = %d\n", *p);

    //想要修改p指针里面保存的地址里面的内容,如何修改
    //方法1:直接通过c变量修改
    c = 666;
    printf("*p = %d\n", *p);

    //方法2:直接通过*p修改
    *p = 777;
    printf("*p = %d\n", *p);

    //方法3:直接修改p保存的地址
    int d = 888;
    p = &d;
    printf("*p = %d\n", *p);
}

int main(int argc, char *argv[])
{
    test3();

    return 0;
}

c++ 中


#include <iostream>

using namespace std;

//C++中的const使用方法与C语言基本类似
//对全局变量和指针变量修饰是一模一样的,但是对局部变量的操作有区别

void test1()
{
    //const如果修饰一个局部变量,局部变量保存值
    //操作系统会认为当前变量是不会被改变的,所以会将当前变量和值保存在符号常量表中
    //保存在符号常量表中之后,下次使用当前变量时,不会从原本变量的地址中取值,而是
    //从符号常量表中取值,所以即使改变原本的地址的内容,使用变量时发现值还是没改
    //const int a = 100;

    //使用volatile修饰变量,表示当前变量时易变的,所以不会保存在符号常量表中
    const volatile int a = 100;
    cout << "a = " << a << endl;

//    a = 666;
//    cout << "a = " << a << endl;

    //C++对类型严格要求,需要保证左右值类型必须一样
    int *p = (int *)&a;
    *p = 666;

    cout << "&a = " << &a << endl;
    cout << "p = " << p << endl;

    cout << "*p = " << *p << endl;
    cout << "a = " << a << endl;
}

void test2()
{
    int m = 100;
    //如果const修饰的变量保存的是一个变量,则不会讲变量保存在符号常量表中
    const int a = m;

    int *p = (int *)&a;
    *p = 666;

    cout << "*p = " << *p << endl;
    cout << "a = " << a << endl;
}

struct stu{
    int a;
    int b;
    char c;
};

void test3()
{
    //如果const修饰的变量的类型是构造数据类型,则也不会保存在符号常量表中
    const stu s1 = {100, 200, 'w'};
    stu *p = (stu *)&s1;

    p->a = 666;
    p->b = 777;
    p->c = 'q';

    cout << s1.a << " " << s1.b << " " << s1.c << endl;
}

int main(int argc, char *argv[])
{
    test3();

    return 0;
}

``

3 – 符号常量表 const int a = 10;符号常量表。
在这里插入图片描述**/

const如果修饰一个局部变量,局部变量保存值.操作系统会认为当前变量是不会被改变的,所以会将当前变量和值保存在符号常量表中。
保存在符号常量表中之后,下次使用当前变量时,不会从原本变量的地址中取值,而是从符号常量表中取值,所以即使改变原本的地址的内容,使用变量时发现值还是没改。
改了没,他确实改了,但是你用的时候却还是改之前的那个狗子了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值