好吧,我想要一个像memset
but for 这样的函数struct
,以便它可以在某些或所有元素上使用,如下所示:
// create array of person data elements
struct {
unsigned char name[25];
unsigned char age;
unsigned int numberPhone;
} persons [256];
// the 256 people have the same name
memset(person, { "Mohammed", 0, 0 } ,sizeof(persons) / sizeof(persons[0]));
我可以使用for loop
,但我更喜欢使用memset
,因为在这种情况下它的性能更好for loop
。
9
最佳答案
3
您不能用于此。将内存区域中的std::memset
所有字节设置为相同的值:
void* memset( void* dest, int ch, std::size_t count );
将值复制
static_cast<unsigned char>(ch)
到 指向的对象的前 count 个字符中dest
。
如果所有 256 个对象都应使用相同的值进行初始化,则只需将其设置为默认值:
struct {
unsigned char name[25] = "Mohammed";
unsigned char age = 0;
unsigned int numberPhone = 0;
} persons [256];
不再需要其他东西了。
如果您不想要默认值,请创建一个实例,然后创建一个数组:
#include <algorithm> // fill
#include <iostream>
#include <iterator> // begin, end
#include <type_traits> // remove_reference
int main() {
struct {
unsigned char name[25];
unsigned char age;
unsigned int numberPhone;
} persons[256];
// an instance with the proper values:
std::remove_reference_t<decltype(persons[0])> temp{
.name = "Mohammed", .age = 0, .numberPhone = 0};
// fill the array
std::fill(std::begin(persons), std::end(persons), temp);
}
注意:std::remove_reference_t<decltype(persons[0])>
这是获取匿名类类型的一种繁琐方法。最好为您创建的类型命名。
|
memset
不适合初始化结构,因为它只能将每个字节设置为相同的值。对于像您这样的具有不同数据类型的结构,您需要定义一个默认结构,并使用为此目的设计的循环或标准函数将其复制到数组中的每个元素,这可以保持良好的性能和正确性。
|
标准 C 函数memset
声明如下
void *memset(void *s, int c, size_t n);
也就是说,它会用存储在第二个参数中的单个字符填充第一个参数指向的所有内存。因此,它不适合完成像你这样的任务。
另外,最好使用命名结构,因为这将简化对结构类型的引用。并且至少数据成员age
应该具有类型unsigned int
而不是类型,char
因为否则,无论如何age
您都需要将其转换为类型(例如int
或)才能输出unsigned int
。
memset
如果你确实指的是 C++,那么你可以使用标准算法来代替使用std::for_each
。例如
这是一个演示程序。
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
const std::size_t numberOfPersons = 5 /*or 264*/;
struct Person
{
unsigned char name[25];
unsigned int age;
unsigned int numberPhone;
} persons[numberOfPersons];
std::for_each( std::begin( persons ), std::end( persons ),
[]( auto &person )
{
person = { "Mohammed", 0, 0 };
} );
for ( const auto &person : persons )
{
const auto &[name, age, numberPhone] = person;
std::cout << "name = " << name
<< ", age = " << age
<< ", phone number = " << numberPhone << '\n';
}
}
程序输出是
name = Mohammed, age = 0, phone number = 0
name = Mohammed, age = 0, phone number = 0
name = Mohammed, age = 0, phone number = 0
name = Mohammed, age = 0, phone number = 0
name = Mohammed, age = 0, phone number = 0
std::for_each
或者,您可以使用标准算法std::generate
或标准算法代替标准算法,std::fill
如下所示
std::generate( std::begin( persons ), std::end( persons ),
[]() -> Person
{
return { "Mohammed", 0, 0 };
} );
或者
std::fill( std::begin( persons ), std::end( persons ),
Person { "Mohammed", 0, 0 } );
或者如果你还不知道标准算法,那么就使用基于范围的 for 循环,例如
for (auto &person : persons)
{
person = { "Mohammed", 0, 0 };
}
但最简单的方法是在声明中初始化结构,无需任何算法或使用默认初始化程序的循环。
#include <iostream>
int main()
{
const std::size_t numberOfPersons = 5 /*or 264*/;
struct Person
{
unsigned char name[25] = "Mohammed";
unsigned int age = 0;
unsigned int numberPhone = 0;
} persons[numberOfPersons];
for ( const auto &person : persons )
{
const auto &[name, age, numberPhone] = person;
std::cout << "name = " << name
<< ", age = " << age
<< ", phone number = " << numberPhone << '\n';
}
}
正如您所看到的,没有使用 memset,也没有使用任何算法,甚至也没有使用循环来初始化数组。:)
考虑到这个基于范围的 for 循环
for ( const auto &person : persons )
{
const auto &[name, age, numberPhone] = person;
std::cout << "name = " << name
<< ", age = " << age
<< ", phone number = " << numberPhone << '\n';
}
可以改写为
for (const auto &[name, age, numberPhone] : persons)
{
std::cout << "name = " << name
<< ", age = " << age
<< ", phone number = " << numberPhone << '\n';
}
}
这些循环仅从 C++17 标准开始有效。否则你可以写
for ( const auto &person : persons )
{
std::cout << "name = " << person.name
<< ", age = " << person.age
<< ", phone number = " << person.numberPhone << '\n';
}
对于 C 来说,除了使用循环之外没有其他方法,因为在 C 中您可能无法为数据成员声明具有默认初始化程序的结构。
如果您已经初始化了结构数组的一个元素,那么要为所有其他元素复制初始化程序,您可以再次使用标准算法,std::fill
例如
#include <iostream>
#include <iterator>
#include <algorithm>
int main()
{
const std::size_t numberOfPersons = 5 /*or 264*/;
struct Person
{
unsigned char name[25];
unsigned int age;
unsigned int numberPhone;
} persons[numberOfPersons] = { "Mohammed", 0, 0 };
std::fill( std::next( std::begin( persons ) ), std::end( persons ), persons[0] );
for (const auto &[name, age, numberPhone] : persons)
{
std::cout << "name = " << name
<< ", age = " << age
<< ", phone number = " << numberPhone << '\n';
}
}
可以在 C 中使用相同的方法
#include <stdio.h>
int main(void)
{
enum { numberOfPersons = 5 /*or 264*/ };
struct Person
{
unsigned char name[25];
unsigned int age;
unsigned int numberPhone;
} persons[numberOfPersons] = { [0] = { .name = "Mohammed", .age = 0, .numberPhone = 0 } };
for ( size_t i = 1; i < numberOfPersons; i++ )
{
persons[i] = persons[0];
}
for ( size_t i = 0; i < numberOfPersons; i++ )
{
printf( "name = %s, age = %u, phone number = %u\n",
persons[i].name, persons[i].age, persons[i].numberPhone );
}
}
|
memset
?–
–
unsigned int numberPhone;
完全不行。请使用字符串,例如char numberPhone[16];
。–
–
–
|