字符数组可以初始化赋值,却不能直接赋值,为啥?

C语言字符数组与字符串的使用详解 字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素。即把10个字符分别赋给str[0]到str[9]10个元素如果花括号中提供的字符个数大于数组长度,则按语法错误处理;若小于数组长度,则只将这些字符数组中前面那些元素,其余的元素自动定为空字符(即 '\0' )。 阅读详情

在C语言中,字符数组(如 char[20])可以在初始化时赋值,但不能在定义后直接赋值,这是由C语言的设计规则和底层内存管理机制决定的。下面详细解释原因。

1. 根本原因:数组名是“不可修改的左值”

  • 数组名的本质:
    在C语言中,数组名是一个指向数组首元素的常量指针(例如 char[20] 的数组名会被视为 char* const 类型)。
    • 它代表一块固定内存的起始地址,编译时确定,无法被修改。
    • 因此,数组名不能作为赋值操作(=)的左值。
  • 初始化 vs 赋值:

初始化(Declaration with Initialization):

char name[20] = "Alice";  // 合法:初始化时编译器会填充数组内存

这是编译器在编译阶段完成的静态内存填充,不涉及运行时赋值操作。

赋值(Assignment after Declaration):

char name[20];
name = "Alice";  // 非法:运行时试图修改数组名的指向

这里 name 是常量指针,不能重新指向其他地址(如字符串字面量 "Alice" 的地址)。

2. 类比:其他语言的设计

C++的 std::string:
C++的 std::string 是类类型,支持直接赋值(重载了 = 运算符),但底层仍是通过动态内存管理实现的:

std::string name;
name = "Alice";  // 合法:实际上是调用了 operator=()

Python/Java的字符串:
这些语言的字符串是不可变对象,变量名本质是指针,赋值只是改变指针指向:

name = "Alice"  # name指向新字符串

C的严格性:
C语言为了效率和贴近硬件,直接暴露内存管理,因此数组名是固定的内存块标识符,不允许重新绑定。

3. 底层解释:内存分配方式

初始化时的内存填充:

char name[20] = "Alice";

编译器会在程序加载到内存时,直接将字符串 "Alice\0" 的字节序列拷贝到数组的内存空间(静态或栈内存)。

赋值时的操作:

name = "Alice";  // 试图做什么?

如果允许这种语法,实际需要完成以下步骤:

    1. 找到字符串字面量 "Alice" 的地址(通常存储在只读区)。
    2. 将 name 的指向改为该地址。
      但 name 是数组的首地址常量,无法被修改(类似 char* const 指针)。

4. 解决方案

(1)使用 strcpy 复制内容
char name[20];
strcpy(name, "Alice");  // 将字符串内容复制到数组内存中
(2)改用指针(动态分配)
char *name = malloc(20);
strcpy(name, "Alice");  // 合法:指针可以重新赋值
free(name);
(3)结构体中的特殊规则

结构体初始化允许整体赋值(因为编译器会隐式处理):

struct Person {
    char name[20];
};
struct Person p = {"Alice"};  // 合法:初始化时整体填充内存

5. 为什么C语言这样设计?

  1. 性能优先:
    直接操作内存是C的核心特性,避免隐式内存拷贝带来的开销。
  2. 确定性内存布局:
    数组名代表固定内存块,编译器可以静态计算偏移量(如 name[5] 直接映射到 地址 + 5)。
  3. 历史原因:
    C诞生于早期计算机时代,设计上强调对硬件的直接控制,不提供高级抽象。

总结对比

操作

字符数组 (char[20])

字符指针 (char*)

初始化赋值

char s[20] = "Alice"; ✅

char *s = "Alice"; ✅

定义后赋值

s = "Bob"; ❌

s = "Bob"; ✅

内容修改

strcpy(s, "Bob"); ✅

strcpy(s, "Bob"); ✅

内存所有权

栈/静态内存(固定)

可指向任意内存(动态/常量)

核心原则:
C语言的数组名是内存块的“标签”,不是变量,因此无法通过赋值改变其绑定关系。

【SAP PO】SAP PO 接口配置完整教程之一RFC服务发布 SAP RFC开发,PO接口配置 阅读详情

相关推荐

python123题目——个税计算器

类型:简单分支。

m0_62488776的博客 5803

关于C语言中数组不能直接赋值的原因探究

#include <stddef.h> #include <stdio.h> typedef struct{ int s1; int s2; }Struct; int test() { return 0; } int test2() { return 0; } int main() { int array[3] = {1,2,3}; Struct stru = {1,2}; Struct sru2 = stru; int a =

watershed1993的博客 5183

2022北京高考数学压轴题21题:Python暴力枚举验证k≥7的5种反例

本文探讨了2022北京高考数学压轴题21题的编程解法,通过Python暴力枚举验证k≥7的5种反例。文章详细介绍了m-连续可表数列的定义、问题转化与约束条件,并提供了暴力枚举算法设计和优化技巧,帮助读者理解如何用编程思维解决数学问题。

weixin_33552698的博客 233

C语言关于为什么字符串不能直接赋值

