介绍
如前所述,本课程要求先决条件是对C语言有基本的理解。话虽如此,由于在本课程中的重要性,我们将提到一些概念。
结构
结构或结构是用户定义的数据类型,允许程序员将不同数据类型的相关数据项分组到一个单元中。结构可用于存储与特定对象相关的数据。结构有助于以易于访问和操作的方式组织大量相关数据。结构中的每一项都被称为“成员”或“元素”,这些术语在课程中可以互换使用。
在使用Windows API时,常见的情况是,某些API需要填充的结构作为输入,而其他API则使用声明的结构并填充它。下面是THREADENTRY32
结构的示例,此时不必了解成员的用途。
typedef struct tagTHREADENTRY32 {
DWORD dwSize; // Member 1
DWORD cntUsage; // Member 2
DWORD th32ThreadID;
DWORD th32OwnerProcessID;
LONG tpBasePri;
LONG tpDeltaPri;
DWORD dwFlags;
} THREADENTRY32;
声明结构
本课程中使用的结构通常通过使用typedef
关键字来声明,以给结构一个别名。例如,下面的结构是用名称_structure_name
创建的,但typedef
添加了另外两个名称,structure_name
和*PSTRUCTURE_name
。
typedef struct _STRUCTURE_NAME {
// structure elements
} STRUCTURE_NAME, *PSTRUCTURE_NAME;
STRUCTURE_NAME
别名指的是结构名称,而PSStructure_NAME
表示指向该结构的指针。Microsoft通常使用P
前缀来表示指针类型。
初始化结构
初始化一个结构会有所不同,这取决于是初始化实际的结构类型还是指向该结构的指针。继续上一个示例,使用_STRUCTURE_NAME
或STRUCTURE_NAME
初始化结构时的操作相同,如下所示。
STRUCTURE_NAME struct1 = { 0 }; // The '{ 0 }' part, is used to initialize all the elements of struct1 to zero
// OR
_STRUCTURE_NAME struct2 = { 0 }; // The '{ 0 }' part, is used to initialize all the elements of struct2 to zero
这与初始化结构指针PSTRUCTURE_NAME
时不同。
PSTRUCTURE_NAME structpointer = NULL;
初始化和访问结构成员
结构的成员可以直接通过结构初始化,也可以通过指向结构的指针间接初始化。在下面的示例中,结构struct1
有两个成员ID
和Age
,直接通过点运算符(.
)初始化。
typedef struct _STRUCTURE_NAME {
int ID;
int Age;
} STRUCTURE_NAME, *PSTRUCTURE_NAME;
STRUCTURE_NAME struct1 = { 0 }; // initialize all elements of struct1 to zero
struct1.ID = 1470; // initialize the ID element
struct1.Age = 34; // initialize the Age element
初始化成员的另一种方法是使用指定的初始化器语法,其中可以指定要初始化结构的哪些成员。
typedef struct _STRUCTURE_NAME {
int ID;
int Age;
} STRUCTURE_NAME, *PSTRUCTURE_NAME;
STRUCTURE_NAME struct1 = { .ID = 1470, .Age = 34}; // initialize both the ID and the Age elements
另一方面,通过指针访问和初始化结构是通过箭头操作符(->
)完成的。
typedef struct _STRUCTURE_NAME {
int ID;
int Age;
} STRUCTURE_NAME, *PSTRUCTURE_NAME;
STRUCTURE_NAME struct1 = { .ID = 1470, .Age = 34};
PSTRUCTURE_NAME structpointer = &struct1; // structpointer is a pointer to the 'struct1' structure
// Updating the ID member
structpointer->ID = 8765;
printf("The structure's ID member is now : %d \n", structpointer->ID);
箭头运算符可以转换为点格式。例如,structpointer->ID
等价于(*structpointer).ID
。也就是说,structurepointer
被取消引用,然后直接访问。
按值传递
按值传递是一种将参数传递给函数的方法,其中参数是对象值的副本。这意味着当参数通过值传递时,对象的值被复制,函数只能修改对象值的本地副本,而不能修改原始对象本身。
int add(int a, int b)
{
int result = a + b;
return result;
}
int main()
{
int x = 5;
int y = 10;
int sum = add(x, y); // x and y are passed by value
return 0;
}
按引用传递
通过引用传递是一种将参数传递给函数的方法,其中参数是指向对象的指针,而不是对象值的副本。这意味着当参数通过引用传递时,传递的是对象的内存地址,而不是对象的值。然后,函数可以直接访问和修改对象,而无需创建对象的本地副本。
void add(int *a, int *b, int *result)
{
int A = *a; // A is now the same value of a passed in from the main function
int B = *b; // B is now the same value of b passed in from the main function
*result = B + A;
}
int main()
{
int x = 5;
int y = 10;
int sum = 0;
add(&x, &y, &sum);
// 'sum' now is 15
return 0;
}
暂无评论内容