【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 <stdio.h>
#include <string.h>

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 <stdio.h>
#include <stdlib.h>

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语言中有着广泛的应用,可以用于动态内存分配、函数参数传递、数组访问等方面。在使用指针时需要注意指针变量的初始化、指向的数据类型、边界问题等。通过本文的学习,相信读者对指针的理解和应用能力有了更深入的认识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/29803.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器视觉初步5-1:图像平滑专题

在计算机视觉领域&#xff0c;图像平滑处理是一个重要的任务&#xff0c;用于降低噪声&#xff0c;提高图像质量。常见的图像平滑算法有均值滤波、中值滤波、高斯滤波等。本文将介绍这些算法的原理&#xff0c;并分别给出使用Python与Halcon实现的代码。&#xff08;当前版本&a…

什么是微软的 Application Framework?

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天来看一下什么是微软的 Application Framework&#xff1f; 到底什么是 Application Framework&#xff1f; 我当年学习这个的时候也困惑了好久&#xff0c;于是一直在搜索这个概念有没有好的解释&#…

ChatGPT时代:ChatGPT全能应用一本通

引言 随着人工智能技术的不断发展和进步&#xff0c;我们进入了ChatGPT时代。ChatGPT是基于GPT架构的大型语言模型&#xff0c;它具备强大的自然语言处理和生成能力&#xff0c;使得我们能够进行更加自由、流畅的对话。作为ChatGPT的全能应用&#xff0c;它可以被视为一本通&a…

【性能优化】性能优化

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录 性能优化运行效率加载效率减少HTTP请求数量使用CDN缓存压缩文件、混淆样式表放在顶部、js代码放…

广告数仓:采集通道创建

系列文章目录 广告数仓&#xff1a;采集通道创建 文章目录 系列文章目录前言一、环境和模拟数据准备1.hadoop集群2.mysql安装3.生成曝光测试数据 二、广告管理平台数据采集1.安装DataX2.上传脚本生成器3.生成传输脚本4.编写全量传输脚本 三、曝光点击检测数据采集1.安装Zookee…

大数据周会-本周学习内容总结018

开会时间&#xff1a;2023.06.18 15:00 线下会议 01【调研-数据分析&#xff08;质量、ETL、可视化&#xff09;】 ETL&#xff0c;是英文Extract-Transform-Load的缩写&#xff0c;用来描述将数据从来源端经过抽取&#xff08;extract&#xff09;、转换&#xff08;transform…

开源游戏区块链项目分享:Unity开发的独立区块链

Arouse Blockchain [Unity独立区块链] ❗️千万别被误导&#xff0c;上图内容虽然都在项目中可寻&#xff0c;但与目前区块链的业务代码关联不大&#xff0c;仅供宣传作用(总得放些图看着好看)。之所以有以上内容是项目有个目标功能是希望每个用户在区块链上都有一个独一无二的…

如何看待 Facebook 上线支付功能?

随着科技的不断进步&#xff0c;电子支付在我们的生活中变得越来越普遍。最近&#xff0c;Facebook宣布推出自己的支付功能&#xff0c;这引起了广泛的关注和讨论。作为世界上最大的社交媒体平台之一&#xff0c;Facebook进入支付领域的举措无疑具有重要意义。那么&#xff0c;…

13年测试老鸟,带你详探服务端的接口测试,测试内卷之路...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 服务器的接口测试…

数据库第三章(SQL)

目录 1.SQL语言 索引 1.SQL语言 sql语言是个非过程性语言 sql的特点 1.综合统一&#xff0c;把增删查改都统一了起来 2.高度非过程化&#xff0c;不关心过程 3.面向集合的操作方式 sql基本语法 drop是删除表 delete是删除表的某个元组 安全方面&#xff1a;grant授权 revo…

EXCEL函数笔记1(数学函数、文本函数、日期函数)

