在 C 中声明和修改字符串

2024-02-09

我最近开始尝试学习C语言。在我的第一个程序(简单的 hello world 事情)中,在我意识到我不能这样做之后,我遇到了声明字符串的不同方法variable_name = "string data":

char *variable_name = "data"
char variable_name[] = "data"
char variable_name[5] = "data"

我不明白的是它们之间的区别。我知道它们是不同的,其中一个专门分配了一定量的内存来存储数据,但仅此而已,我觉得在转向 C 中更复杂的概念之前我需要从内到外理解这一点。

另外,为什么使用*variable_name让我将变量名称重新分配给一个新字符串,但是variable_name[number] or variable_name[]才不是?当然,如果我给它分配 10 个字节(char variable_name[10] = "data")并尝试将其重新分配给 10 字节或更小的东西,它应该可以工作,那么为什么不行呢?

空括号和星号有什么作用?


在这份声明中

char *variable_name = "data";

声明了一个指针。该指针指向字符串文字“data”的第一个字符。编译器将字符串文字放置在内存的某个区域,并通过文字的第一个字符的地址分配指针。

您可以重新分配指针。例如

char *variable_name = "data";
char c = 'A';

variable_name = &c;

但是您不能更改字符串文字本身。尝试更改字符串文字会导致程序的未定义行为。

在这些声明中

char variable_name[] = "data";
char variable_name[5] = "data";

声明了两个数组元素,其元素由用于初始化字符串文字的字符初始化。例如这个声明

char variable_name[] = "data";

等价于下面的

char variable_name[] = { 'd', 'a', 't', 'a', '\0' };

该数组将有 5 个元素。所以这个声明完全等同于声明

char variable_name[5] = "data";

如果您指定数组的其他大小,则会有所不同。例如

char variable_name[7] = "data";

在这种情况下,数组将按以下方式初始化

char variable_name[7] = { 'd', 'a', 't', 'a', '\0', '\0', '\0' };

也就是说,数组中没有显式初始化器的所有元素都被零初始化。

请注意,在 C 中,您可以按以下方式使用字符串文字声明字符数组

char variable_name[4] = "data";

即字符串文字的终止零未放置在数组中。 在 C++ 中这样的声明是无效的。

当然,如果您愿意,您可以更改数组的元素(如果它没有定义为常量数组)。

请考虑到您可以将用作初始化程序的字符串文字括在大括号中。例如

char variable_name[5] = { "data" };

在 C99 中,您还可以使用所谓的目标初始值设定项。例如

char variable_name[] = { [4] = 'A', [5] = '\0' };

这是一个演示程序

#include <stdio.h>
#include <string.h>

int main(void) 
{
    char variable_name[] = { [4] = 'A', [5] = '\0' };

    printf( "%zu\n", sizeof( variable_name ) );
    printf( "%zu\n", strlen( variable_name ) );

    return 0;
}

程序输出是

6
0

