C语言 —— 初步入门知识(内存、指针、结构体)

news2025/1/13 13:58:23

本篇文章将接着上篇继续介绍C语言的基础知识,那么对于C语言大部分初学者会觉得难以理解, 所以作者将指针单独拿出来写篇较短的文章进行讲解。

1.指针

1.1 内存

要学习指针,就先要了解内存。一起来看。

内存是计算机中的关键组成部分,用于存储数据和程序。每个内存单元的大小通常是1字节,这意味着它可以存储8位的二进制数据(每个位可以是0或1)。

当计算机需要访问内存中的特定位置时,它需要生成一个地址,以便指示内存控制器要读取或写入哪个内存单元的数据。对于32位的计算机,生成地址的过程涉及到32根地址线。

这些地址线的状态(通电或不通电)以二进制形式表示。例如,如果计算机有32根地址线,它们可以同时处于以下状态:

  • 00000000 00000000 00000000 00000000(对应0)
  • 00000000 00000000 00000000 00000001(对应1)
  • ...
  • 11111111 11111111 11111111 11111111(对应最大的32位二进制值)

这些地址线的不同组合产生不同的二进制地址。每个不同的地址都对应一个内存单元(1字节),因此,对于32位电脑来说,它可以管理的最大内存容量为4GB(千兆字节)。

所以,如果一个内存单元的大小是1字节,并且计算机使用32位地址线,那么它可以管理的最大内存容量就是4GB。这意味着它可以同时访问和处理4GB的数据和程序。这种地址线和内存容量的关系对计算机的性能和功能有重要影响,因此在计算机硬件设计中非常重要。

如何理解内存? 这个时候就要类比生活中的例子.

在生活中有许多的居民楼, 居民楼里面整个空间就被划分为一个个房间, 对每个房间进行编号, 这样就能很好的知道每个房间的位置. 假如要送外卖到某个房间, 那么只要知道客户的地址, 也就是房间的编号就可以准确无误的送达.

那么内存也是一样的, 内存就相当于上面例子中的"居民楼", 划分出的单元"房间"的编号就是内存单元的地址. 当给内存空间的每个单元编号, 有地址了之后, 需要找到哪个内存空间就会非常的方便.

总结如下:

内存划分成一个个小的内存单元,每个内存单元的大小是1个字节.

为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址.

上图中的编号为十六进制

1.2 变量在内存中的存储

变量是创建内存中的(在内存中分配空间的),每个内存单元都有地址,所以变量也是有地址的。

编写以下代码进行调试, 来查看变量在内存中的存储.

int main()
{
    int a = 10;    // 向内存申请 4 个字节的空间, 存储 10
    &a;    // 取地址操作符

    return 0;
}

如果需要看内存也可以在调试->窗口->内存打开内存调试窗口进行查看.(注意这里面的窗口必须是先开始调试才能看到监视/内存窗口)

输入&a, 按下回车可以看到,

内存窗口中的地址和上方监视窗口显示的&a的值是相同的.

十进制: 0 1 2 3 4 5 6 7 8 9
八进制: 0~7
十六进制: 0~9 a b c d e f

十进制的10 转化为二进制:
0000 0000 0000 0000 0000 0000 0000 1010
再转化为十六进制:
0 0 0 0 0 0 0 a
即:
0x 00 00 00 0a
到内存中则倒序存储(暂时不解释为什么倒序)

所以可以看到, 内存中确实存储了数据10.


通过%p可以打印a的地址.


1.3 指针变量存储地址

1.3.1 指针与指针变量

我们在前面打印的a的地址, 是个十六进制的数字, 下面我们假设a的地址为0x0012ff40(凭空捏造出来的地址, 用以说明), 那么这个地址也是可以像int a = 10;把10存进a中一样, 将这个地址存进某个变量中, 如下所示.

int* p = &a;

a的地址取到, 放到p中, 那么p的变量类型为int*. 此时, 这个变量p就叫做指针变量.


我们前面有聊到内存单元, 每个内存单元都有编号, 那么这个编号其实就是地址, 而这个"地址"也别称为"指针". 所以指针就是地址.

上面的p是用来存a的地址的, 也就是存a的编号, 也就是存a的指针. 所以把存放地址, 存放指针的变量叫做指针变量.


当p是指针变量的时候如何理解它?


1.3.2 存储地址的意义

我们通过地址可以找到地址上的对象, 现在p中存放了a的地址, 那么就可以通过p找到a.

*p; 
*是解引用操作符, 这里意思是通过 p中存放的地址, 找到 p所指向的对象, *p 就是 p 指向的对象, 也就是 a.
int main()
{
    int a = 10;
    printf("%p\n", &a);

    int* p = &a; 
    printf("%d\n", a);

    *p = 20;
    printf("%d\n", a);

    return 0;
}

1.3.3 指针变量的大小

