【C语言 全局 整形变量 布尔变量 数组变量 指针变量 结构体位域变量 枚举变量被其他.C文件相互访问】

【C语言 全局-> 整形变量 布尔变量 数组变量 指针变量 结构体位域变量 枚举变量被其他.C文件相互访问】

学完这一篇,对于变量的使用不在迷糊


【0】UI设计

UI使用文本编辑框显示操作的记录
在这里插入图片描述

【1】项目概述

本次使用QT平台进行编写和编译,使大家掌握某个.C文件的变量可以被其他文件 访问 | 修改 等

全局变量 整形 结构体 枚举 使用exterm关键字声名
目的:其他文件通过添加本文件头文件,可以使用这些变量 修改值|获取值|传参等

需要处理
【1】在本头文件.h必须使用exterm关键字声明变量
【2】在本源文件.C文件定义变量(分配变量空间)
【3】typedef关键字作用起别名


【2】mainwindow.h头文件解析

结构体声明

/* 全局变量 整形 结构体 枚举 使用exterm关键字声名
 * 目的:其他文件通过添加本文件头文件,可以使用这些变量 修改值|获取值|传参等*/
typedef  struct {
    int age;//可以被其他.c文件访问
}node_t;
extern node_t age_t;//可以被其他.c文件访问

常用数据类型变量声明

extern node_t age_t;//可以被其他.c文件访问
extern int global;  //可以被其他.c文件访问
extern bool global_bool;//可以被其他.c文件访问
extern int array[10];//可以被其他.c文件访问
extern char str[8];//可以被其他.c文件访问

exterm “C” 使用C的编译规范

extern "C"{//使用C语言的编译规范 因为C++11警告在其他.c文件给p赋值字符串
    extern char *p;//可以被其他.c文件访问
};

静态全局变量不能被其他.C文件访问

//extern static int a; //static关键字的一个作用就是限制变量的范围,即作用域 不能被其他.C文件访问

枚举声明

typedef enum{red,blue,green}color;//可以被其他.c文件访问

结构体位域声明
在嵌入式领域 几乎位域运算符的使用必不可少,这种处理的目的是为了给寄存器的某个位设置某个值,,或者对于一些标志位只有0和1的值,可以大大节省空间,其中位于的运算指标: 2 n 2^{n} 2n-1
举例:unsigned int bit:3; 那么 2 3 2^{3} 23-1=0-7 总共8个字符 也就是这个变量的最大值最多=7,最小值=0
注意:上面的变量用unsigned无符号修饰,所以取值范围:0-7 如果是有符号,请看下面说明。
位域变量的数据类型很重要
在这里插入图片描述
注意
在位域结构体中,常常使用结构体嵌套联合体,联合体在嵌套结构体,目的:联合体内的变量和联合体内的结构体共用一块内存保存数据,对联合体变量【uint32】赋值,就是对联合体内的结构体【bits】赋值,具体请看后面的代码实操
重点理解
【1】第一种赋值方式对uint32赋值,由于联合体内的变量共用一块内存,那么结构体内的uint16 | uint1 | 那个未使用占15个位的匿名变量将均分uint32的值

值分配的原则
【1】联合体内的结构体变量 从上到下 低字节-高字节
如uint32 = 0x0001ffff; 【十六进制 从左到右 高字节-低字节】
那么uint16=ffff 【占16个位 范围:0-65535】
uint1=1 【占1个位 范围:0-1】
匿名15位=0 【占15个位 范围:0- 2 15 2^{15} 215-1】
注意
联合体内的位域变量:16位+1位+15位=32位
和联合体内的uint32 = 32位相等
如此一来他们共用一块4字节的空间,赋值的时候不会出错。
【2】联合体内的位域变量赋值
先做初始化:
memset(&结构体栈地址,0x00,sizeof(结构体别名));目的:联合体内的所有变量=0
uint16=0xffff;
uint1=0x1;
此时想获取全部值,就uint32=0x0001FFFF
(高字节-低字节)
实例加深记忆
在这里插入图片描述
在这里插入图片描述

