C 语言学习日记・数据类型与结构体篇

一、整型数据与溢出

1. 取值范围

  • 32 位int:范围 -2^31 ~ 2^31-1(-2147483648 ~ 2147483647)

  • 64 位long long:范围 -2^63 ~ 2^63-1,最多正确计算 20 的阶乘

2. 溢出现象

整数溢出属于 C 语言未定义行为,数值会发生截断错乱。例如计算 100! 时,持续累乘后二进制低位全部变为 0,最终输出结果为 0。

  • 解决方案:小范围用long long;超大数必须用数组模拟高精度乘法。

二、const 常量修饰

const修饰的变量为只读变量,定义后不可修改:

const int number = 10;
// number = 20;  // ❌ 编译报错,只读变量不可修改

常用来定义数组长度、固定参数,提高代码可读性和安全性。

三、结构体与 typedef

方式 1:匿名结构体(定义类型同时直接创建变量,无类型名)

没有结构体标签名,只能当场定义变量,后面不能再定义新变量

#include <stdio.h>

// 匿名结构体
struct {
    int a;
    char b;
} t, ti;   // 直接定义 t、ti 两个结构体变量

int main(void)
{
    t.a = 10;
    t.b = 'c';
    printf("%d %c\n", t.a, t.b);
    return 0;
}

方式 2:带标签名结构体(先声明类型,后定义变量)

有标签名struct person,可以在任意地方重复定义变量

#include <stdio.h>

// 1.声明结构体标签 struct person
struct person {
    int num;
    char name[10];
};

int main(void)
{
    // 2.使用标签定义变量,必须写 struct
    struct person p = {20, "cyx"};
    struct person p2;   // 可以继续定义新变量
    printf("%d %s\n", p.num, p.name);
    return 0;
}

方式 3:typedef 给结构体起别名(工程最常用)

使用typedef,后续不用写struct,直接用别名

#include <stdio.h>

// typedef + 匿名结构体,别名 Data
typedef struct {
    int lead;
    int data[100];
} Data;

int main(void)
{
    // 直接用别名Data定义变量,不用写struct
    Data h = {19, {1,2,3}};
    Data *hi = &h;

    printf("%d\n", (*hi).data[2]);  // 写法1:解引用 + . ,括号不能丢
    printf("%d\n", hi->data[2]);   // 写法2:箭头 -> ,推荐

    return 0;
}

关键对比总结

写法是否需要写struct能否后续新建变量
方式 1 匿名结构体变量处不用写❌ 不能
方式 2 struct 标签名定义变量必须写 struct✅ 可以
方式 3 typedef 别名直接写别名,不用 struct✅ 可以

四、结构体初始化

按照成员定义的顺序,用大括号批量赋值:

// 普通结构体初始化
struct person p = {20, "cyx"};

// 包含数组成员的结构体,嵌套大括号初始化数组
Data h = {19, {1, 2, 3}};
  • 初始化顺序必须和结构体成员的声明顺序一一对应

  • 只初始化部分成员时,剩余成员自动初始化为 0

五、结构体成员访问

1. 普通结构体变量:点运算符 .

Data h = {19, {1, 2, 3}};
h.lead = 20;        // 修改普通成员
h.data[1] = 10;     // 修改数组型成员:变量名.数组名[下标]
  • 结构体变量直接用 . 访问内部成员

  • 若成员是数组,再通过[下标]访问数组的具体元素

2. 结构体指针:两种访问写法

当用指针指向结构体时,有两种等价的访问方式:

Data h = {19, {1, 2, 3}};
Data *hi;
hi = &h;    // 指针指向结构体变量地址

写法 1:解引用 + 点运算符(必须加括号)

printf("%d\n", (*hi).data[2]);
  • 括号不能省略:.的优先级高于*,不加括号会先执行hi.data引发错误

  • 逻辑:先对指针解引用得到结构体本身,再用.访问成员

写法 2:箭头运算符 ->(推荐,最常用)

printf("%d\n", hi->data[2]);
  • ->是结构体指针专属的访问运算符,等价于(*指针).成员

  • 写法更简洁,是指针访问结构体成员的标准写法

六、常用格式符汇总

格式符作用参数要求
%d输出 / 输入十进制整数传 int 变量值(scanf 需加 &)
%c输出 / 输入单个字符传 char 变量值
%s输出 / 输入字符串传字符串首地址(不能加 *)
%p输出内存地址传指针 / 地址
%lld输出 long long 类型整数传 long long 变量

七、易错踩坑清单

  1. 相等判断写错:if 条件中相等是==,写成=会变成赋值语句,引发逻辑错误。

  2. 结构体成员访问:结构体里的数组成员,访问时是变量名.数组名[下标],不要写错顺序。

  3. 类型不匹配:字符串只能初始化char数组,不能直接赋值给int数组。

  4. 括号遗漏错误(*p).成员的括号绝对不能省,写成*p.member会编译报错。

  5. 访问符混淆:普通结构体变量用.,结构体指针用->,不可混用。

  6. 初始化顺序错误:初始化值的顺序必须和结构体成员定义顺序一致,不能乱序。

  7. 数组成员初始化遗漏大括号:结构体里的数组成员,初始化时要用{}单独包裹,例如{19, {1,2,3}}

  8. 匿名结构体复用问题:法一的匿名结构体类型,不能在后续代码中再用来定义新变量。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kelvins轩

感谢大佬投喂!暴富发财好运爆棚

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值