不管是什么类型的指针, 都是在创建指针变量. 指针变量是用来存放地址的, 它的大小取决于一个地址存放需要的大小.

32位平台下地址是32个bit位 (即4个字节)

64位平台下地址是64个bit位 (即8个字节)

int main()
{
    printf("%zu\n", sizeof(char*));    // 4
    printf("%zu\n", sizeof(short*));   // 4
    printf("%zu\n", sizeof(int*));     // 4
    printf("%zu\n", sizeof(float*));   // 4
    printf("%zu\n", sizeof(double*));  // 4
    return 0;
}

2.结构体

之前我们已经有学过各种数据类型, 比如char, short, int, long, float, double等等, 但是这些类型不能表示所有的情况, 因为这些类型表示一些数值是没有任何问题的, 但是如果需要表示一个复杂对象, 比如要表示 .就得要有名字, 年龄, 性别, 地址, 电话. 再比如表示一本 . 就得要有书名, 作者, 出版社, 定价, 书号. 所以要表示一个复杂对象就不能用简单的数据类型表示, 这个时候C语言就给了程序员自定义类型的能力, 自定义类型中有一种是结构体.

结构体是把一些单一类型组合在一起的做法.

// 学生
struct Stu
{
    // 成员
    char name[20];
    int age;
    char sex[10];
    char tele[12];
};