//位域结构体 常用于嵌入式寄存器设置位
typedef struct{
    union{//记住联合体共用一块内存 如同一笔钱  赋值的时候类比给钱
          //[1]家长可以给每个孩子钱 [2]每个孩子凑成的钱=家长的钱  孩子的个头不同 变量大小不同 分的钱也不同
        unsigned int uint32; //无符号整形范围 类比家长
        struct{ //结构体内部变量 类比孩子
                unsigned int uint16:16;//用于保存16位数据 范围:0-65535
                unsigned int uint1:1;  //用于保存1个位值  范围:0-1
                unsigned int :15;   //无用 只作为对齐填充,默认情况下值都是0
        }bits;
    }UNION;
}str_union;
extern str_union bitstruct;//可以被其他.c文件访问

【3】头文件源码

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

/* 全局变量 整形 结构体 枚举 使用exterm关键字声名
 * 目的:其他文件通过添加本文件头文件,可以使用这些变量 修改值|获取值|传参等*/
typedef  struct {
    int age;//可以被其他.c文件访问
}node_t;
extern node_t age_t;//可以被其他.c文件访问
extern int global;  //可以被其他.c文件访问
extern bool global_bool;//可以被其他.c文件访问
extern int array[10];//可以被其他.c文件访问
extern char str[8];//可以被其他.c文件访问
extern "C"{//使用C语言的编译规范 因为C++11警告在其他.c文件给p赋值字符串
    extern char *p;//可以被其他.c文件访问
};

//extern static int a; //static关键字的一个作用就是限制变量的范围,即作用域 不能被其他.C文件访问

typedef enum{red,blue,green}color;//可以被其他.c文件访问

//位域结构体 常用于嵌入式寄存器设置位
typedef struct{
    union{//记住联合体共用一块内存 如同一笔钱  赋值的时候类比给钱
          //[1]家长可以给每个孩子钱 [2]每个孩子凑成的钱=家长的钱  孩子的个头不同 变量大小不同 分的钱也不同
        unsigned int uint32; //无符号整形范围 类比家长
        struct{ //结构体内部变量 类比孩子
                unsigned int uint16:16;//用于保存16位数据 范围:0-65535
                unsigned int uint1:1;  //用于保存1个位值  范围:0-1
                unsigned int :15;   //无用 只作为对齐填充,默认情况下值都是0
        }bits;
    }UNION;
}str_union;
extern str_union bitstruct;//可以被其他.c文件访问

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void setTextEdit();//显示所有值
    void setColor(color val);//接收枚举变量

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H


【4】mianwindow.c源文件解析

全局变量定义处,必不可少
在定义时可以赋值和不赋值,根据需求去写

/*全局变量定义处*/
node_t age_t;
int global;
int array[10]={0};
char str[8]="hello";//最多可存储8个字符
char *p="NULL";
bool global_bool=false;
str_union bitstruct;

变量初始化
对于结构体而言,一般使用这种方式初始化

memset(&bitstruct,0x00,sizeof (bitstruct));

使用两个函数来显示操作的记录

//设置显示文本
void MainWindow::setTextEdit()
{
    ui->textEdit->append(QString("年龄=%1").arg(age_t.age));
    ui->textEdit->append(tr("global=%1").arg(global));
    ui->textEdit->append(tr("global_bool=%1").arg(global_bool));
    ui->textEdit->append(tr("enum red=%1").arg(red));
    ui->textEdit->append(tr("array[0]=%1").arg(*array));//只获取第一个值
    ui->textEdit->append(tr("array[2]=%1").arg(array[2]));//只获取第3个值
    ui->textEdit->append(tr("str=%1").arg(str));
    ui->textEdit->append(tr("p=%1").arg(p));
    if(global_bool ==true)
    {
       qDebug("孩子uint16->hex=0x%x ",bitstruct.UNION.bits.uint16);
       qDebug("孩子uint1->hex=0x%x ",bitstruct.UNION.bits.uint1);
       qDebug("家长uint32->hex=0x%x \r\n",bitstruct.UNION.uint32);
    }
}

