[这是一个受到其他地方最近讨论的启发的问题,我会用它来提供答案.]
我想知道数组"衰减"指针的奇怪C现象,例如当用作函数参数时.这似乎是不安全的.用它明确地传递长度也是不方便的.我可以通过其他类型的聚合 - 结构 - 完全符合价值; 结构不会腐烂.
这个设计决定背后的理由是什么?它如何与语言集成?为什么结构有区别?
我知道在C中我可以做到以下几点.
int test[5] = {1, 2, 3, 4, 5};
Run Code Online (Sandbox Code Playgroud)
现在,这在声明数组时才合法.但是我想知道为什么以后这样做不合法?但是后来在该计划中,执行以下操作是不合法的.
test[5] = {10, 20, 30, 40, 50};
Run Code Online (Sandbox Code Playgroud)
或类似的东西.为什么是这样?我知道这不合法,我不是在抱怨,但有人可以给我一个更技术性的解释,说明为什么我不能这样做?(即不要只说C规范不允许它或类似的东西)
我假设它必须对内存在数组的堆栈上分配的时间做一些事情,所以在那一点C可以自动填充我的值,但那么为什么它不能在以后呢?
多谢你们
我问过的结构类似的问题在这里,但我试图找出ç如何处理像变量赋值的东西,为什么不允许将它们分配到海誓山盟,如果他们在功能上是相同的.
可以说我有两个数组:
int x[10];
int y[10];
Run Code Online (Sandbox Code Playgroud)
为什么x = y不能编译?如果它们都是相同的"签名",那么你不应该来回分配它们吗?
我是否可以通过允许我在C中执行此操作的方式声明这些内容?你能够做到这一点对我有意义,但也许有办法可以做到这一点?结构的Typedef似乎是解决方案,它对于数组声明和赋值是否相同?
我感谢你们的帮助,我是Stackoverflow的新手,但到目前为止它对我来说是一个非常好的资源!
可以将结构分配给另一个,这会导致将所有值从struct复制到另一个:
struct
{
int a, b, c;
} a, b;
...
a = b;
Run Code Online (Sandbox Code Playgroud)
但为什么数组不能像这样分配:
int a[3], b[3];
...
a = b;
Run Code Online (Sandbox Code Playgroud)
因为,严格来说,结构只是具有可变大小元素的数组,那么为什么不允许这样呢?无论如何,这种任务尚未使用.当然,似乎只涉及地址,但可以轻松地复制数组("静态").
可以使用所谓的初始化列表来初始化数组。
例如:
int my_array[3] = {10, 20, 30};
Run Code Online (Sandbox Code Playgroud)
当我们为数组设置一组初始值时,这非常有用。但是,这种方法一旦声明就无法为数组分配新值。
my_array = {10, 20, 30};
error: assigning to an array from an initializer list
Run Code Online (Sandbox Code Playgroud)
但是,有时我们有一些过程需要将数组初始化为一些初始值(例如,在循环内),因此我认为能够使用初始化列表将值分配给已声明的变量将非常有用。
我的问题是:是否有理由在声明时拥有这种功能,但一旦声明数组就没有?为什么在一种情况下有效,而在另一种情况下无效?
我得到了一个让我困惑的作业问题.问题是:
在C++中,等式测试==可以应用于数组,但赋值运算符=不能应用于数组.解释为什么.
这让我很困惑,因为我的理解是==操作员只是比较前两个元素的地址(如果两个数组实际上保存在不同的存储器位置,当然会有所不同).并且=运算符在使用时array1 = array2;会使array1指向与array2相同的内存位置.
我在这里错过了什么?似乎可以使用任一运算符,但两者都不会产生通常由这些运算符预期的结果.
我想知道为什么不能在C中返回数组?毕竟,数组只是一个由大小信息支持的指针(以便sizeof工作).首先我认为这是为了防止我返回我的堆栈上定义的数组,但没有什么能阻止我将指针返回到我的堆栈上的东西(gcc警告我,但代码编译).而且我也可以返回字符串文字,这是静态存储的字符数组.顺便说一句,在lunux中存储它.rodata,并且const数组也存储在那里(检查它objdump),所以我可以返回数组(将它转换为指针)并且它可以工作,但是AFAIK这只是特定于实现的(另一个操作系统) /编译器可以在堆栈上存储const).
我有2个想法如何实现数组返回:只需将其复制为值(就像它为结构所做的那样.我甚至可以将数据包装到结构中!!),并自动创建指针或允许用户返回const数组和创建这样的数组应具有静态存储持续时间的合同(就像它对字符串所做的那样).这两个想法都是微不足道的!所以,我的问题是为什么K&R没有实现类似的东西?
好.我们知道以下代码无法编译.
char source[1024];
char dest[1024];
// Fail. Use memcpy(dest, source, sizeof(source)); instead.
dest = source;
Run Code Online (Sandbox Code Playgroud)
但是,以下代码可以编译并且行为正确.
class A {
char data[1024];
};
A source;
B dest;
dest = source;
Run Code Online (Sandbox Code Playgroud)
我想知道,在运算符赋值函数中,数组将是隐式的memcpy吗?
以下是完整的测试代码.
#include <cstdio>
#include <memory>
class A {
public:
char data[1024];
};
int main() {
{
A source;
A dest;
// Initialization
char *data = "hello world";
memcpy (source.data, data, strlen(data) + 1);
printf ("source.data = %s\n", source.data);
printf ("address source.data = %x\n", source.data);
// Works! Does this in the …Run Code Online (Sandbox Code Playgroud) 在关于C的介绍性书籍中,经常声称指针或多或少是数组.充其量只是一个巨大的简化吗?
存在是 C中的数组类型,它可以表现从指针完全不同的,例如:
#include <stdio.h>
int main(int argc, char *argv[]){
int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int *b = a;
printf("sizeof(a) = %lu\n", sizeof(a));
printf("sizeof(b) = %lu\n", sizeof(b));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
给出输出
sizeof(a) = 40
sizeof(b) = 8
Run Code Online (Sandbox Code Playgroud)
或者作为另一个例子a = b会产生编译错误(GCC:"赋值给带数组类型的表达式").
当然,指针和数组之间存在密切关系,在某种意义上,数组变量本身的内容是第一个数组元素的内存地址,例如int a[10] = {777, 1, 2, 3, 4, 5, 6, 7, 8, 9}; printf("a = %ul\n", a);打印包含777的地址.
现在,一方面,如果你在结构中"隐藏"数组,只需使用=运算符就可以轻松复制大量数据(数组,如果忽略包装结构)(这甚至也很快):
#include …Run Code Online (Sandbox Code Playgroud) 假设我有一个包含std :: string的结构,如下所示:
struct userdata{
int uid;
std::string username;
}
Run Code Online (Sandbox Code Playgroud)
我是否需要创建一个复制ctor或任何东西来从函数返回它或在STL容器中使用它?考虑这个功能:
userdata SomeClass::GetUserData(unsigned int uid)
{
//do error checking and other stuff...
//m_usermap is std::map<unsigned int, userdata>
return m_usermap[uid];
}
Run Code Online (Sandbox Code Playgroud)
当我将用户数据结构插入到std :: map中时,会创建一个struct的副本,对吧?是否使用username字段的值创建了新的std :: string,或者是否发生了某种按位复制(这会很糟糕)?类似地,当我从GetUserData方法返回userdata结构时,它是否有一个包含用户名的独立字符串,还是我需要定义一个copy ctor并显式创建一个新字符串?
为什么以下作业不起作用?如果可能的话,我想要一个低级的解释。另外,这是我得到的编译器错误:'char*' 到 'char [20]' 赋值中的类型不兼容
class UCSDStudent {
char name[20];
public:
UCSDStudent( char name[] ) {
//this-> name = name; does not work! Please explain why not
strcopy( this -> copy, copy ); //works
}
};
Run Code Online (Sandbox Code Playgroud) 这是我面临的一个奇怪的问题 - 考虑到我生锈的C++技能,可能是超基本的东西,但我仍然感到困惑:
unsigned long long在这堂课中也有一系列的- 让我们称之为arr我的班级界面:
typedef unsigned long long U64;
class DQClass
{
public:
DQClass (void);
virtual ~DQClass (void);
U64 arr[12];
};
Run Code Online (Sandbox Code Playgroud)
现在至于实施......
测试1(这是有效的):
DQClass::DQClass (void)
{
this->arr[0] = 0x8100000000000000ULL;
this->arr[1] = 0x4200000000000000ULL;
// and so on..
}
Run Code Online (Sandbox Code Playgroud)
测试2(这不):
DQClass::DQClass (void)
{
this->arr =
{
0x8100000000000000ULL,
0x4200000000000000ULL,
0x2400000000000000ULL,
0x1000000000000000ULL,
0x0800000000000000ULL,
0x00FF000000000000ULL,
FLIPV(0x8100000000000000ULL),
FLIPV(0x4200000000000000ULL),
FLIPV(0x2400000000000000ULL),
FLIPV(0x1000000000000000ULL),
FLIPV(0x0800000000000000ULL),
FLIPV(0x00FF000000000000ULL)
};
}
Run Code Online (Sandbox Code Playgroud)
错误:
dqclass.cpp: In constructor ‘DQClass::DQClass()’:
dqclass.cpp:28: error: expected primary-expression before ‘{’ token
dqclass.cpp:28: error: …Run Code Online (Sandbox Code Playgroud) arrays ×10
c ×7
c++ ×7
pointers ×3
struct ×2
char-pointer ×1
constructor ×1
gcc ×1
operators ×1
stl ×1