当您应用标准 C 函数时strlen在标头中声明<string.h>您会发现它返回 0,因为索引为 4 的元素之前的数组的第一个元素初始化为零。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C 中声明和修改字符串 的相关文章

  • 为什么libc++的shared_ptr实现使用完整内存屏障而不是宽松内存屏障?

    在boost的实现中shared ptr 它用放松内存排序以增加其引用计数 https github com boostorg smart ptr blob master include boost smart ptr detail sp
  • 32 位应用程序的特征最大矩阵大小

    所以 我正在寻找Eigen http eigen tuxfamily org index php title Main Page当我尝试声明大于 10000x10000 的矩阵时 包崩溃 我需要声明一个像这样的矩阵 可靠地大约有 13000
  • 为什么要序列化对象需要 Serialized 属性

    根据我的理解 SerializedAttribute 不提供编译时检查 因为它都是在运行时完成的 如果是这样 那么为什么需要将类标记为可序列化呢 难道序列化器不能尝试序列化一个对象然后失败吗 这不就是它现在所做的吗 当某些东西被标记时 它会
  • C++:重写已弃用的虚拟方法时出现弃用警告

    我有一个纯虚拟类 它有一个纯虚拟方法 应该是const 但不幸的是不是 该接口位于库中 并且该类由单独项目中的其他几个类继承 我正在尝试使用这个方法const不会破坏兼容性 至少在一段时间内 但我找不到在非常量方法重载时产生警告的方法 以下
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • 将名称字符串编码为唯一的数字

    我有一大堆名字 数以百万计 他们每个人都有一个名字 一个可选的中间名和一个姓氏 我需要将这些名称编码为唯一代表这些名称的数字 编码应该是一对一的 即一个名称只能与一个数字相关联 一个数字只能与一个名称相关联 对此进行编码的明智方法是什么 我
  • C 语言中 =+(等于加)是什么意思?

    我碰到 与标准相反 今天在一些 C 代码中 我不太确定这里发生了什么 我在文档中也找不到它 In ancientC 版本 相当于 它的残余物与最早的恐龙骨头一起被发现 例如 B 引入了广义赋值运算符 使用x y to add y to x
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • 如何重置捕获像素的值

    我正在尝试创建一个 C 函数 该函数返回屏幕截图位图中每四个像素的 R G 和 B 值 这是我的代码的一部分 for int ix 4 ix lt 1366 ix ix 4 x x 4 for int iy 3 iy lt 768 iy i
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 如何在c#中的内部类中访问外部类的变量[重复]

    这个问题在这里已经有答案了 我有两个类 我需要声明两个类共有的变量 如果是嵌套类 我需要访问内部类中的外部类变量 请给我一个更好的方法来在 C 中做到这一点 示例代码 Class A int a Class B Need to access
  • 在 C 中使用 GNU automake 中的解析器

    我是 GNU autotools 的新手 在我的项目中使用了 lex 和 yacc 解析器 将它们作为 makefile am 中的源代码会产生以下错误 配置 in AC CHECK PROGS YACC bison yacc none i
  • 如何挤出平面 2D 网格并赋予其深度

    我有一组共面 连接的三角形 即二维网格 现在我需要将其在 z 轴上挤出几个单位 网格由一组顶点定义 渲染器通过与三角形数组匹配来理解这些顶点 网格示例 顶点 0 0 0 10 0 0 10 10 0 0 10 0 所以这里我们有一个二维正方
  • 尚未处理时调用 Form 的 Invoke 时出现 ObjectDisposeException

    我们得到一个ObjectDisposedException从一个电话到Invoke在尚未处理的表格上 这是一些演示该问题的示例代码 public partial class Form2 Form void Form2 Load object
  • g++ 对于看似不相关的变量“警告:迭代...调用未定义的行为”

    考虑以下代码strange cpp include
  • 是否可以有一个 out ParameterExpression?

    我想定义一个 Lambda 表达式out范围 有可能做到吗 下面是我尝试过的 C Net 4 0 控制台应用程序的代码片段 正如您在 procedure25 中看到的 我可以使用 lambda 表达式来定义具有输出参数的委托 但是 当我想使
  • 当前的 x86 架构是否支持非临时加载(来自“正常”内存)?

    我知道有关此主题的多个问题 但是 我没有看到任何明确的答案或任何基准测量 因此 我创建了一个处理两个整数数组的简单程序 第一个数组a非常大 64 MB 第二个数组b很小 无法放入 L1 缓存 程序迭代a并将其元素添加到相应的元素中b在模块化
  • 双精度类型二维多维数组的 pinvoke 编组作为 c# 和 c++ 之间的输入和输出

    我有以下我正在尝试解决的双物质类型的 2d 多维数组的 c 和 c pinvoke 编组 我已经查看了以下热门内容以获得我目前拥有的内容使用双精度数组进行 P Invoke 在 C 和 C 之间编组数据 https stackoverflo
  • 使用 CSharpCodeProvider 类编译 C# 7.3 的 C# 编译器版本是什么?

    我想使用 Microsoft CSharp CSharpCodeProvider 类来编译 C 7 3 代码 编译器版本在 IDictionary 中指定 在创建新的 CSharpCodeProvider 时将其作为输入 例如 Compil
  • 是否可以在 C# 中强制接口实现为虚拟?

    我今天遇到了一个问题 试图重写尚未声明为虚拟的接口方法的实现 在这种情况下 我无法更改接口或基本实现 而必须尝试其他方法 但我想知道是否有一种方法可以强制类使用虚拟方法实现接口 Example interface IBuilder

