对不起,我是编程新手,所以我的描述可能不正确。我设计了一个使用linkedNode结构的类:
#include <iostream>
#include <ctime>
#include <ratio>
#include <chrono>
#include <array>
#include <omp.h>
int main() {
using namespace std::chrono;
const int big_number = 1000000000;
alignas(64) std::array<double, 6*8> array = { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 };
// Sequential
high_resolution_clock::time_point start_linear = high_resolution_clock::now();
for(int i = 0; i < 6; i++) {
for(int j = 0; j < big_number; j++) {
array[i]++;
}
}
high_resolution_clock::time_point end_linear = high_resolution_clock::now();
// Parallel
high_resolution_clock::time_point start_parallel = high_resolution_clock::now();
array = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
#pragma omp parallel
{
#pragma omp for
for(int i = 0; i < 6; i++) {
for(int j = 0; j < big_number; j++) {
array[i*8]++;
}
}
}
high_resolution_clock::time_point end_parallel = high_resolution_clock::now();
// Stats.
std::cout << omp_get_num_procs() << " processors used." << std::endl << std::endl;
duration<double> time_span = duration_cast<duration<double>>(end_linear - start_linear);
std::cout << "Linear action took: " << time_span.count() << " seconds." << std::endl << std::endl;
time_span = duration_cast<duration<double>>(end_parallel - start_parallel);
std::cout << "Parallel action took: " << time_span.count() << " seconds." << std::endl << std::endl;
return EXIT_SUCCESS;
}
和主要:
--no-ff
因此可以无限期地调用我的next(),但是我很好奇class test {
public int data,
public test next;
public test(int data){this.data = data;}
}
如何与public static void main(){
test t1 = new test(1), t2 = new test(2); //Line 1
t1.next = t2; //Line 2
t2.next = t1; //Line 3
t2 = null; //Line 4
Console.Write(t1.next.next.next.......data) // Line 5
}
连接?如果将t2
复制到t1.next
,则第3行将无法使其成为循环;如果t2
仅按地址链接,则第4行将中断循环。所以我很困惑代码后面会发生什么?
答案 0 :(得分:4)
实际上,您的结论都不正确。不会创建该对象的副本,但是第4行不会“破坏循环”。让我们分解一下:
test t1 = new test(1), t2 = new test(2); //Line 1
这将创建两个“测试”对象,并将它们的引用存储在局部变量中。由于它们每个都有一个标识它们的值(在此示例中不变),我们将它们称为“事物1”和“事物2”
t1.next = t2; //Line 2
好。现在,“事物1”的next
属性引用了“事物2”(从技术上讲,t2
的 value -对“事物2”的引用)被复制到{{ 1}})
t1.next
仍然很好。现在,“事物2”的t2.next = t1; //Line 3
属性引用了“事物1”(从技术上讲,next
的 value -对“事物1”的引用)被复制到{{ 1}})
t1
好。 变量 t2.next
现在什么也没有指向。此处的主要误解是 “事物2”没有任何变化 。仅WAS引用“事物2”的变量发生了变化。 “事物2”本身不受影响。它仍然具有引用“事物1”的t2 = null; //Line 4
属性。因此,“事物1”也不受影响。它具有一个引用“事物2”的t2
属性
next
next
引用“事物1”,其 Console.Write(t1.next.next.next.......data) // Line 5
属性引用“事物2”,其t1
属性引用“事物1”,其next
属性引用“事物” 2”等。因此,根据您呼叫next
的次数,结果将为next
或.next
。
我很好奇t2如何连接到t1.next?
直到第4行,它们都引用同一对象。然后,第4行会更改1
引用的内容(无),但不会更改2
的值。
答案 1 :(得分:1)
D Stanley的回答非常好,但是我想用更细粒度的步骤进行更真实的类比,这可能会帮助您继续前进。我将遍历代码的每个部分,并将其转换为此类比。我在构造函数中更改了参数名称,以使事情更清晰一些。
class test {
您创建了一个称为“测试”的制造说明,该说明应将什么包装在纸板箱中以及如何将其放入其中。
public int data,
将有一张纸条,纸条上将印有“数据”标签,该纸条上将有一个写在-2,147,483,648和2,147,483,647之间的数字点。纸张的默认值为0。
public test next;
另一张标有“下一张”的纸将放入包装盒中,这是一张特殊的纸,仅允许您在用来存放“测试”盒的架子上的位置书写。默认情况下,此位置将留空。
public test(int newData){this.data = newData;}
}
这是包装说明,说明说“我会给您一张标有“ newData”的纸条,上面有一个数字。您应在包装箱中的“ data”纸条上书写。我给你的单据“ newData”中的数字。完成后,就扔掉我最初给你的标有“ newData”的纸条。”
public static void main() -->{<--
你去上班。
test t1 = -->new test(1)<--
您去找供应商,订购一个“测试”盒,并给他们一张纸条,上面有1。他们把这箱子运到仓库。
--> test t1 =<-- new test(1), t2 = new test(2); //Line 1
您被告知您的盒子坐在架子0xAAAAAAAA上,您打印出那只特殊纸,只允许在上面写上带有标签“ t1”的架子编号,并在上面写上值0xAAAAAAAA。 / p>
test t1 = new test(1), -->t2 = new test(2);<-- //Line 1
您重复前面的两个步骤,但是这次给制造商一个2,标签为t2的纸条上写有0xBBBBBBBB。
-->t1.<--next = t2; //Line 2
转到“居所”,然后在框上找到名称与标签为t1(架子0xAAAAAAAA)的纸张上写的数字相匹配的架子。
t1-->.next = t2<--; //Line 2
打开该架子上的盒子,在纸条上写上“ next”,该数字是您在“ t2”纸上的编号(0xBBBBBBBB)。将“下一张”纸留在盒子中,然后用“ t2”纸回到办公室。
-->t2.<--next = t1; //Line 3
转到院子里的盒子里,架子名称与写在t2纸上的数字相匹配(架子0xBBBBBBBB)。
t2-->.next = t1<--; //Line 3
打开该架子上的盒子,在纸条上写上“ next”,该数字是您在“ t1”纸上的编号(0xAAAAAAAA)。将“下一张”纸留在盒子中,然后用“ t1”纸回到办公室。
t2 = null; //Line 4
抹掉标记为“ t2”的纸上的数字
Console.Write(-->t1.<--next.next.next.......data) // Line 5
转到院子里,找到上面有写在“ t1”(0xAAAAAAAA)上的数字的架子,然后找到上面的盒子。
Console.Write(t1.-->next.<--next.next.......data) // Line 5
在您当前位于(0xAAAAAAAA)的框中,阅读标有“下一页”的纸,然后找到编号为(0xBBBBBBBB)的书架
Console.Write(t1.next-->.next.<--next.......data) // Line 5
在您当前位于(0xBBBBBBBB)的框中,阅读标有“下一页”的纸,然后找到具有该数字(0xAAAAAAAA)的架子
Console.Write(t1.next.next-->.next.<--......data) // Line 5
在您当前位于(0xAAAAAAAA)的框中,阅读标有“下一页”的纸,然后找到编号为(0xBBBBBBBB)的书架
Console.Write(t1.next.next.next-->.......<--data) // Line 5
每次在读取0xAAAAAAAA和0xBBBBBBBB上的框之间来回跳动时,每次读取“ next”的值并转到纸张上写有该框的位置。
Console.Write(t1.next.next.next......-->.data<--) // Line 5
在您当前位于(?)的框中,阅读标有“数据”的纸
-->Console.Write(t1.next.next.next.......data)<-- // Line 5
将写在“数据”纸上的数字提供给“控制台”公司,并告诉他们您要他们“写”它。
}
你一天回家。
在盒子上写下原始值之后,您再也不会对其进行修改,只会删除您办公室里的那张纸的编号,因此擦除该编号不会影响阅读“下一张”在两个盒子里的纸。
以下是有关使用相同类比如何获取对象垃圾的一些小信息。
t2 = null; //Line 4
--><---
Console.Write(t1.next.next.next.......data) // Line 5
}
您将带有“ t2”标签的纸丢掉,因为在接下来的工作日中不会使用“ t2”。
t2 = null; //Line 4
Console.Write(t1.next.next.next......-->.data<--) // Line 5
--><---
}
您扔掉标有“ t1”的纸,因为在接下来的工作日中将不再使用它。
public static void main() -->{
test t1 = new test(1), t2 = new test(2); //Line 1
t1.next = t2; //Line 2
t2.next = t1; //Line 3
t2 = null; //Line 4
Console.Write(t1.next.next.next.......data) // Line 5
}<--
在一天中的某个时候,如果管理人员认为房屋太满了,他们会经过每个人的办公室,他们会发现所有纸条上都写有任何种类的仓库货架,并将这些货架标记为“已使用” ,然后他们转到那些用过的书架中的箱子,并在箱子内找到其他任何架子编号。他们重复此过程,直到所有可以标记为已使用的框都被标记为止。然后,他们扔掉了所有未标记的用于腾出空间的盒子。