//接收一个枚举变量值
void MainWindow::setColor(color val)
{
    ui->textEdit->append(tr("enum green=%1").arg(val));
}


【5】源文件源码

#include "mainwindow.h"
#include "ui_mainwindow.h"
/*全局变量定义处*/
node_t age_t;
int global;
int array[10]={0};
char str[8]="hello";//最多可存储8个字符
char *p="NULL";
bool global_bool=false;
str_union bitstruct;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    global=100;//全局变量初始化
    memset(&bitstruct,0x00,sizeof (bitstruct));
    ui->textEdit->append(QString("结构体所有值=%1").arg(bitstruct.UNION.uint32));
}

MainWindow::~MainWindow()
{
    delete ui;
}
//设置显示文本
void MainWindow::setTextEdit()
{
    ui->textEdit->append(QString("年龄=%1").arg(age_t.age));
    ui->textEdit->append(tr("global=%1").arg(global));
    ui->textEdit->append(tr("global_bool=%1").arg(global_bool));
    ui->textEdit->append(tr("enum red=%1").arg(red));
    ui->textEdit->append(tr("array[0]=%1").arg(*array));//只获取第一个值
    ui->textEdit->append(tr("array[2]=%1").arg(array[2]));//只获取第3个值
    ui->textEdit->append(tr("str=%1").arg(str));
    ui->textEdit->append(tr("p=%1").arg(p));
    if(global_bool ==true)
    {
       qDebug("孩子uint16->hex=0x%x ",bitstruct.UNION.bits.uint16);
       qDebug("孩子uint1->hex=0x%x ",bitstruct.UNION.bits.uint1);
       qDebug("家长uint32->hex=0x%x \r\n",bitstruct.UNION.uint32);
    }
}

//接收一个枚举变量值
void MainWindow::setColor(color val)
{
    ui->textEdit->append(tr("enum green=%1").arg(val));
}


【6】main文件解析+源码

从mainwindow.c 到main.c就是本次项目的重点,
我们需要在main.c获取mianwindow.c里面的变量,需要做两点:
【1】在main.c添加mianwindow.c的头文件
【2】在mianwindow.c/h文件中 声明 定义全局变量

以下代码在嵌入式或者其他领域都是通用性的,请大家仔细阅读,并理解通透

#include "mainwindow.h"
#include <QDebug>
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;

    age_t.age=100; //某个.c文件的全局结构体变量 在这里赋值
    qDebug()<<age_t.age;
    w.setTextEdit();
    global =120;    //某个.c文件的全局变量 在这里赋值
    w.setTextEdit();
    w.setColor(green);//某个.c文件的全局枚举变量 在这里赋值
    //mainwindow数组修改值
    array[0]=1;//赋值方式1
    array[1]=2;
    *(array+2)=3;//赋值方式2

    //修改字符串值
    str[0]='K';
    w.setTextEdit();

    //修改指针值
    p="ignore waring";

    global_bool=true;//某个.c文件的全局布尔变量 在这里赋值

    /*unsigned int 占4字节 有32位 在下面的举例中 uint16 占unsigned int[0-31]中的低16位 0-15 可看成unsigned short
      uint1 占unsigned int中的低17位 在16 其余不用的17-31保留复位值 */
    //给结构体-联合体-结构体位设置值 分散设置
    memset(&bitstruct,0x00,sizeof(bitstruct));//初始化的一种方式 复位全部为零
    w.setTextEdit();
    bitstruct.UNION.bits.uint16=0xffff;//2n次方 n=16 等65536 范围:0-65535 hex=0x0000 - 0xFFFF
    bitstruct.UNION.bits.uint1=1;      //2n次方 n=1  等2     范围:0-1 hex=0x0 - 0x1
    w.setTextEdit();
    //给结构体-联合体-结构体位设置值   一次性设置
    memset(&bitstruct,0x00,sizeof(bitstruct));
    bitstruct.UNION.uint32 |=(unsigned int)1<<16 ; //设置uint1 这个位=1 其他位保持不变  【嵌入式寄存器必用】
    w.setTextEdit();
    bitstruct.UNION.uint32 |=(unsigned int)1<<15 ; //设置uint16 最高位=1 其他位保持不变 【嵌入式寄存器必用】
    w.setTextEdit();
    bitstruct.UNION.uint32 =0x00018000;//将上面的两步一次性赋值
    w.setTextEdit();
    memset(&bitstruct,0x00,sizeof(bitstruct));
    bitstruct.UNION.uint32 =0x00018000;//将上面的两步一次性赋值
    bitstruct.UNION.uint32 &= ~((unsigned int)1<<16);//清空uint1这个位 其他位保持不变 【嵌入式寄存器必用】
    w.setTextEdit();
    //初始化的另一种方式 复位全部为零
    int arry=0x00;
    memcpy(&bitstruct,&arry,sizeof (arry));
    w.setTextEdit();

    w.show();
    return a.exec();
}


