为什么第 16 数制的 1 位对应第 2 数制的 4 位?如果我可以这样说,你能否给出一个“数学”,这件事的理由。
n 1 k z z z's questions
消息来源说модель плоской памяти - парадигма, в которой память представляется программе как единое непрерывное адресное пространство. ЦП может напрямую (и линейно) адресовать все доступные без необходимости прибегать к каким-либо видам схемы сегментации памяти или подкачки
。听说现在到处都在使用这样的内存模型,但是程序内存怎么还分成代码段、数据段等等,还有页呢?如果程序是分段的,那是不是意味着我正在使用 分段内存模型?还有平面内存模型与虚拟内存有什么关系,难道不是一回事吗?或者,例如,一个是另一个的实现?
以 Windows 为例。我知道这个操作系统使用分页内存。但是数据段、代码段、堆段等概念,仍然适用于在这个OS下运行的程序,是这样吗?我是否正确理解这些不是x86 机器上的段?那么如何对它们进行寻址呢?
我有一个问题,为什么入口点WinApi
必须有一个调用约定__stdcall
?我知道使用不同的调用约定,堆栈的管理方式不同,函数有不同的标识符,但我还是不明白为什么会这样?这条规则的技术原因是什么(如果有的话)?提前感谢您的回复:)
有一个这样的示例代码:
typedef int* iter;
typedef const int* c_iter;
int arr[]{1, 2, 3, 4};
iter arrbegin()
{ return arr; }
int main()
{
const auto it = arrbegin();
it++;
return 0;
}
它会引发错误(更改常量数据),但我有点困惑。据我了解,此代码等效于:
const iter it = arrbegin ();
但它const iter
不是等价的iter_const
吗?根据经验,我已经明白不是,但我不清楚:为什么不呢?
有这个代码:
class Test
{
public:
void foo()
{}
void foo();
};
你怎么理解它会引发错误,但我不明白为什么?我查看了关于声明类成员的标准,但没有发现任何可以禁止这样做的东西。为什么这段代码不起作用?
今天我写了一个处理内存的类,我需要在其中使用另一个嵌套类。主类有一个方法可以返回这个嵌套类的对象:
class Main
{
private:
class Inner
{
};
public:
Inner foo()
{ return {}; }
};
然后我这样做了:
Main m;
auto a = m.foo();
它奏效了。但是你不能直接创建这样的对象,因为嵌套类是私有的:
Main::Inner a; //ошибка
老实说,我有点困惑,我感兴趣的是这是一个缺陷还是它是故意的(直到现在我还没有在任何地方看到这个)。
抱歉这个可能很愚蠢的问题,但我不明白这是如何工作的。假设我们有一个 x86 处理器并且我们跳转到某个地址。据我所知,这条指令在内存中占用 5 个字节。jmp(1 个字节)+ 地址(4 个字节)。但是我不明白处理器是如何读取这条指令的,因为 x86 的寄存器大小是 4 个字节,而我们的指令大小是 5 个字节。事实证明,处理器需要 2 个周期来读取这条指令,因为它不完全适合寄存器。我知道这很可能不是这种情况,但我不明白它是如何工作的。你能告诉我什么是什么。提前致谢 :)
我会马上说我的问题很可能是这个问题的重复。但我不会问我是否理解了一切。
我感兴趣的第一件事是处理器一次可以读取多少数据?据我了解,处理器读取的数据大小等于其机器字的大小,例如 32 位。也就是说,即使处理器只需要读取 8 位信息,它仍然会读取 32 位,但它只会使用它需要的 8 位。我理解正确吗?
但是出现了另一个问题,许多人说处理器在处理位于不是其机器字大小倍数的地址的数据时效果很差。也就是说,假设一个机器字的大小为 4 个字节,那么为什么处理器不能读取位于该地址的数据0x5
呢?我查看了很多与我的问题相关的网站和文章,但很多人只是说这不可能,但他们没有说出原因。
我听到的唯一一件事是 SSE 指令,它们不适用于此类地址。处理器的这种行为还有其他原因吗?
在研究函数调用约定 ( __stdcall
, __cdecl
) 时,我发现函数参数是从右到左传递到堆栈的。为什么参数是从右到左传递而没有别的(除了__fastcall
and __vectorcall
)。这种现象有什么解释吗?
它是如何工作的变得非常有趣std:: initializer_list
。我们可以将任意数量的参数传递给它的构造函数是如何实现的。我查看了它的实现,但构造函数只有 2 个参数,我们可以在那里传递更多参数。那么它是如何工作的,我该怎么做呢?
在本例中,未初始化数据部分 (bss) 中将存储什么?
int a;
int arr[20];
int main(){}
我将尝试表达我的建议:а
它将被初始化为零,因为它具有静态存储持续时间并且会落入data
段中。但是数组呢,它会在哪里呢?
我使用 curl 连接到一些服务器,然后该服务器发送一些我需要接收和输出的响应。我有以下代码,理论上应该执行上述功能:
void listen(CURL* curl)
{
char buf[1024];
size_t num;
curl_easy_recv(curl, buf, sizeof buf, &num);
std::cout << buf;
}
int main()
{
CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
curl_easy_perform(curl);
while (true)
listen(curl);
}
但是此代码仅输出从服务器接收到的第一个响应,仅此而已,没有其他任何事情发生,即使其他响应来自服务器,控制台上也不会显示任何内容,尽管它应该。告诉我我做错了什么以及如何解决?
我有一个关于继承如何工作的问题。当我们从彼此继承类时,一个类可以访问另一个类的成员,但这非常简单。我对继承中发生的事情的更精确定义感兴趣。现在让我解释一下是什么促使我产生了这个想法。有2个类:
class Parent
{
};
class Child : public Parent
{
public:
void say()
{
cout << "I am child";
}
};
现在,我感兴趣的最重要的事情:
int main()
{
Parent variable = Child();
}
为什么这个条目有效并且一切都编译得很好?现在还有一点,如果我尝试这样做:
variable.say();
然后什么都对我不起作用,虽然看起来variable
类的对象就在里面Child
,而且Child
它有一个方法say
,但是我不能调用它,怎么会呢?请解释当一个类从另一个类继承时会发生什么,显然父类的成员不只是简单地复制到继承类,但是这种情况以某种不同的方式发生,如何?
大家好。我目前正在学习virtual
函数,我有一个问题。我有 2 节课:
class Parent
{
public:
void say()
{
cout << "I am Parent" << endl;
}
};
class Child : public Parent
{
void say()
{
cout << "I am Child" << endl;
}
};
现在我会这样做:
int main()
{
Parent* pParent = new Child ();
pParent->say();
}
我得到以下输出:
I am Parent
那么问题来了:为什么要调用父类的函数,根据所有逻辑,什么时候应该调用继承类的函数。编译器没有真正看到->
我们正在调用继承类的方法,其对象位于指针旁边。是的,我知道有办法解决这个问题virtual
。但是这一切是为了什么?
我想完成一些工作typedef
。定义说它是我们指定的类型的同义词。我有一个问题:它是怎么回事 - 同义词?好吧,也就是说,声明typedef int my_int
会有些等价#define my_int int
,只有 typedef 声明有自己的范围。并且在编译my_int
时将替换为int
? 它是如何工作的?
大家好。最近我对 std::end 的工作原理产生了兴趣,当我去查看实现时,我在那里看到了类似这样的代码(我现在看不到它):
template<typename T, size_t sz> constexpr end( T (&arr)[sz])
{
return arr+sz;
}
据我了解sz
,它负责数组的大小,但由于某种原因,它绝对不是一个普通的变量,而是以某种方式在模板中。模板中定义的这个神奇的“变量”是什么?它的用途是什么?