数学函数 取整&#xff1a;INT(number) 取余&#xff1a;MOD(number,除数) 四舍五入&#xff1a;ROUND(number&#xff0c;保留几位小数) 取绝对值&#xff1a;ABS(number) 根号处理&#xff1a;SQRT&#xff08;number&#xff09; 0到1随机数&#xff1a;RAND&#xff08;&am…

【机器学习】十大算法之一 “朴素贝叶斯”

作者主页&#xff1a;爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typeblog个…

【LeetCode】每日一题 -- 1171. 从链表中删去总和值为零的连续节点 -- Java Version

题目链接&#xff1a;https://leetcode.cn/problems/remove-zero-sum-consecutive-nodes-from-linked-list/ 1. 题解&#xff08;1171. 从链表中删去总和值为零的连续节点&#xff09; 2021年字节二面真题 1.1 暴力解法&#xff1a;穷举 时间复杂度 O(n2)&#xff0c;空间复杂…

【论文】attention is all you need

重点在第三节 attention is all you need摘要1. 绪论2. 背景3. 模型架构3.1 编码器和解码器堆叠 3.2 注意力3.2.1 缩放点积注意力&#xff08;Scaled Dot-Product Attention&#xff09;3.2.2 多头注意力机制3.2.3 模型中注意力的应用 3.3 职位感知前馈网络&#xff08;Positio…

前端中间件Midway的使用

一、 关于midway1. 解决什么痛点2. 期望达到什么效果 二、创建应用并使用1. 创建midway应用2. 认识Midway2.1 目录结构2.2 Controller2.3 路由2.4 获取请求参数2.5 Web中间件2.6 组件使用2.7 服务(service) 三、写到最后 一、 关于midway Midway 是阿里巴巴 - 淘宝前端架构团队…

基于深度学习的高精度安全背心检测识别系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于深度学习的高精度安全背心检测识别系统可用于日常生活中或野外来检测与定位安全背心目标&#xff0c;利用深度学习算法可实现图片、视频、摄像头等方式的安全背心目标检测识别&#xff0c;另外支持结果可视化与图片或视频检测结果的导出。本系统采用YOLOv5…

微服务: 01-rabbitmq的应用场景及安装(docker)

目录 1. rabbitmq前言简介: 1.1 RabbitMQ的几个重要作用&#xff1a; -> 1.1.1 解耦&#xff1a; -> 1.1.2 异步通信&#xff1a; -> 1.1.3 流量削峰&#xff1a; -> 1.1.4 消息传递的可靠性和持久性&#xff1a; 2. rabbitmq的安装(docker版) -> 2.1 …

SpringMVC 学习整理

文章目录 一、SpringMVC 简介1.1 什么是MVC1.2 什么是Spring MVC1.3 Spring MVC的特点 二、SpringMVC 快速入门三、RequestMapping注解说明四、SpringMVC获取请求参数4.1 通过ServletAPI获取请求参数4.2 通过控制器方法的形参获取请求参数4.3 通过RequestParam接收请求参数4.4 …

Rust语言从入门到入坑——(2)Rust在windows上搭建开发环境

文章目录 0 引入1、搭建 Visual Studio Code 开发环境1.1、安装 Rust 编译工具1.2 、VS Code安装 2、官网在线3、总结4、引用 0 引入 开始搭建一个适合在windows上运行的Rust环境。 Rust支持的程序语言很多&#xff1a;可详见官网介绍 1、搭建 Visual Studio Code 开发环境 …

[架构之路-211]- 需求- 软架构前的需求理解:ADMEMS标准化、有序化、结构化、层次化需求矩阵 =》需求框架

目录 前言&#xff1a; 一、什么是ADMES: 首先&#xff0c;需求是分层次的&#xff1a; 其次&#xff0c;需求是有结构的&#xff0c;有维度的 再次&#xff0c;不同层次需求、不同维度需求之间可以相互转化&#xff08;难点、经验积累&#xff09; 最终&#xff0c;标准…
最新文章