C/C++ 静态变量解析

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 静态变量:这种变量的内存将保存到整个程序的结束,他的内存是独立存放到一个叫做静态内存区的。           所有的静态的变量如果不赋值,会默认赋值为0,不管是结构体还是其他类型的变量,           当然静态变量的初始化也分为静态初始化和动态初始化,如果有一些不可确定的因素会使用           动态初始化           比如:           int a = 1;静态初始化。


静态变量:这种变量的内存将保存到整个程序的结束,他的内存是独立存放到一个叫做静态内存区的。
          所有的静态的变量如果不赋值,会默认赋值为0,不管是结构体还是其他类型的变量,
          当然静态变量的初始化也分为静态初始化和动态初始化,如果有一些不可确定的因素会使用
          动态初始化
          比如:
          int a = 1;静态初始化。
          double a = sqrt(2);动态初始化因为sqrt是一个不确定的因素。
          有几个概念
          内部全局:内部是说不能被其他文件调用,全局是说有限访问范围为本文件。
          外部全局:外部是说可以被其他文件调用,全局是说有限访问范围为本文件。
          内部局部:内部是说不能被其他文件调用,局部是说有限访问范围为本代码块。
举例3种模式
1、内部局部静态变量,如
int test(void)
{
static i = 1;
.....
}
这个静态变量是局部的,有效范围是本代码块。
2、外部全局静态变量
int i = 1;
int test(void)
{
   ....
}
这个静态变量是全局的,有效范围是本文件。
并且它是外部的,所以其他文件如果想使用可以使用
extern int i;
3、内部全局静态变量
static i = 1;
int test(void)
{
   ....
}
这个静态变量是全局的,有效范围是本文件。
并且它是内部的,不能被其他文件调用,
如果想extern int i;是不行的。
注意extern int i;不能初始化,因为他只是声明而已,实际的变量在其他文件进行了空间初始化,也就是说内存
已经分配了这里
extern int i;不会分配任何内存空间。
这里展开说一下关于左值和右值。
任何一个有限的内存空间才能作为左值,

int a=1;
int *p;
p = &a;
*p = 1;
是可以作为左值的,如果没有有效内存一定不行
比如

int a;
int b;
a+b = 5;
这里的a+b 是一段临时空间不能作为左值

但是关于如果我们抓住一个细节就是这段静态内存区域在整个程序期间都存在,C/C++是很灵活的,
我们就可以定义一个指针来访问他。
我写了一段程序。这段程序包含了其他的一些东西,比如flexible array number 来节约内存,

点击(此处)折叠或打开

  1. t1.h

  2. #include<iostream>
  3. using namespace std;

  4. #ifndef TEST_H__
  5. #define TEST_H__
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <stdio.h>

  9. typedef struct chain
  10. {
  11.          char address[];
  12. } CM;
  13. typedef struct mc
  14. {
  15.         int id;
  16.         char name[20];
  17.         CM* adr;
  18. } CHC;
  19. #define LEN_S strlen(max_address)+sizeof(CM)+3
  20. #define LEN_MAX strlen(max_address)
  21. CM* finps(CHC* ins);
  22. void fshows(const CHC* ins);
  23. int** stre(void);

  24. #endif


  25. t3.cpp


  26. #include<iostream>
  27. #include "t1.h"
  28. using namespace std;

  29. static int st1 = 1;
  30. static int st2 = 2;

  31. int** stre(void)
  32. {
  33.         static int* p[2];
  34.         p[0] = &st1;
  35.         p[1] = &st2;
  36.         return p;
  37. }

  38. CM* finps(CHC* ins)
  39. {
  40.         char max_address[80];
  41.         static CM* ck;

  42.         cout<< "please input id:" <<endl;
  43.         cin >> ins->id;
  44.         cin.get();
  45.         cout<<"please input name:"<<endl;
  46.         cin.getline(ins->name,19);
  47.         cout<<"please input your address"<<endl;
  48.         cin.getline(max_address,79);
  49.         ck = (CM* )malloc(LEN_S);
  50.         ins->adr = ck;
  51.         strcpy(ck->address,max_address);
  52.         return ck;

  53. }

  54. void fshows(const CHC* ins)
  55. {
  56.         cout<<"your information is:"<<endl;
  57.         cout<< ins->id <<endl;
  58.         cout<< ins->name <<endl;
  59.         cout<< ins->adr->address <<endl;
  60. }

  61. t2.cpp
  62. #include<iostream>
  63. #include "t1.h"
  64. using namespace std;

  65. int main(void)
  66. {
  67.         CHC ins;
  68.         CM* dt;
  69.         int** p;
  70.         dt = finps(&ins);
  71.         fshows(&ins);
  72.         free(dt);
  73.         p = stre();
  74.         cout<<"access static values from pointer:"<<endl;
  75.         cout<<**p<<endl;
  76.         cout<<**(p+1)<<endl;
  77. }