一、为什么字符串声明的时候可以直接赋值,后面的就不行 //这样可以直接初始化赋值: char name[24] = "my name is eet"; //后面再赋值是错误的: char name[24]; name = "my name is eet"; ----...

1万+

NT35310 LCD屏的初始化与图形显示实战:从画点到UI设计的完整指南

本文详细介绍了NT35310 LCD屏的初始化与图形显示实战,从硬件配置到UI设计全流程。内容包括8080总线连接、初始化序列、基础图形绘制算法、显示优化技巧以及UI框架实现,帮助开发者快速掌握TFT-LCD驱动开发技术,适用于工业控制和智能家居等嵌入式应用场景。

table的专栏 370

Origin作图——等高线图

最近做一个测试数据图,开始想通过用热图来展示,结果发现热图有很多的小方块,很难呈现出最好的效果,因为数据是有一层一层的递进效果,因此经过尝试后,发现等高线图是个好选择。 热图展示效果如下:其中有很多的小方块不适合,热图制图方法前面有记录。 下面展示等高线图制作方法。首先是导入数据,可以从excal导入,也可以直接复制进去。等方法。 选中要展示的数据,绘图----等高线图 选中箭头,确定。 双击图像,点击线,我们需要把线隐藏了. 双击图像,我们需要调色板,根据自己的选择,一般用调色板的颜色。

qq_42278015的博客 1万+

结构体中数组的赋值问题

