首页 > 其他分享 >c语言学习 volatile __attribute__ const

c语言学习 volatile __attribute__ const

时间:2024-08-02 17:52:57浏览次数:17  
标签:__ const 常量 int attribute 编译器 volatile 数组

1 volatile

在C语言中,volatile是一个类型修饰符,用于告诉编译器某个变量的值可能会被外部因素改变,从而避免编译器对该变量进行优化。这在多线程编程或硬件编程中非常重要。

用法

volatile int myVar;

何时使用 volatile
硬件寄存器:当变量映射到某个硬件寄存器。
中断服务例程:当变量在一个中断服务程序中被修改。
多线程环境:当变量在一个线程中被修改,而在另一个线程中被读取。
特点
编译器每次访问 volatile 变量时都会读取最新的值,而不是使用缓存的值。
适用于需要确保变量的最新状态被获取的场景,防止优化导致的数据不一致。
示例

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

volatile int flag = 0;

void* thread_function(void* arg) {
    // 模拟某种条件下改变变量
    sleep(1);
    flag = 1;
    return NULL;
}

int main() {
    pthread_t thread;
    pthread_create(&thread, NULL, thread_function, NULL);

    while (flag == 0) {
        // 这里会持续循环,直到flag被其他线程改变
    }

    printf("Flag changed!\n");
    pthread_join(thread, NULL);
    return 0;
}

在这个例子中,flag 被定义为 volatile,确保在主线程中读取时能获取到被子线程修改的最新值。

2 attribute_

u8 DmaTxBuffer[MAX_PKT_LEN] __attribute__ ((aligned(64)));

这段代码是C语言中的一段声明和定义,具体解释如下:

u8: 这通常是一个类型定义,表示一个无符号的8位整数(unsigned char)。在一些编程环境中,u8 被用作 uint8_t 的缩写,它表示一个单字节的数据类型。uint8_t 是C语言中定义的无符号整数类型,用于表示一个占用一个字节(即8位)的数。它常用于低级编程,特别是在嵌入式系统和硬件相关的代码中。请注意,不同的编程环境可能有不同的类型定义习惯,具体取决于代码所在的上下文。

DmaTxBuffer: 这是声明的变量名,表示一个数组的名称。这个数组用于存储数据。

MAX_PKT_LEN: 这应该是一个先前定义的常量或宏,表示数组的最大长度或最大数据包长度。具体的值依赖于程序的上下文。使用这个宏的目的是为了让数组的大小可配置或易于更改,同时保证类型安全性。实际的数组大小将在编译时确定。

attribute ((aligned(64))): 这是GCC编译器特定的属性,用于定义内存对齐。这里的意思是要保证DmaTxBuffer这个数组首地址是按照64字节对齐的。这很重要在涉及DMA(直接内存访问)操作时,一些系统需要数据的特定对齐以进行高效的访问或者满足特定的硬件需求。确保数据的正确对齐可以防止一些潜在的性能问题或错误行为。在这个例子中,通过该属性告诉编译器为这个数组分配的内存应该按64字节对齐。这对于某些硬件操作和系统性能优化至关重要。

综上所述,这段代码定义了一个名为 DmaTxBuffer 的数组,该数组用于存储数据包的字节数据(假设是DMA传输相关的缓冲区),其大小由 MAX_PKT_LEN 定义,并且要求内存地址按照64字节对齐。这种声明通常出现在嵌入式系统编程或涉及直接内存操作的场合中。

3 const

在C语言中,const 是一个关键字,用于指定一个变量的值在其生命周期内不能被修改。这对于提高代码的安全性和可读性非常有用。

用法
声明常量

const int maxValue = 100;
maxValue 的值不能被改变。

指向常量的指针

const int *ptr;

这里的 ptr 是一个指向常量整数的指针,不能通过 ptr 修改其所指向的值,但 ptr 本身可以指向不同的地址。

常量指针

int *const constPtr;

这是一个常量指针,指向一个整数,意味着指针本身的地址不能修改,但可以通过它修改所指向的值。

常量数组

const int array[] = {1, 2, 3, 4};

定义一个常量数组,不能改变数组的元素。

示例

#include <stdio.h>

void printValue(const int *value) {
    printf("Value: %d\n", *value);
}

