【C语言/C++实现结构体和指针详细教程】

结构体和指针

结构体

C语言中的结构体是一种自定义的数据类型,它允许我们将不同类型的数据组合在一起,形成一个新的数据类型。结构体可以包含不同类型的数据,如整数、字符、浮点数、数组等,可以用来描述复杂的数据结构。下面将详细介绍C语言中的结构体,包括结构体的定义、结构体变量的声明和初始化、结构体成员的访问等内容。

一、结构体的定义

结构体的定义使用关键字struct,其语法格式如下:

struct 结构体名 {
数据类型 成员名1;
数据类型 成员名2;
数据类型 成员名3;
……
};

其中,结构体名是我们自定义的名称,成员名是我们为结构体中的每个元素命名的名称,数据类型可以是任意的C语言数据类型,也可以是其他的结构体类型。

例如,我们可以定义一个结构体来表示一个学生的信息,包括姓名、年龄、性别、学号和成绩等,代码如下:

struct Student {
    char name[20];
    int age;
    char sex;
    char id[10];
    float score;
};

在上面的代码中,我们定义了一个名为Student的结构体,它包含了5个成员,分别是姓名、年龄、性别、学号和成绩,它们的数据类型分别为char、int、char、char和float。

二、结构体变量的声明和初始化

结构体定义好之后,我们就可以声明结构体变量并对其进行初始化。结构体变量的声明和初始化有两种方式,分别是:

1、先声明后初始化

struct Student stu;
stu.age = 18;
strcpy(stu.name, "Tom");
stu.sex = 'M';
strcpy(stu.id, "2018001");
stu.score = 95.0;

在上面的代码中,我们先声明了一个名为stu的Student类型的结构体变量,然后对其各个成员进行了初始化。

2、同时声明和初始化

struct Student stu = {"Tom", 18, 'M', "2018001", 95.0};

在上面的代码中,我们在声明stu结构体变量的同时对其进行了初始化,初始化的顺序和成员的定义顺序一致。

三、结构体成员的访问

结构体成员的访问使用“.”操作符,例如:

printf("姓名:%s\n", stu.name);
printf("年龄:%d\n", stu.age);
printf("性别:%c\n", stu.sex);
printf("学号:%s\n", stu.id);
printf("成绩:%f\n", stu.score);

在上面的代码中,我们使用“.”操作符来访问stu结构体变量中的各个成员,然后输出它们的值。

四、结构体作为函数参数

结构体可以作为函数的参数,例如:

void printStudent(struct Student s) {
    printf("姓名:%s\n", s.name);
    printf("年龄:%d\n", s.age);
    printf("性别:%c\n", s.sex);
    printf("学号:%s\n", s.id);
    printf("成绩:%f\n", s.score);
}

在上面的代码中,我们定义了一个名为printStudent的函数,它的参数是一个Student类型的结构体变量s,然后输出s变量中的各个成员。

五、完整代码

下面是一个完整的使用结构体的例子,它定义了一个名为Student的结构体,并声明了一个名为stu的结构体变量,并对其进行了初始化,最后输出了stu变量中的各个成员。

#include 
#include 

struct Student {
    char name[20];
    int age;
    char sex;
    char id[10];
    float score;
};

void printStudent(struct Student s) {
    printf("姓名:%s\n", s.name);
    printf("年龄:%d\n", s.age);
    printf("性别:%c\n", s.sex);
    printf("学号:%s\n", s.id);
    printf("成绩:%f\n", s.score);
}

int main() {
    struct Student stu = {"Tom", 18, 'M', "2018001", 95.0};
    printStudent(stu);
    return 0;
}

运行结果如下:

姓名:Tom
年龄:18
性别:M
学号:2018001
成绩:95.000000

六、总结

本文介绍了C语言中的结构体,包括结构体的定义、结构体变量的声明和初始化、结构体成员的访问和结构体作为函数参数等内容。结构体是一种非常重要的数据类型,它可以用来描述复杂的数据结构,方便程序的编写和维护。

指针

指针是C语言中非常重要的概念,也是初学者最难以理解的概念之一。指针的本质是一个地址,它指向一个数据存储的位置。通过指针,我们可以访问并操作这个位置中存储的数据。下面将详细讲解C语言中指针的相关概念和用法,并附带详细代码和代码的解释。

一、指针的定义

指针的定义格式为:*数据类型 指针变量名;其中,数据类型表示指针所指向的数据类型,指针变量名是一个标识符,用于表示指针变量在内存中的位置。例如:

int *p; //定义一个指向整型数据的指针变量

在定义指针变量时,需要指定指针所指向的数据类型。这是因为不同的数据类型占据的存储空间大小不同,指针需要知道所指向的数据类型的大小,才能正确地进行指针运算。

二、指针的初始化

指针变量在定义时不会自动指向某个地址,需要进行初始化操作,将指针变量指向一个合法的内存地址。指针变量的初始化可以通过以下几种方式:

① 直接赋值:将指针变量赋值为一个已知的地址。

int a = 10;
int *p = &a; //将指针p指向变量a的地址

② 通过malloc函数动态分配内存:

int *p = (int *)malloc(sizeof(int)); //动态分配一个整型数据的内存空间,并将指针p指向这个空间的地址

③ 通过函数返回值初始化:

int *get_array(int size) {
    int *p = (int *)malloc(size * sizeof(int));
    return p;
}

int *arr = get_array(10); //将指针arr指向动态分配的数组的首地址

三、指针的运算

指针变量可以进行加减运算,指向的地址会根据运算结果进行相应的偏移。例如:

int a[5] = {1, 2, 3, 4, 5};
int *p = a; //将指针p指向数组a的首地址

for (int i = 0; i < 5; i++) {
    printf("%d ", *p); //输出指针p所指向的数据
    p++; //指针p指向下一个数据
}

在上面的代码中,指针p首先指向数组a的首地址,然后通过指针运算,依次访问数组中的每个元素,并输出它们的值。

指针变量还可以进行比较运算,比较的是它们所指向的地址是否相同。例如:

int a = 10, b = 20;
int *p1 = &a, *p2 = &b;

if (p1 > p2) {
    printf("p1指向的地址大于p2\n");
} else {
    printf("p1指向的地址小于等于p2\n");
}

在上面的代码中,通过指针变量p1和p2的比较,判断它们所指向的地址的大小,并输出相应的结果。

四、指针的应用

指针在C语言中有着广泛的应用,可以用于以下几个方面:

① 动态内存分配:通过指针和malloc函数可以动态地分配内存空间,避免了静态分配时内存浪费的问题。

② 函数参数传递:通过指针可以实现函数参数的传递,可以将函数内部的计算结果返回给调用者。

void swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

int a = 10, b = 20;
swap(&a, &b); //将变量a和b的值交换

在上面的代码中,通过指针将变量a和b的值交换,实现了函数的功能。

③ 数组的访问:数组名本质上是一个指向数组首地址的指针,通过指针可以访问数组中的每个元素。

int a[5] = {1, 2, 3, 4, 5};
int *p = a; //将指针p指向数组a的首地址

for (int i = 0; i < 5; i++) {
    printf("%d ", *(p + i)); //输出数组中的每个元素
}

在上面的代码中,通过指针p访问数组a中的每个元素,并输出它们的值。

五、指针的注意事项

指针在使用时需要注意以下几点:

① 指针变量必须先进行初始化,才能使用。

② 指针变量不能访问没有被分配的内存空间,否则会导致程序崩溃。

③ 指针变量必须指向正确的数据类型,否则会导致指针运算错误。

④ 指针变量在使用时需要注意指针运算的边界问题,避免越界访问。

六、示例代码

下面是一个完整的示例代码,演示了指针的定义、初始化、运算和应用:

#include 
#include 

void swap(int *x, int *y) {
    int temp = *x;
    *x = *y;
    *y = temp;
}

int *get_array(int size) {
    int *p = (int *)malloc(size * sizeof(int));
    return p;
}

int main() {
    int a = 10, b = 20;
    int *p1 = &a, *p2 = &b;
if (p1 > p2) {
    printf("p1指向的地址大于p2\n");
} else {
    printf("p1指向的地址小于等于p2\n");
}

int arr[5] = {1, 2, 3, 4, 5};
int *p = arr;

for (int i = 0; i < 5; i++) {
    printf("%d ", *(p + i));
}
printf("\n");

int *arr2 = get_array(10);
for (int i = 0; i < 10; i++) {
    *(arr2 + i) = i;
    printf("%d ", *(arr2 + i));
}
printf("\n");

swap(&a, &b);
printf("a=%d, b=%d\n", a, b);

free(arr2);

return 0;
}

在上面的代码中,定义了两个指针变量p1和p2,通过比较它们所指向的地址的大小,输出相应的结果。然后定义了一个数组arr,通过指针变量p访问数组中的每个元素,并输出它们的值。接着通过函数get_array动态分配了一个数组,通过指针变量arr2访问数组中的每个元素,并输出它们的值。最后通过函数swap交换了变量a和b的值,并输出它们的值。注意,在使用完动态分配的数组后,需要使用free函数释放内存空间。

七、总结

本文详细讲解了C语言中指针的相关概念和用法,包括指针的定义、初始化、运算和应用。指针在C语言中有着广泛的应用,可以用于动态内存分配、函数参数传递、数组访问等方面。在使用指针时需要注意指针变量的初始化、指向的数据类型、边界问题等。通过本文的学习,相信读者对指针的理解和应用能力有了更深入的认识。

你可能感兴趣的:(数据结构与算法,C++,C语言,c++,c语言,开发语言)