模块4 – 编码基础

介绍

如前所述,本课程要求先决条件是对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_NAMESTRUCTURE_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有两个成员IDAge,直接通过点运算符(.)初始化。

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;
}
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容