我在给结构体中的数组赋值的时候显示,左操作数不能作为左值。左值就是变量,那么也就是说结构体里面的数组是一个常量而不是变量。那么怎么解决这个问题? typedef struct student { char name[20]; int age; } int main() { student s; s.name = "gay"; // 错误代码 } 为什么会出现这种现象哪?先看这一种现象: char[20] name; name = "gay"; 上面这段代码

jerry的博客 4759

VC Spyglass CDC验证避坑指南:如何正确配置同步复位信号(实验二重点解析)

本文深入解析VC Spyglass CDC验证中同步复位信号的正确配置方法,通过实验二案例详细展示错误配置的典型表现及修正过程。文章提供同步复位的最佳实践方案,包括约束文件修改指南、验证流程优化建议和高级调试技巧,帮助工程师有效避免CDC验证中的常见陷阱。

rock5的博客 678

数组之间不能直接赋值,为什么?赋值有四种方法

数组和数组之间能直接赋值吗?——不能 你难道是想 a=b?? 首先你要明白: 数组名a,b代表指针常量,所以说赋值号左边必须是一个变量 a=b; 根本就是错误的 注意:数组名是常量,指针一般都是变量,当然也可以是常量。查看:https://blog.youkuaiyun.com/cyj2014go/article/details/78203404 法一: 当然你的想法也有可取之处,取地址运算,把数...

Hello,小高同学 3万+

WPF实战:利用Live Charts实现高性能动态曲线可视化

本文详细介绍了如何在WPF中使用Live Charts实现高性能动态曲线可视化,特别适用于工业监控和金融分析等实时数据场景。通过增量渲染、内存复用和硬件加速等核心技术,Live Charts能够高效处理高频数据更新,显著提升图表流畅度。文章提供了从基础实现到工业级优化的完整解决方案,帮助开发者应对各种性能挑战。

weixin_29189373的博客 407

【FISCO-BCOS】 八、ubuntu配置Java环境

ubuntu配置Java环境需根据自己的java版本号进行细节修改,本文以jdk11.0.18版本为例。ps:通过此法还可以查看java安装路径,但必须是环境配置成功的情况下才能使用。二、添加Java环境路径。四、检查java环境设置。

naihe_fish的博客 4309

结构体数组赋值的问题

C语言只有在定义字符数组的时候才能用“=”来初始化变量,其它情况下是不能直接用“=”来为字符数组赋值的,要为字符数组赋值可以用string.h头文件中的strcpy函数来完成。 例如: char a[10] = "123"; /*正确,在定义的时候初始化*/ char a[10]; a = "123"; /*错误,不能用“=”直接为字符数组赋值*/ strcpy(a, "123"); /*正确,...

ginwafts 3万+

大数据分析案例-基于决策树算法构建世界杯比赛预测模型

本项目旨在分析往届世界杯比赛数据,找出规律,最后使用决策树算法构建世界杯比赛预测模型,给出两个球队即可预测胜率,可以给爱看球的小伙伴提供一个参考。本次实验我们使用了2018年及其之前的世界杯比赛数据,通过建立决策树模型,模型准确率为82%,接着我们使用该模型预测了2022年世界杯的5场半决赛及决赛,模型准确率也是接近80%的,说明模型效果还是很不错的。心得与体会:通过这次Python项目实战,我学到了许多新的知识,这是一个让我把书本上的理论知识运用于实践中的好机会。

m0_64336780的博客 1万+

字符数组可以初始化,不能赋值,能strcpy的原因

能初始化 不能赋值

weixin_41838721的博客 1158

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

结构体变量中数组成员赋值问题

#include using namespace std; struct student {   char name[20];   int age; }; int main( ) {  student s;  s.name="gyy";   //error  return 0; } 道理和以下语句错误的原因一样,数组名表示常量,不允许对常量赋值,所以常量不允许出现在

smallgyy的专栏 7976

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

1.C语言基础-给字符数组赋值

1.定义字符数组定义时直接初始化 定义字符数组定义时直接初始化,下面例子中直接将字符串123456的首地址赋值给a char a[6]=“123456”; 需要注意的是,在定义之后,不可以在对a数组使用字符串直接初始化,如下 char a[6]; a = "123456" a是一个静态数组,在C语言中其在编译期间为一个常量表达式,而常量表达式可以当做是常量来使用,所以不能对于a进行指针赋值操作,既然这样是错误的,这么对于字符数组进行赋值呢 2.字符数组单个字符的赋值操作 最简单的方法是通过for循环,使

weixin_43824344的博客 1万+

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

C语言基础知识:字符数组用字符串赋值

问题提出:char a[10]; 怎么给这个数组赋值呢? 字符数组用字符串赋值的三种可行形式: 1、定义的时候直接用字符串赋值 char a[10]="hello"; 【注意】不能先定义再给它赋值,如char a[10]; a[10]="hello";这样是错误的,一个字符怎么能容纳一个字符串?况且a[10]也是不存在的!再如char a[10]; a="hello";//这种情...

baidu_37973494的博客 5088

字符数组初始化

Q:不能把字符串"HELLO!"赋给数组b的语句是(B) A、char b[10]={'H','E','L','L','O','!','\0'}; B、char b[10];b="HELLO!"; C、char b[10];strcpy(b,"HELLO!"); D、char b[10]="HELLO!"; A:字符数组初始化有两...

weixin_30703911的博客 181

关于中字符串常量给字符数组赋值

【代码】关于中字符串常量给字符数组赋值。

我与我周旋久,宁作我 1093

在 C++ 中,只有字符数组(`char[]`)可以使用字面值常量进行初始化的原因

其他类型的数组,如整数数组(`int[]`)或浮点数数组(`float[]`),则不能直接使用字面值常量进行初始化。在 C++ 中,只有字符数组(`char[]`)可以使用字面值常量进行初始化,而其他类型的数组则不能直接使用字面值常量进行初始化。在这个例子中,你不能使用类似 `{1, 2, 3, 4, 5}` 的字面值常量来初始化 `num` 数组,因为整数数组的元素不是字符类型。总之,只有字符数组可以直接使用字面值常量进行初始化,其他类型的数组需要使用其他方法进行初始化。

Kegi_的博客 458

【C语言】字符数组与字符串

字符数组与字符串定义与初始化,赋值方式的异同讲解

m0_72594605的博客 621

C语言 | 结构体成员数组赋值的问题

C语言只有在定义字符数组的时候才能用“=”来初始化变量,其它情况下是不能直接用“=”来为字符数组赋值的,之所以不能赋值成功,是因为数组名是一个指针常量,指向固定地址,再对其赋值即改变其指向的地址,作为常量自然不同意。 要为字符数组赋值可以用string.h头文件中的strcpy函数来完成。 例如: char a[10] = "123"; /*正确,在定义的时候初始化*/ char a[10]; a = "123"; /*错误,不能用“=”直接为字符数组赋值*/ strcpy(a, "123"); /*.

"You are worthy! You can do it!" 3725

字符数值赋值问题

一个字符串,如"feiren",一般为字符串常量,可以用它对字符指针赋值,或初始化,相当于把这个字符串常量的首地址赋给这个指针,如: char *p = "feiren"; 或者 char *p; p="feiren"; 但是,当用"hello"给字符数组作初始化时,"hello",并非一个字符串常量,而是相当于一个初始化列表{'h','e','l','l','o','\0'},在其他...

flying_man_的博客 1239

22.字符串初始化方法及赋值,字符串和指针总结

字符串初始化方法及赋值,字符串和指针总结

GUDGET的博客 1077

iOS  日记2 --字符串赋值给指针与数组的区别

一个字符串,如"hello",一般为字符串常量,可以用它对字符指针赋值,或初始化,相当于把这个字符串常量的首地址赋给这个指针,如: char *p = "hello";  或者 char *p; p="hello"; 但是,当用"hello"给字符数组作初始化时,"hello",并非一个字符串常量,而是相当于一个初始化列表{'h','e','l','l','o','\

u014675492的博客 446

学习笔记 C语言 字符数组

数组中的字符数组和排序算法的相关知识点,以思维导图的形式呈现: 其中补充几点在思维导图中没有呈现出来的: 字符数组的引用: char a[7]; a[0]='C'; //直接给数组元素a[0]赋值 scanf("%c",&a[0]); //从键盘输入数据给数组元素a[0] printf("%c",a[0]); //输出数组元素a[0]的值 初始化: 字符型常量初始化: char a[8...

Lemonliyi的博客 444
上一篇: 如何防止函数内意外修改数组数据?
下一篇: 数组名是指针么?
AI发烧友
博客等级 码龄4年 266粉丝 92原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值