【7】编译-链接-运行结果

打印结果

结构体所有值=0
年龄=100
global=100
global_bool=0
enum red=0
array[0]=0
array[2]=0
str=hello
p=NULL
年龄=100
global=120
global_bool=0
enum red=0
array[0]=0
array[2]=0
str=hello
p=NULL
enum green=2
年龄=100
global=120
global_bool=0
enum red=0
array[0]=1
array[2]=3
str=Kello
p=NULL
年龄=100
global=120
global_bool=1
enum red=0
array[0]=1
array[2]=3
str=Kello
p=ignore waring
年龄=100
global=120
global_bool=1
enum red=0
array[0]=1
array[2]=3
str=Kello
p=ignore waring
年龄=100
global=120
global_bool=1
enum red=0
array[0]=1
array[2]=3
str=Kello
p=ignore waring
年龄=100
global=120
global_bool=1
enum red=0
array[0]=1
array[2]=3
str=Kello
p=ignore waring
年龄=100
global=120
global_bool=1
enum red=0
array[0]=1
array[2]=3
str=Kello
p=ignore waring
年龄=100
global=120
global_bool=1
enum red=0
array[0]=1
array[2]=3
str=Kello
p=ignore waring
年龄=100
global=120
global_bool=1
enum red=0
array[0]=1
array[2]=3
str=Kello
p=ignore waring

文本框一次显示不完,输出结果就是上面这段,可以对比源码观看,效果更佳
在这里插入图片描述

在这里插入图片描述


位域结构体实例运行结果

11:01:10: Starting C:\Users\sujieyin\Desktop\QT\build-TEST-Desktop_Qt_5_14_2_MinGW_64_bit-Debug\debug\TEST.exe ...
100
孩子uint16->hex=0x0 
孩子uint1->hex=0x0 
家长uint32->hex=0x0 

孩子uint16->hex=0xffff 
孩子uint1->hex=0x1 
家长uint32->hex=0x1ffff 

孩子uint16->hex=0x0 
孩子uint1->hex=0x1 
家长uint32->hex=0x10000 

孩子uint16->hex=0x8000 
孩子uint1->hex=0x1 
家长uint32->hex=0x18000 

孩子uint16->hex=0x8000 
孩子uint1->hex=0x1 
家长uint32->hex=0x18000 

孩子uint16->hex=0x8000 
孩子uint1->hex=0x0 
家长uint32->hex=0x8000 

孩子uint16->hex=0x0 
孩子uint1->hex=0x0 
家长uint32->hex=0x0 

在这里插入图片描述


  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Qt历险记

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值