int main() {
    const int a = 42;
    // a = 50;  // 编译错误:不能修改常量

    printValue(&a);  // 传递常量的地址

    return 0;
}

优势
保护性: 防止意外修改重要数据。
优化: 编译器可以对常量进行更多优化。
可读性: 表明某些值在函数中是只读的。
注意事项
使用 const 并不意味着数据是只读的,只是限制了通过该指针或变量的修改。
在涉及指针和数组时,理解 const 的效果非常重要。

标签:__,const,常量,int,attribute,编译器,volatile,数组
From: https://blog.csdn.net/baidu_34971492/article/details/140788974

相关文章

  • FPGA MIPI DSI LCD彩条显示
    1MIPI简介MIPI(MobileIndustryProcessorInterface)是一种针对移动设备和嵌入式系统的接口标准,由MIPI联盟制定。其主要目的是提高移动设备之间的通信效率,降低功耗,并支持高速数据传输。MIPI的主要标准包括:MIPIDSI(DisplaySerialInterface):用于连接显示模块,支持高清视......
  • Prism视图模型定位器(ViewModelLocator)
    视图模型定位器(ViewModelLocator)依照“标准命名约定”将视图(View)中的数据上下文链接到视图模型(ViewModel)的实例。自动绑定视图模型Prism视图模型定位器(ViewModelLocator)有一个AutoWireViewModel属性:当设置为true时,AutoWireViewModelChanged事件调用类中的ViewMod......
  • mvnan settings pom.xml
    <?xmlversion="1.0"encoding="UTF-8"?><!--LicensedtotheApacheSoftwareFoundation(ASF)underoneormorecontributorlicenseagreements.SeetheNOTICEfiledistributedwiththisworkforadditionalinformationregardi......
  • docker安装Jenkins
    1、拉取jenkinsdockerpulljenkins/jenkins2、配置jenkins路径mkdir-p/data/jenkins_home3、启动jenkinsdockerrun-d-uroot-p8081:8080-p50000:50000--namejenkins--restart=always-v/data/jenkins_home:/var/jenkins_home-v/etc/localtime:/etc/local......
  • 无法将为“Microsoft.Office.Interop.Word.ApplicationClass”的 COM 对象强制转换为
    原文链接:https://blog.csdn.net/Castlehe/article/details/1243806481.错误原因安装了多版本的Office安装过WPS后没正常卸载2.解决方式2.1office多版本问题导致的以下四个操作基本覆盖常见原因了,可以从2.1.1尝试,每尝试一种,就去试一下看问题解决了没有,如果已经解决了,其他操作就......
  • redis配置(不全)
    1、pom添加依赖<!--redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>2、Redis配置类packagecom.exam.config;importcom.......
  • mysql密码的初始化,修改与重置
    目录mysql密码的初始化,修改与重置郑重说明:初始化密码(第一次使用前要初始化密码)查看密码(已登录状态)修改密码(已知原密码)忘记密码(密码找回)诺mysql装在Windows诺mysql装在Linux结尾systemctl为什么可以管理mysql附件mysql密码的初始化,修改与重置郑重说明:文章guixiang原创,全......
  • webservice 類型映射
    a1@1deMacBook-Prophone1%wsdl2h-ophoneService.hphoneService.wsdl-tapi.batSavingphoneService.h**ThegSOAPWSDL/WADL/XSDprocessorforCandC++,wsdl2hrelease2.8.135**Copyright(C)2000,2024GeniviaInc.AllRightsReserved.**Thewsdl......
  • dubbo和openfein的区别
    Dubbo和OpenFeign是Java生态中两个广泛使用的远程过程调用(RPC)框架,两者主要在**稳定性、独立性和易用性**等方面有所区别。具体分析如下:1.**稳定性**-**Dubbo**:基于TCP进行传输,处于更底层的模型,数据传输稳定,特别是在处理大量并发请求时表现优秀[^1^]。-**OpenFeign**:使用......
  • 8.1 NOIP 模拟赛总结
    8.1NOIP模拟赛总结T1给你一个含有\(n\)个问号的形如max(?,max(?,min(?,?)))的表达式,将\(1...n\)填入\(n\)个问号中,求表达式一共有多少种可能的答案。首先写的\(10\pts\)的全排列,然后想了一会想不出来,就直接扬了。直接是二叉树,很神奇。T2首先想暴力。发现每回......