C 中的指针 - 结构和指向指针的指针

0. 结构体指针

与整数指针、数组指针和函数指针一样,我们也有结构体指针或结构体指针。

struct records {
    char name[20];
    int roll;
    int marks[5];
    char gender;
};

struct records student = {"Alex", 43, {76, 98, 68, 87, 93}, 'M'};

struct records *ptrStudent = &student;

在这里,我们声明了一个ptrStudent类型为 的指针struct recordsstudent我们已将的地址分配给ptrStudent

ptrStudent存储 的基地址student,它是结构体第一个成员的基地址。增加 1 将使地址增加sizeof(student)字节。

printf("Address of structure = %d\n", ptrStudent);
printf("Adress of member `name` = %d\n", &student.name);
printf("Increment by 1 results in %d\n", ptrStudent + 1);

/* Output */
Address of structure = 6421984
Adress of member `name` = 6421984
Increment by 1 results in 6422032

我们可以通过两种方式访问student​​using的成员。ptrStudent使用我们的老朋友*或使用->中缀或箭头运算符)。

对于*,我们将继续使用.( 点运算符),而对于 ,->我们将不需要点运算符。

printf("Name w.o using ptrStudent : %s\n", student.name);
printf("Name using ptrStudent and * : %s\n", ( *ptrStudent).name);
printf("Name using ptrStudent and -> : %s\n", ptrStudent->name);

/* Output */
Name without using ptrStudent: Alex
Name using ptrStudent and *: Alex
Name using ptrStudent and ->: Alex

同样,我们也可以访问和修改其他成员。请注意,使用时括号是必需的,*因为点运算符 ( .) 的优先级高于*

1. 结构体数组

我们可以创建一个类型数组struct records并使用指针来访问元素及其成员。

struct records students[10];

 /* Pointer to the first element ( structure) of the array */
struct records *ptrStudents1 = &students;

 /* Pointer to an array of 10 struct records */
struct records (*ptrStudents2)[10] = &students;

请注意,ptrStudent1是 一个指向student[0]while的指针,而ptrStudent2是一个指向整个数组 10 的指针struct records。加 1 将ptrStudent1指向student[1]

我们可以使用ptrStudent1循环来遍历元素及其成员。

for( int i = 0; i <  10; i++)
printf("%s, %d\n", ( ptrStudents1 + i)->name, ( ptrStudents1 + i)->roll);

2. 将结构指针作为参数

我们还可以将结构变量的地址传递给函数。

#include 

struct records {
    char name[20];
    int roll;
    int marks[5];
    char gender;
};

main(){
 struct records students = {"Alex", 43, {76, 98, 68, 87, 93}, 
'M'};
 printRecords(&students);
}

void printRecords( struct records *ptr){
  printf("Name: %s\n", ptr->name);
  printf("Roll: %d\n", ptr->roll);
  printf("Gender: %c\n", ptr->gender);
  for( int i = 0; i < 5; i++)
   printf("Marks in %dth subject: %d\n", i, ptr->marks[i]);
}

 /* Output */
Name: Alex
Roll: 43
Gender: M
Marks in 0th subject: 76
Marks in 1th subject: 98
Marks in 2th subject: 68
Marks in 3th subject: 87
Marks in 4th subject: 93

请注意,该结构struct records是在外部声明的main()。这是为了确保它在全球范围内可用并且printRecords()可以使用。

如果该结构体在内部定义main(),其范围将被限制为main(). 此外,结构体也必须在函数声明之前声明。

与结构一样,我们可以拥有指向联合的指针,并且可以使用箭头运算符 ( ->) 访问成员。

3. 指针到指针

到目前为止,我们已经了解了指向各种原始数据类型、数组、字符串、函数、结构和联合的指针。

我自然而然地想到的问题是——指针到指针怎么样?

好消息给你!他们也存在。

int var = 6;
int *ptr_var = &var;

printf("Address of var = %d\n", ptr_var);
printf("Address of ptr_var = %d\n", &ptr_var);

/* Output */
Address of var = 6422036
Address of ptr_var = 6422024

int为了存储变量的地址var,我们有一个指向 的指针int ptr_var。我们需要另一个指针来存储 的地址ptr_var

由于ptr_var是 类型int *,为了存储其地址,我们必须创建一个指向 的指针int *。下面的代码展示了如何做到这一点。

int * *ptr_ptrvar = &ptr_var; /* or int* *ppvar or int **ppvar */

我们可以使用ptr_ptrvar来访问 的地址ptr_var,并使用双重解引用来访问 var。

printf("Address of ptr_var = %d\n", ptr_ptrvar);
printf("Address of var = %d\n", *ptr_ptrvar);
printf("Value at var = %d\n", *(*ptr_ptrvar));

/* Output */
Address of ptr_var = 6422024
Address of var = 6422036
Value at var = 6

取消引用时不需要使用括号ptr_ptrvar。但使用它们是一个很好的做法。我们可以创建另一个指针ptr_ptrptrvar,它将存储 的地址ptr_ptrvar

由于ptr_ptrvar是 类型int**,因此声明ptr_ptrptrvar

int** *ptr_ptrptrvar = &ptr_ptrvar;

我们可以再次访问ptr_ptrvarptr_var使用。varptr_ptrptrvar

printf("Address of ptr_ptrvar = %d\n", ptr_ptrptrvar);
printf("Value at ptr_ptrvar = %d\n",*ptr_ptrptrvar);
printf("Address of ptr_var = %d\n", *ptr_ptrptrvar);
printf("Value at ptr_var = %d\n", *(*ptr_ptrptrvar));
printf("Address of var = %d\n", *(*ptr_ptrptrvar));
printf("Value at var = %d\n", *(*(*ptr_ptrptrvar)));

/* Output */
Address of ptr_ptrvar = 6422016
Value at ptr_ptrvar = 6422024
Address of ptr_var = 6422024
Value at ptr_var = 6422036
Address of var = 6422036
Value at var = 6

ptr_ptrptrvar如果我们使用或更改任何指针的值ptr_ptrvar,则指针将停止指向该变量。


我尝试尽可能多地介绍指针。我们讨论了指针表示法、定义、类型和算术。接下来是它在数组、字符串和函数中的使用。最后,我们讨论了结构体和指针本身!一个完整的圆,不是吗?

你可能感兴趣的:(c语言,c++,c语言,开发语言)