在C语言中,啥是动态存储,啥是静态存储?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在C语言中,啥是动态存储,啥是静态存储?相关的知识,希望对你有一定的参考价值。

动态存储是auto关键字,例如我们定义的int
a;
默认就是动态存储,具体应该是
auto
int
a;一般是用于函数参数,局部变量,超出作用域范围会失效,变量产生在动态存储区
静态存储时static关键字,例如,我们定义一个
static
int
a;
就是存储在静态存储区,相当于一个全局变量
一楼的理解出现了问题
参考技术A char
sz[5];就是静态的

char
*psz
=
new
char[5]就是动态的

静态的5一定要试常数不能使变量,而动态的则可以是随便的,可以是表达式也可以是常量或变量

因为静态的是编译完就分配好的,而动态的是在运行过程中才确定大小的;

比如我在程序中写char
sz[5];那么运行过程中就无法改变这块内存,分配大小从开始到运行结束都始终是不变的

而如果我在程序中写

int
i;

cin
>>
i;

char
*psz
=
new
char[i];

程序开始是没有分配大小的,因为这个值是未知的,等到我输入数值,他才知道该分配了多大,而你不能这样写

int
i;

cin
>>
i;

char
sz[i];

这样写是错误的,他会警告中括号里面的数字不是常数

而像这样的临时分配的内存必须要释放掉(c++中用delete而c中则是用free())

用于存储简单数据的“公共静态”和“私有静态”之间的区别。啥是更好的? [复制]

【中文标题】用于存储简单数据的“公共静态”和“私有静态”之间的区别。啥是更好的? [复制]【英文标题】:Difference between "public static" and "private static" for storing simple data. What is better? [duplicate]用于存储简单数据的“公共静态”和“私有静态”之间的区别。什么是更好的? [复制] 【发布时间】:2017-06-30 00:47:42 【问题描述】:

什么是更好的解决方案?

我在想,实际上哪个性能更好,或者哪个更“正确”?

public static List<String> globalUseVariable;

private static List<String> globalUseVariable;
public static List<String> getGlobalUseVariable() 
    return globalUseVariable;

我认为第二个是因为封装规则?

【问题讨论】:

您可能应该将其设为final,但这是一个见仁见智的问题。性能没有差异(实际上)(方法调用稍微慢)。 有人不得不说,正确的解决方案是没有有全局状态变量。我相信这里的答案总结了一切:***.com/questions/7026507/… 您还需要考虑是否要允许此列表的使用者对其进行修改。如果不是,您可能想要分发一个副本或一个不可变的包装器。副本的优点是您不需要关心并发修改。但是,这一切都取决于上下文是否需要或开销。当然也要避免像害虫一样的static @eckes 是的,这对我来说很有意义! @GhostCat 我不同意 dup 锤子。 【参考方案1】:

简单地说:

首先避免静态 也避免暴露内部状态

拥有 public 可写字段几乎是不可能的。如果您允许多个组件更新该数据,则会导致直接的硬耦合。这也意味着您可以(很可能)对线程安全说“再见”。即使你认为“我今天只会阅读那个领域”;也许你会在几周内忘记这一点。或者你团队中的其他人错过了那部分。所以

所以,如果您有好的理由向“公众”提供一些数据;然后至少使用getter方法;因为这允许(以后)更改。或者它允许简单的增强功能,例如返回内部状态的副本/克隆(以防止“外部人员”稍后操纵该内部状态)。

两种绕过静态的方法:

    如果您真的需要 全局 状态,或者其他东西可以完成这项工作,请仔细考虑 如果您需要全局状态,那么:A) 创建一个接口,表示您要提供的服务 B) 创建该接口的实现作为“普通”类 C) 然后使用实现该接口的单例(例如枚举)[现在单例枚举可以将其工作委托给该 impl 类]

通过遵循方法 2,您将获得具有相同功能的东西(您拥有所有代码都可以使用的“全局”东西);但是你让事情变得更加解耦;最重要的是:您可以在各处进行合理的单元测试。

静态通常是合理单元测试的“杀手”。

【讨论】:

【参考方案2】:

建议使用 getter,因为您可能希望在不更改 API 的情况下对类进行更改,或者您会决定在返回列表之前执行某种类型的转换。看看this answer regarding a similar situation。在我看来,同样的原则通常适用于静态字段,真的没有理由为它们例外。 This question 也涉及到同样的话题。我认为那里列出的原因也适用于静态字段并且是完全合理的。

一般而言,如果您将某些内容公开,您将创建一个公共 API,并应保证它不太可能更改,以免日后让您头疼(如果您正在创建公共库并且必须更改,甚至可能无法更改)向后兼容)。

另外使用 getter 和 setter,您可以确保您编写的代码是线程安全的,如其他答案和链接问题中所述。当您公开公共字段时,您无能为力。

【讨论】:

我们在这里谈论的是static getters。 我会考虑删除 getter 和 setter 的唯一情况是,如果我们正在讨论存储在 final 字段中的某种配置值,并且您真的不想使用 getter某种原因(我猜是为了让它包含更少的代码,但我不会亲自去做)。链接问题中提到的所有原因同样适用于静态字段。 只是一个提示:关于垂直间距的新疯狂概念(老派称之为“段落”)有助于使您的内容更易于阅读。只是说... @boreq 如果类外的代码可以修改List,那么getter 的意义何在。看我的回答。 重点是 getter 不必返回那个特定的列表。将来您可能希望更改它以完全返回其他内容。这通常是一个破坏性的 API 更改,这是在非常大的代码库或库中无法完成的。正如我所说,线程安全或防止列表被复制是由该问题解决的其他问题。不使用吸气剂确实是一种不好的做法,至少在我看来,如果您查看我链接的答案,其他人似乎同意我的观点。【参考方案3】:

哪个更“正确”?

就您的代码而言,我都不同意。将List 标记为private,然后在方法中返回对相同List 的引用,您将一无所获。您不能调用此封装,因为无论您在方法中添加什么逻辑,您都会将 List 引用返回给调用者,以便他们随意修改。如果你想真正遵守封装,你至少可以要求你的方法返回一个不可修改的集合(使用Collections.unmodifiableList)。

如果您希望您的列表为public,您至少可以将其标记为final,以便您的类外的代码无法尝试类似YourClass.globalUseVariable=null 的操作并破坏任何使用List 的代码。

【讨论】:

以上是关于在C语言中,啥是动态存储,啥是静态存储?的主要内容,如果未能解决你的问题,请参考以下文章

C语言中啥是整形数类

C语言中啥是字符,啥是字符串啊,谢谢

C语言中啥是一个8位的整数

c语言中啥是单精度型和双精度型???各举个例子。。。

C语言中啥是逻辑表达式,啥是关系表达式。举几个例子

C语言中啥是逻辑表达式,啥是关系表达式?