随机推荐

  • 以编程方式打开特定的设置页面

    在我的应用程序中 有什么方法可以将用户重定向到特定的设置 页面 吗 我的应用程序用作锁屏应用程序 因此我希望能够将用户直接重定向到 Android 设置的 锁屏 部分 最好通过按钮或类似的东西 ACTION SECURITY SETTING
  • 使用闭包工具创建表

    谁能帮助我使用闭包库创建表格 网格布局 有可用的小部件吗 我搜索过但没有找到 请帮忙 截至 2012 年 5 月 Closure Library 不提供表格 网格布局组件 有一个表格排序器 参见demo http closure libra
  • 如果没有 std::contigious_iterator_tag,如何检测连续迭代器?

    C 17引入了ContigeousIterator的概念http en cppreference com w cpp iterator http en cppreference com w cpp iterator 但似乎并没有计划cont
  • 是否可以在我自己的服务器上托管电报?

    Telegram https telegram org 是一种基于云的聊天服务 他们所有的客户端都是开源的 我想知道是否有办法在我自己的服务器上托管 私人 电报服务 如果没有 是否有任何东西可以提供 telegram 提供的所有或几乎所有功
  • 如何调整 pub 包“flutter_native_splash”中的图像大小?

    我正在使用 flutter native splash 1 3 1 包向应用程序添加启动屏幕 显示的图像尺寸大于启动屏幕上所需的尺寸 减小启动屏幕上图像大小的正确方法是什么 不幸的是 我认为你做不到 因此 选项是调整图像大小以适合您的屏幕
  • Visual Studio 中 F10 和 F11 键有什么区别?

    I m new in C I hit a breakpoint and pressed F10 or F11 应该使用哪个键进行编译 请帮帮我 你能解释一下这个键的作用吗 F10 step over does not descend any
  • 模拟真实的鼠标点击

    我想做的是在 YouTube 上执行鼠标单击 在页面加载时按播放键 如何单击该特定位置 假设它始终位于同一位置 我尝试过但失败了 var e document getElementById myelem e click var e new
  • 在 Electron 中禁用网络

    电子 js https electronjs org 是一个用户界面工具包 允许 Web 应用程序作为任意 GUI 运行 然而 有一些应用程序应该被视为敏感 例如 银行业的 GUI 应该有强有力的保证 确保它不会做任何恶作剧 我想知道电子
  • 接收和旋转字符的函数 - 凯撒密码

    我正在尝试创建一个函数 rotate character char rot 接收一个字符 char 长度为 1 的字符串 和一个整数 rot 该函数应返回一个长度为 1 的新字符串 这是将 char 向右旋转 rot 个位数的结果 因此 输
  • 选择小数点后 4 位以上的数字

    我有一个 SQL 表 其中有一个浮点列 其中填充了如下值 1 4313 3 35 2 55467 6 22456 3 325 我需要选择仅包含小数点后 4 位以上的值的行 在这种情况下 选择必须返回 2 55467 6 22456 有想法吗
  • 在 H5PY 中打开文件时出错(未找到文件签名)

    我一直在使用以下代码来打开一些 HDF5 文件 这些文件是在 MATLAB 中使用 H5PY 在 python 中生成的 import h5py as h5 data dataset mat f h5 File data r 但是我收到以下
  • 更大的运算符“">”是否满足严格的弱排序?

    定义 Let lt 是一个二元关系 其中a lt b means a小于b Let gt 是一个二元关系 其中a gt b means a大于b 所以 我们假设 lt and gt 具有我们在日常生活中通常使用的含义 不过 在某些编程语言
  • 有人可以解密这个javascript吗

    我在一个论坛中找到它 告诉我这段代码可以让我自动玩 Facebook 游戏 但我担心这不是他们所说的 我担心这是恶意脚本 请帮忙 javascript var 0x8dd5 x73 x72 x63 x73 x63 x72 x69 x70 x
  • 将 .db 文件导入 R

    我正在尝试使用下面的代码导入 db 文件 该代码与包的示例相同 并且显示找不到函数 有人知道如何导入 db 文件吗 library ProjectTemplate db reader c3 db Users xxx Documents c3
  • 在 Startup.cs .net core 2.1 中加载程序集

    我在名为 nuqkgs 的文件夹中有块包 在项目启动时我想将这些包 有 dll 加载到项目中以在运行时使用 我使用下面的代码来加载它们 当我调试时 我可以看到信息 并且找到并打开了 dll 但是当应该使用它们时 我收到错误 找不到 dll
  • TEdgeBrowser 模态打印对话框?

    TEdge浏览器有替换了 TWebBrowser https docwiki embarcadero com RADStudio Alexandria en Using TEdgeBrowser Component and Changes
  • 更改默认图标工具栏(传单)

    我如何将默认工具栏图标更改为传单上的其他图标 上面的图片显示了图标的默认视图 我想自定义图标并将其更改为其他图标 例如我希望第一个图标看起来像桥梁和第二个文本图标等等 我已经尝试了几种方法但没有成功 这是我的代码 var electricp
  • 在 lapply 函数中访问和保留列表名称

    我需要访问 lapply 函数内的列表名称 我在网上找到了一些线程 据说我应该迭代列表的名称 以便能够获取函数中的每个列表元素名称 gt n names mylist gt mynewlist lapply n function namei
  • 在另一个视图控制器中更改标签的文本

    我有一个名为 FirstViewController 的视图控制器 还有一个名为 SecondViewController 的视图控制器 我提出第二个视图控制器 UIViewController controller self storyb
  • 在 C 中声明和修改字符串

    我最近开始尝试学习C语言 在我的第一个程序 简单的 hello world 事情 中 在我意识到我不能这样做之后 我遇到了声明字符串的不同方法variable name string data char variable name data