在Go中,有多种方法可以返回其struct值或片.对于我见过的个人:
type MyStruct struct {
Val int
}
func myfunc() MyStruct {
return MyStruct{Val: 1}
}
func myfunc() *MyStruct {
return &MyStruct{}
}
func myfunc(s *MyStruct) {
s.Val = 1
}
Run Code Online (Sandbox Code Playgroud)
我理解这些之间的差异.第一个返回结构的副本,第二个返回指向函数内创建的结构值的指针,第三个期望传入现有结构并覆盖该值.
我已经看到所有这些模式都在各种环境中使用,我想知道关于这些模式的最佳实践是什么.你什么时候用哪个?例如,第一个可能适用于小结构(因为开销很小),第二个适用于较大结构.第三个是你想要非常高效的内存,因为你可以在调用之间轻松地重用一个struct实例.有什么时候使用哪种最佳做法?
同样,关于切片的相同问题:
func myfunc() []MyStruct {
return []MyStruct{ MyStruct{Val: 1} }
}
func myfunc() []*MyStruct {
return []MyStruct{ &MyStruct{Val: 1} }
}
func myfunc(s *[]MyStruct) {
*s = []MyStruct{ MyStruct{Val: 1} }
}
func myfunc(s *[]*MyStruct) {
*s = []MyStruct{ &MyStruct{Val: 1} }
}
Run Code Online (Sandbox Code Playgroud)
再说一次:这里的最佳做法是什么.我知道切片总是指针,所以返回指向切片的指针是没用的.但是,如果我返回一片struct值,一块指向结构的指针,我应该将指向切片的指针作为参数传入(Go …
我有一个函数,我想作为一个参数,一个可变大小的2D数组.
到目前为止我有这个:
void myFunction(double** myArray){
myArray[x][y] = 5;
etc...
}
Run Code Online (Sandbox Code Playgroud)
我在代码中的其他地方声明了一个数组:
double anArray[10][10];
Run Code Online (Sandbox Code Playgroud)
但是,调用myFunction(anArray)给了我一个错误.
当我传入数组时,我不想复制数组.所做的任何更改都myFunction应该改变数据的状态anArray.如果我理解正确,我只想作为参数传入指向2D数组的指针.该函数还需要接受不同大小的数组.例如,[10][10]和[5][5].我怎样才能做到这一点?
首先,这里是一些代码:
int main()
{
int days[] = {1,2,3,4,5};
int *ptr = days;
printf("%u\n", sizeof(days));
printf("%u\n", sizeof(ptr));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法找出ptr指向的数组的大小(而不是仅仅给出它的大小,在32位系统上是4个字节)?
在C中,似乎有零各个值之间的差- NULL,NUL和0.
我知道ASCII字符的'0'计算结果为48或0x30.
该NULL指针通常定义为:
#define NULL 0
Run Code Online (Sandbox Code Playgroud)
要么
#define NULL (void *)0
Run Code Online (Sandbox Code Playgroud)
另外,也有似乎评价的NUL人物.'\0'0
是否有时候这三个值不相等?
这在64位系统上也是如此吗?
删除NULL指针是否安全?
它是一种很好的编码风格吗?
我刚开始用指针,我有点困惑.我知道&一个变量的地址,它*可以在指针变量前面使用,以获取指针指向的对象的值.但是当您使用数组,字符串或使用变量的指针副本调用函数时,情况会有所不同.在所有这些内部很难看到逻辑模式.
什么时候应该使用&和*?
我一直在使用C++,我一直在想新的关键字.简单地说,我应该使用它吗?
1)使用新关键字...
MyClass* myClass = new MyClass();
myClass->MyField = "Hello world!";
Run Code Online (Sandbox Code Playgroud)
2)没有新的关键字......
MyClass myClass;
myClass.MyField = "Hello world!";
Run Code Online (Sandbox Code Playgroud)
从实现的角度来看,它们看起来并没有什么不同(但我确定它们是......)但是,我的主要语言是C#,当然第一种方法就是我习惯的方法.
困难似乎是方法1更难用于std C++类.
我应该使用哪种方法?
我最近使用new关键字作为堆内存(或免费存储)用于超出范围的大型数组(即从函数返回).在我使用堆栈之前,导致一半的元素在范围之外被破坏,切换到堆使用确保元素是完整的.好极了!
我的一位朋友最近告诉我,使用new关键字有一个简单的规则; 每次打字new,输入delete.
Foobar *foobar = new Foobar();
delete foobar; // TODO: Move this to the right place.
Run Code Online (Sandbox Code Playgroud)
这有助于防止内存泄漏,因为您总是必须将删除放在某处(即,当您将其剪切并粘贴到析构函数或其他方式时).
有什么区别:
char * const
Run Code Online (Sandbox Code Playgroud)
和
const char *
Run Code Online (Sandbox Code Playgroud) dot(.)运算符用于访问结构的成员,而->C中的箭头运算符()用于访问由有问题的指针引用的结构的成员.
指针本身没有任何可以使用点运算符访问的成员(它实际上只是一个描述虚拟内存中位置的数字,因此它没有任何成员).因此,如果我们只是将点运算符定义为在指针上使用指针(编译时afaik编译器已知的信息)时自动取消引用指针,则不会产生歧义.
那么为什么语言创建者决定通过添加这个看似不必要的运算符来使事情变得更复杂?什么是重大的设计决定?
在给函数提供原始变量时,最好的做法是:
unsigned long x = 4;
void func1(unsigned long& val) {
val = 5;
}
func1(x);
Run Code Online (Sandbox Code Playgroud)
要么:
void func2(unsigned long* val) {
*val = 5;
}
func2(&x);
Run Code Online (Sandbox Code Playgroud)
IOW:有没有理由选择一个而不是另一个?
pointers ×10
c ×5
c++ ×4
arrays ×2
reference ×2
const ×1
dereference ×1
go ×1
keyword ×1
new-operator ×1
null ×1
null-pointer ×1
sizeof ×1
variables ×1