void print(struct Stu* ps)
{
    printf("%s %d %s %s\n", (*ps).name, (*ps).age, (*ps).sex, (*ps).tele);
    // -> 
    // 结构体指针变量->成员名
    printf("%s %d %s %s\n", ps->name, ps->age, ps->sex, ps->tele);

}
int main()
{
    // 结构体初始化
    struct Stu s = {"zhangsan", 20, "nan", "01234567890"};
    // 结构体对象.成员名
    printf("%s %d %s %s\n", s.name, s.age, s.sex, s.tele);

    print(&s);

    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

机器学习技术(九)——支持向量机算法实操(基于SVM的模型对潜在运营商客户进行分类)

机器学习技术(九)——支持向量机算法实操 文章目录 机器学习技术(九)——支持向量机算法实操一、引言二、数据集介绍三、导入相关依赖库四、读取数据五、数据可视化分析1、是否为潜在客户与不同用户主叫时长对比2、是否为潜在合约…

绘图(一)弹球小游戏

AWT编程 语雀 仓库:Java图形化界面: Java图形化界面学习demo与资料 (gitee.com) 很多程序如各种小游戏都需要在窗口中绘制各种图形,除此之外,即使在开发JavaEE项目时, 有 时候也必须"动态"地向客户 端生成各种图形、…

C语言进阶指针(3) ——qsort的实现

大家好&#xff0c;我们今天来学习回调函数qsort的实现。 首先让我们打开cplusplus.com找到qsort函数。 我们看到这个函数就可以看到它的头文件和参数信息。 #include<stdlib.h> void qsort (void* base, size_t num, size_t size, int (*compar)(const void*,const voi…

前后端跨域请求问题解决方法

如图&#xff1a; 1.在config配置包中创建一个CorsConfig配置类 2.将下面代码复制到这个类中即可 import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfigurati…

[字符串和内存函数]strcmp和strncmp以及memcmp的区别

CPlus中对strcmp的介绍 #include <stdio.h> #include <string.h>int main () {char key[] "apple";char buffer[80];do {printf ("Guess my favorite fruit? ");fflush (stdout);scanf ("%79s",buffer);} while (strcmp (key,buf…

MySQL 约束与复杂查询

当涉及到数据库管理系统&#xff08;DBMS&#xff09;的高级主题时&#xff0c;包括数据库的约束、表的设计以及各种类型的查询&#xff0c;特别是聚合查询、联合查询和合并查询&#xff0c;是非常重要的。这些主题可以帮助我们更好地理解数据库的内部工作机制以及如何有效地操…

[maven] 创建 spring boot 项目及使用 Jenkins 运行 maven

[maven] 创建 spring boot 项目及使用 Jenkins 运行 maven 本篇笔记走一下用 maven 创建 spring boot 项目和利用 Jenkins 管理 maven 流程 使用 maven 创建 spring boot 项目 根据官方文档说&#xff0c;现在使用 boot 需要 java 17&#xff0c;Gradle 7.5/Maven 3.5 spri…

idea无法通过vpn 连接到数据库或者kafka

本地navicate 等sql客户端 &#xff0c;通过vpn&#xff0c;可以连接到数据库&#xff0c;&#xff0c;xshell也可以通过vpn连接到远程机器&#xff0c;但是&#xff0c;idea开发时&#xff0c;报连接超时错误&#xff0c;解决方法&#xff1a; 项目中 VM这一栏加上-Djava.net…

区块链:去中心化革命下的创新与发展!

区块链作为一项重要的技术实验&#xff0c;确实具有重大的影响力。它代表了一场去中心化的运动&#xff0c;吸引了许多研究人员、工程师、建设者和用户的参与&#xff0c;创造了我们目前所见到的一些最有趣的技术。 区块链的透明特性赋予了用户对于数据和交易的控制权&#xff…

来看看Python __all__变量的用法

​ 事实上&#xff0c;当我们向文件导入某个模块时&#xff0c;导入的是该模块中那些名称不以下划线&#xff08;单下划线“_”或者双下划线“__”&#xff09;开头的变量、函数和类。因此&#xff0c;如果我们不想模块文件中的某个成员被引入到其它文件中使用&#xff0c;可以…

展示日志log4.properties

log4.properties 1.log4.properties 此时文件主要用于展示日志的输出的级别的信息。 # Set root category priority to INFO and its only appender to CONSOLE. #log4j.rootCategoryINFO, CONSOLE debug info warn error fatal log4j.rootCategoryinfo, CONSO…

本地事务与分布式事务

目录 一、本地事务 1、事务的基本性质 2、事务的隔离级别 3、事务的传播行为 4、SpringBoot 事务关键点 二、分布式事务 1、为什么有分布式事务 2、CAP 定理与 BASE 理论 3、分布式事务几种方案 一、本地事务 1、事务的基本性质 数据库事务的几个特性&#xff1a;原…

PhpStorm 2023年下载、安装教程和好用插件,保姆级教程

PhpStorm 2023年下载、安装教程和好用插件&#xff0c;保姆级教程 文章目录 PhpStorm 2023年下载、安装教程和好用插件&#xff0c;保姆级教程前言一、安装PhpStorm二、好用的插件简体中文包Chinese(Simplified)Language Pack 三、卸载插件CTRLN 查找类CTRLSHIFTN 全局搜索文件…

Scala编程语言

Scala编程语言 一、Scala引入1、学习Scala的目的2、Scala的基本概念 二、Scala环境搭建1、安装步骤2、配置环境变量3、测试Scala4、Scala与idea的集成5、关联源码6、 class 和 object 说明 三、常用语法、变量和数据类型1、 注释2、变量和常量3 、标识符的命名规范4、字符串输出…

一阶低通滤波器滞后补偿算法

一阶低通滤波器的推导过程和双线性变换算法请查看下面文章链接: PLC算法系列之数字低通滤波器(离散化方法:双线性变换)_双线性离散化_RXXW_Dor的博客-CSDN博客PLC信号处理系列之一阶低通(RC)滤波器算法_RXXW_Dor的博客-CSDN博客_rc滤波电路的优缺点1、先看看RC滤波的优缺点…

matlab EL image绘制

利用光谱仪测试的结果可以得到image&#xff0c;输出为csv文件&#xff0c;包括640X512的矩阵&#xff0c;这个矩阵将会反映器件发光的位置和强度&#xff0c;算是一个灰度图。 在matlab中&#xff0c;可以用imagesc函数来进行绘图。 imagesc函数的用法 clear; clc; close a…

Linux从root账号切换到普通账号并执行shell脚本

背景&#xff1a;最近自己在用的中间件只能运行在 普通账号下&#xff0c;现在每次重启之后都要切换到 普通账号 然后去执行启动脚本。一次两次还能接受……反正现在接受不了了…… 写一个脚本让它帮我起吧 先贴目录 新建文件 start_es.sh, 用于root账号下调用 #!/bin/bash e…

计算机组成原理——基础入门总结(一)

本帖更新一些关于计算机组成原理的重点内容。由于博主考研时并不会考这门课&#xff0c;但是考虑到操作系统中又很多重要晦涩的概念涉及很多诸如内存、存储器、磁盘、cpu乃至各种寄存器的知识&#xff0c;此处挑选一些核心的内容总结复盘一遍——实现声明&#xff1a;本帖的内容…

【CCF】第30次csp认证——202305-1重复局面

202305-1重复局面&#xff1a; 问题描述 国际象棋每一个局面可以用大小为 88 的字符数组来表示&#xff0c;其中每一位对应棋盘上的一个格子。六种棋子王、后、车、象、马、兵分别用字母 k、q、r、b、n、p 表示&#xff0c;其中大写字母对应白方、小写字母对应黑方。棋盘上无…

[ESP32 IDF+Vscode]蓝牙配网后采用上传温湿度数据至阿里云(MQTT协议)

阿里云平台的设置 参考文章&#xff1a; http://t.csdn.cn/RzLGqhttp://t.csdn.cn/RzLGq Blufi配网 1.简介 BluFi 是一款基于蓝牙通道的 Wi-Fi 网络配置功能&#xff0c;适用于 ESP32。它通过安全协议将 Wi-Fi 配置和证书传输到 ESP32&#xff0c;然后 ESP32 可基于这些信…