注意这里的

点击(此处)折叠或打开

  1. static int st1 = 1;
  2. static int st2 = 2;
  3. int** stre(void)
  4. {
  5.         static int* p[2];
  6.         p[0] = &st1;
  7.         p[1] = &st2;
  8.         return p;
  9. }


实际上我定义了一个指针数组来保存st1和st2的地址,并且返回了指向指针的指针p
那么我们访问的时候就可以
<endl;

点击(此处)折叠或打开

  1. cout<<**p<<endl;
  2. cout<<**(p+1)<<endl;
<endl;
来进行访问了,这样一来虽然定义的内部全局静态变量但是任然访问到了。


编译执行这段程序:
gaopeng@bogon:~/CPLUSPLUS/part9$ g++  t2.cpp t3.cpp
gaopeng@bogon:~/CPLUSPLUS/part9$ ./a.out 
please input id:
1
please input name:
gaopeng
please input your address
chongqing
your information is:
1
gaopeng
chongqing
access static values from pointer:
1
2
</endl;
</endl;

--end---



目录
打赏
0
0
0
0
91
分享
相关文章
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
【C++篇】深度解析类与对象(中)
在上一篇博客中,我们学习了C++类与对象的基础内容。这一次,我们将深入探讨C++类的关键特性,包括构造函数、析构函数、拷贝构造函数、赋值运算符重载、以及取地址运算符的重载。这些内容是理解面向对象编程的关键,也帮助我们更好地掌握C++内存管理的细节和编码的高级技巧。
【C++篇】深度解析类与对象(上)
在C++中,类和对象是面向对象编程的基础组成部分。通过类,程序员可以对现实世界的实体进行模拟和抽象。类的基本概念包括成员变量、成员函数、访问控制等。本篇博客将介绍C++类与对象的基础知识,为后续学习打下良好的基础。
基于红黑树的局域网上网行为控制C++ 算法解析
在当今网络环境中,局域网上网行为控制对企业和学校至关重要。本文探讨了一种基于红黑树数据结构的高效算法,用于管理用户的上网行为,如IP地址、上网时长、访问网站类别和流量使用情况。通过红黑树的自平衡特性,确保了高效的查找、插入和删除操作。文中提供了C++代码示例,展示了如何实现该算法,并强调其在网络管理中的应用价值。
C++ `noexcept` 关键字的深入解析
`noexcept` 关键字在 C++ 中用于指示函数不会抛出异常,有助于编译器优化和提高程序的可靠性。它可以减少代码大小、提高执行效率,并增强程序的稳定性和可预测性。`noexcept` 还可以影响函数重载和模板特化的决策。使用时需谨慎,确保函数确实不会抛出异常,否则可能导致程序崩溃。通过合理使用 `noexcept`,开发者可以编写出更高效、更可靠的 C++ 代码。
73 1
深入解析C++中的函数指针与`typedef`的妙用
本文深入解析了C++中的函数指针及其与`typedef`的结合使用。通过图示和代码示例,详细介绍了函数指针的基本概念、声明和使用方法,并展示了如何利用`typedef`简化复杂的函数指针声明,提升代码的可读性和可维护性。
119 1
【C++11】包装器:深入解析与实现技巧
本文深入探讨了C++中包装器的定义、实现方式及其应用。包装器通过封装底层细节,提供更简洁、易用的接口,常用于资源管理、接口封装和类型安全。文章详细介绍了使用RAII、智能指针、模板等技术实现包装器的方法,并通过多个案例分析展示了其在实际开发中的应用。最后,讨论了性能优化策略,帮助开发者编写高效、可靠的C++代码。
74 2
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
141 2
从入门到精通:H5游戏源码开发技术全解析与未来趋势洞察
H5游戏凭借其跨平台、易传播和开发成本低的优势,近年来发展迅猛。接下来,让我们深入了解 H5 游戏源码开发的技术教程以及未来的发展趋势。

推荐镜像

更多
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等