C语言中字符数组赋值的三种方法及常见错误解析
1.定义时直接使用字符串赋值

字符 a[10]="你好";
注意:不能先定义再赋值,如char a[10]; a[10]="你好";这是错误的!
2.给数组中的字符一一赋值
char a[10]={'h','e','l','l','o'};
3.使用strcpy
字符a[10]; strcpy(a, "你好");
容易出错的情况:
1. 字符a[10]; a[10]="hello";//一个字符怎么能包含一个字符串呢?而且,a[10]并不存在!
2. 字符a[10]; a="hello";//这样的情况很容易出现。虽然a是一个指针,但它已经指向堆栈中分配的10个字符空间。现在在这种情况下,a 指向数据区域。 hello常量,这里的指针a让人困惑,我不同意!
另外:不能使用关系运算符“==”来比较两个字符串,只能使用strcmp()函数。
C语言运算符根本不能对字符串进行操作。在C语言中,字符串被视为数组。因此,字符串受到与数组相同的限制。特别是,它们不能使用 C 语言运算符进行复制和比较。
直接尝试复制或比较字符串将会失败。例如,假设 str1 和 str2 具有以下声明:
字符str1[10],str2[10];
无法使用 = 运算符将字符串复制到字符数组中:
str1 = "abc";/*** 错误 ***/
str2 = str1;/*** 错误 ***/
C 语言将这些语句解释为一个指针和另一个指针之间的(非法)赋值操作。但是,使用 = 初始化字符数组是合法的:
char str1[10] = "abc";
这是因为在声明中,= 不是赋值运算符。
尝试使用关系或相等运算符比较字符串是合法的,但不会产生预期的结果:
if (str1==str2) ... /*** 错误 ***/
该语句将 str1 和 str2 作为指针进行比较,而不是比较两个数组的内容。由于 str1 和 str2 具有不同的地址,因此表达式 str1 == str2 的值必须为 0。
动态数组定义使用:
数组到底应该有多大有时是未知的。所以我希望我能够有能力在执行过程中改变数组的大小。
动态数组可以随时更改大小。
通俗地说,静态数组就是定义数组时操作系统分配的空间,例如
整数a[10];
这意味着系统在定义的时候给你分配了10个int类型的空间。该空间可以被初始化,例如
int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
这样定义后,系统首先会分配10个int类型的存储空间,然后将大括号内的数字按顺序放入这10个空间中。你只要写下这句话,数组赋值操作就由系统完成。当然,是否初始化取决于您的需要。初始化不是强制操作。如果需要,您可以初始化它。如果您不愿意也没关系。我们继续上面的例子:
整数a[10];
这里定义了它,但没有初始化。这没有问题。以后可以自己给它赋值,例如
a[1] = 8;
a[5] = 3;
或者
for(int i = 0; i < 10; i++)
a[i] = i;
ETC。
对于动态数组,它们无法初始化,因为动态数组在定义时只是指针,例如
整数*a;
这里的变量a只是一个指向int类型的指针,而不是一个数组。动态分配一个包含10个int类型元素的数组,如下:
a = (int * ) malloc(10*sizeof(int));
很明显,指针a在定义的时候是不能被初始化的。例如,这样写是错误的:
int a = {1,2,3,4,5,6,7,8,9,10}; / 错误! */
由于a是一个只有4个字节的指针,因此没有可用的存储空间来存放需要初始化的变量。
在C语言编程中,当我们声明一个字符串数组时,经常需要将其初始化为空字符串。总结起来有以下三种方式:
(1) char str[10]="";(2) char str[10]={'\0'};(3) char str[10]; str[0]='\0';
第(1)(2)方法是将str数组的所有元素初始化为'\0',而(3)方法是仅将str数组的第一个元素初始化为'\0'。如果数组的大小非常大,那么前两种方法会造成很大的开销。
因此,除非必要(即当我们需要将str数组的所有元素初始化为0时),否则我们应该选择方法(3)来初始化字符串数组。
1. 基本问题
数组可以被初始化,即在定义时,使它们包含可以立即被程序使用的值。
例如,以下代码定义一个全局数组并使用一组斐波那契数对其进行初始化:
1 int iArray[10]={1, 1, 2, 3, 5, 8, 13, 21, 34, 55); //初始化
2 无效主函数()
3 {
4 //...
5}
初始化数组中的值的数量不能多于数组元素的数量,并且初始化数组中的值不能通过跳过逗号来省略。这在 C 中是允许的,但在 C++ 中不允许。
初始化值的数量可以小于数组元素的数量。当初始化值的个数小于数组元素个数时,前面的值按顺序初始化,后面的值初始化为0(全局或静态数组)或不确定值(局部)大批)。
2.初始化字符数组
初始化字符数组有两种方法,一种是:
字符数组[10]={"你好"};
另一种是:
char数组[10]={'h','e','l','l','\0'};
第一种方法更加通用。初始化时,系统自动用'\0'填充数组未填充的位置。另外,该方法中的大括号可以省略,可以表示为:
字符数组[10]=“你好”;
第二种方法一次初始化数组一个元素,就像整数数组一样。此方法常用于输入那些不易在键盘上生成的不可见字符。
例如,以下代码将值初始化为多个制表符:
char chArray[5]={'\t','\t','\t','\t','\0');
不要忘记在这里为最后一个“\0”分配空间。如果要初始化字符串“hello”,为其定义的数组必须至少有 6 个数组元素。
例如,以下代码初始化一个数组,但会导致不可预测的错误:
字符数组[5]=“你好”;
该代码不会导致编译错误,但很危险,因为它会覆盖数组空间之外的内存位置。
3.省略数组大小
初始化数组定义可以省略方括号中的数组大小。
例如,以下代码中的数组被定义为 5 个元素:
int a[]={2,4,6,8,10};
数组的大小必须在编译时已知。通常,声明数组时方括号内的数字决定数组的大小。当存在已初始化的数组定义并且省略方括号中的数组大小时,编译器会计算大括号之间的元素数量以找到数组的大小。
例如,以下代码会产生相同的结果:
静态 int a1[5]={1, 2, 3, 4, 5};
静态 int a2[]={1, 2, 3, 4, 5};
让编译器计算出初始化数组的大小有几个好处。它通常用于初始化一个数组,其元素数量在初始化期间就已确定,为程序员提供了修改元素数量的机会。
如何在不指定数组大小的情况下知道数组的大小? sizeof操作解决了这个问题。
1.字符数组的定义和初始化
理解字符数组的初始化最简单的方法就是将字符一一分配给数组中的每个元素。
char str[10]={ 'I',' ','a','m',' ','h','a','p','p','y'};
即对str[0]到str[9]这10个元素分别赋值10个字符。
如果大括号中提供的字符数大于数组的长度,则会被视为语法错误;如果小于数组的长度,则只有这些字符的数组中的第一个元素会被自动设置为空字符(即'\0')。 。
2. 字符数组和字符串
在C语言中,字符串被当作字符数组来处理。 (C++中没有)在实际应用中,人们关心的是有效字符串的长度而不是字符数组的长度。例如,定义一个字符数组长度为100,但实际有效字符只有40个。为了确定字符串的实际长度,C语言指定了一个“字符串结束标志”,用字符'\0'表示。如果有一个字符串,第10个字符是'\0',那么这个字符串的有效字符是9个。也就是说,当遇到第一个字符'\0'时,就表示字符串结束,和它前面的字符组成一个字符串。
系统对字符串常量也自动加一个'\0'作为结束符。例如"C Program”共有9个字符,但在内存中占10个字节,最后一个字节'\0'是系统自动加上的。(通过sizeof()函数可验证)
有了结束标志'\0'后,字符数组的长度就显得不那么重要了,在程序中往往依靠检测'\0'的位置来判定字符串是否结束,而不是根据数组的长度来决定字符串长度。当然,在定义字符数组时应估计实际字符串长度,保证数组长度始终大于字符串实际长度。(在实际字符串定义中,常常并不指定数组长度,如char str[ ])说明:'\0代表ASCII 码为0的字符,从ASCII 码表中可以查到ASCII 码为0的字符不是一个可以显示的字符,而是一个“空操作符”,即它什么也不干。用它来作为字符串结束标志不会产生附加的操作或增加有效字符,只起一个供辨别的标志。
对C 语言处理字符串的方法由以上的了解后,再对字符数组初始化的方法补充一种方法——即可以用字符串常量来初始化字符数组:
char str[ ]={"我很高兴"};
花括号可以省略,如下所示
char str[ ]="我很高兴";
注意:上面提到的字符数组整体赋值只能在字符数组初始化时使用,不能用于字符数组的赋值。字符数组的赋值只能为其元素一一赋值。下面的赋值方法是错误的。
字符str[];
str="I am happy";//错误,字符数组的赋值只能对元素进行一一赋值
不要使用单个字符作为初始值,而是使用字符串(注意:字符串两端用双引号“”括起来,而不是单引号'')作为初始值。显然,这种方法更加直观、方便。 (注意:数组str的长度不是10,而是11。请记住这一点,因为系统会自动在字符串常量“I am happy”的末尾添加一个'\0')
因此,上面的初始化等价于下面的初始化
char str[ ]={'I',' ','a','m',' ','h','a','p','p','y','\0'};
而不是等价于以下
char str[ ]={'I',' ','a','m',' ','h','a','p','p','y'};
前者的长度为11,后者的长度为10。
注意:字符数组不要求最后一个字符是'\0',甚至可以不包含'\0'。这样写是完全合法的。
char str[5]={'C','h','i','n','a'};
可以看到,使用两种不同的方法初始化字符数组后得到的数组长度是不同的。
包括
无效主(无效)
char c1[]={'I','','a','m','','h','a','p','p','y'};
char c2[]="我很高兴";
int i1=sizeof(c1);
int i2=sizeof(c2);
printf("%d\n",i1);
printf("%d\n",i2);
结果:10 11
3. 字符串的表示
在C语言中,字符串可以用两种方式表示和存储:
(1)使用字符数组存储字符串
char str[ ]="我爱中国";
(2) 使用字符指针指向字符串
char* str="我爱中国";
对于第二种表示方法,有人认为str是字符串变量,认为定义时直接将字符串常量“我爱中国”赋值给字符串变量,这是错误的。 C 语言将字符串常量作为字符数组处理。在内存中开辟一个字符数组来存储字符串常量。程序在定义字符串指针变量str时,只是改变了字符串的首地址(即存储字符串的字符)。数组的首地址)被分配给str。
字符串输出的两种表示形式都使用
printf("%s\n",str);
%s表示输出一个字符串,并赋予字符指针变量名str(对于第一种表示方法,字符数组名就是字符数组的首地址,与第二种方法中指针的含义一致),则系统首先输出它指向的字符数据,然后自动将str加1指向下一个字符,以此类推,直到遇到字符串标识符“\0”结尾。
4.使用字符指针变量和字符数组表示字符串的讨论
虽然字符数组和字符指针变量都可以用来存储和操作字符串,但是它们之间是有区别的,不应该混淆。
4.1.字符数组由若干个元素组成,每个元素存储一个字符;而字符指针变量存储的是地址(字符串/字符数组的首地址),而不是字符串放在字符指针变量中(是String首地址)
4.2.分配方法:
您只能为字符数组的各个元素赋值。不能使用以下方法给字符数组赋值。
字符str[14];
str="我爱中国"; //错误,不是初始化,这是赋值,只能一一进行。
(但初始化字符数组时可以使用,即char str[14]="I love China";)
对于字符指针变量,使用以下方法赋值:
字符*a;
a="我爱中国";//指针赋值,是
或者 char* a="我爱中国";两个都很好
4.3.将初始值赋给字符指针变量(初始化):
char* a="我爱中国";
相当于:
字符*a;
a=“我爱中国”;
用于字符数组的初始化
char str[14]="我爱中国";
不等于:
字符str[14];
str="我爱中国"; (这不是初始化,而是赋值,而且像这样给数组赋值是错误的)
4.4.如果定义了字符数组,它就有一定的内存地址,并且不能被多次赋值。字符指针变量定义时并不指向某个字符数据,可以多次赋值。
5.字符串处理函数
5.1 字符串连接
char *strcat(char *str1,const char *2);
char *strcat(char *strDestination,const char *strSource );
功能:该函数将字符串str2连接到str1的末尾,并返回指针str1
注意:前两个要连接的字符串末尾有一个'\0'。连接时,去掉字符串1后面的'\0',只留下新字符串末尾的'\0'。
5.2 字符串复制
char *strcpy(char *str1,const char *2);
char *strcpy(char *strDestination,const char *strSource );
功能:将字符串strSource中的字符复制到字符串strDestination中,包括空终止符。返回值是指针strDestination。
笔记:
1、“字符数组1”必须写成数组名形式,“字符串2"可以是字符数组名,也可以是一个字符串常量
2、复制时连同字符串后面的' \0 ' 一起复制到数组1中
3、不能用赋值语句直接将一个字符串常量或者字符数组直接赋给一个字符数组(同普通变量数组是一样的),而只能用strcpy 函数处理。
4、可以用strcpy 函数将字符串2中的前若干个字符复制到字符数组1中去。相关文章
猜你喜欢
-
编程语言超600种各有特点,莫盲目跟风,如Python近年突然火爆
编程语言的种类繁多,已超过六百种,每种语言都有其独特的特性,它们根据社会生产的不同需求被选用。若全球都统一使用一种语言,岂不是更为便捷?然而,汇编语言作为低级语言,...
-
C语言5个实用技能之指定初始化与数组相关知识抓紧学
C语言5个实用的技能抓紧学习 一、指定的初始化 很多人都知道像这样来静态地初始化数组: int fibsl] = [1,1, 2, 3, 5); C99标准实际上提...
-
2021年4月16日更新:C语言课程设计目的、基本要求及实例代码介绍
C语言不用链表完成学生管理系统(完整代码) 更新时间为2021年4月16日,15时23分00秒,作者是Waterpaddler 。 这篇文章主要介绍了C语言完成学生...
-
C语言动态内存分配详解:深入剖析malloc、calloc、realloc函数
C语言动态内存分配详细解析:malloc、calloc、realloc 在C语言里,动态内存分配是一种关键的内存管理方式。它能让程序在运行之际请求以及释放内存。这给...
-
贤弟带你简单了解堆排序算法及其原理
大家好,我是贤弟!本文对堆排序算法作简要介绍。堆排序是最常用的算法之一。冒泡排序也是最常用的算法之一。 一、什么是堆排序算法? 堆排序算法是一种基于二叉堆数据结构的...

请小编喝杯咖啡吧!