在C/CPP/C++中,字符数组大小是动态的



到目前为止,我所知道的是C和CPP/C++中的数组具有固定的大小。然而,最近我遇到了两段似乎与这一事实相矛盾的代码。我把照片附在这里。想听听每个人对这些工作原理的看法。也粘贴代码和疑虑在这里:

1.

#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char str1[]="Good"; //size of str1 should be 5
char str2[]="Afternoon";  //size of str2 should be 10

cout<<"nSize of str1 before the copy: "<<sizeof(str1);
cout<<"nstr1: "<<str1;

strcpy(str1,str2);     //copying str1 into str2      

cout<<"nSize of str1 after the copy: "<<sizeof(str1);
cout<<"nstr1: "<<str1;
return 0;
}

your textO/P:复制前str1的大小:5str1:好复制后str1的大小:5str1:下午

在第一个片段中,我使用strcpy来复制char str2[]内容;下午";转换为大小比str2的大小小5的char str1[]。因此,理论上,线strcpy(str1,str2)应该给出误差,因为str1的大小小于str2的大小并且是固定的。但它会执行,更令人惊讶的是,即使在str1之后也包含单词";下午";大小仍然相同。

2.

#include <iostream>
#include <cstring>
using namespace std;
int main()  
{  
char first_string[10]; // declaration of char array variable  
char second_string[20]; // declaration of char array variable  
int i;  // integer variable declaration  

cout<<"Enter the first string: ";  
cin>>first_string;  
cout<<"nEnter the second string: ";  
cin>>second_string;  

for(i=0;first_string[i]!='';i++);   


for(int j=0;second_string[j]!='';j++)  
{  

first_string[i]=second_string[j];  
i++;  
}  
first_string[i]='';  
cout<<"After concatenation, the string would look like: "<<first_string;  
return 0;  
}

O/p:输入第一个字符串:良好

输入第二个字符串:下午

串联后,字符串看起来像:下午好

这里,即使我提供长度为20的字符串作为second_string[]的输入,它仍然能够连接这两个字符串并将它们放在firstrongtring]]中,即使连接的字符串的大小将明显大于firstrongtring[]的大小,即10。

我试图将长度较大的字符串分配给长度较小的字符串变量。从技术上讲,它不应该工作,但它无论如何都工作

有两个误解

  1. sizeof编译时的数组大小。它与数组的内容无关。您可以随心所欲地更改内容,sizeof将保持不变。如果需要字符串的长度,请使用函数strlen

  2. 大多数时候,当你违反C++的规则时,它会导致未定义的行为。将字符串复制到太小而无法容纳该字符串的数组中是未定义行为的一个示例。

你说

因此,从理论上讲,行strcpy(str1,str2)应该给出错误大小的大小小于str2的大小并且是固定的。

这是不真实的。未定义的行为并不意味着一定存在错误。它的意思正是它所说的,你的程序的行为是未定义的,任何事情都可能发生。这可能意味着一条错误消息,也可能意味着崩溃,或者可能意味着你的程序似乎可以工作。这种行为是不明确的。

你并不是唯一一个这样思考的人。我认为sizeof的目的和未定义行为的性质是初学者最常见的两个误解。

并回答标题中的问题。字符数组的大小在C++中是固定的,您的示例中没有任何内容与此相矛盾。

老实说,我从未见过C++程序员编写char stringname[20] = "string";,这不是用C处理字符串的方式++⁰.

C程序员也不会使用数组表示法,因为它并不常见;您通常会将数组用于非字符串的东西,即使"string literal"的类型实际上是char[length + 1]

超出数组末尾的访问只是一个bug。这是未定义的行为。缓冲区溢出。静态代码分析器,甚至可能是编译器,会告诉你这是一种致命的罪过。str*函数实际上对数组的大小一无所知,它们只看到指向第一个元素的指针,而数组实际上对它所包含的字符串的长度一无所知,该长度由终止的零字符的位置给定。你把两件事搞混了!

在C++中,您肯定会使用std::string类来读取cin,这正是为了避免缓冲区溢出的问题。

所以,老实说:如果你是C++初学者,现在可能会尝试忽略C字符串。它不是一种处理字符串数据的C++方式,而不是固定的字符串文字(即源代码中""之间的内容),而且据我所知,C方式的字符串处理实际上仍然是软件中可远程利用漏洞的主要原因。C++不是C,老实说,当涉及到处理字符串时,会更好。同时包含<string.h><iostreams>是一个非常可靠的指示,表明编程初学者可以接触到将C++视为扩展C的糟糕指南。但事实并非如此;这是一种非常不同的编程语言,具有一些深远的C兼容性,但你会也不应该混合这两种语言&作为一个初学者,学习一种语言已经够难的了。


⁰从技术上讲,它甚至感觉不对;C++中的字符串文字是const char指针,而在C中它只是char指针。C和C++不是同一种语言。

cco如果你觉得自己在向人们解释C++,有时又觉得无法向不是专业C程序员的人做出好的解释,Kate Gregory很好地解释了为什么教C教C++是一个非常糟糕的主意,我同意这一点,即使她过分强调了几点

最新更新