printf("%x,%x",ptr1[-1],*ptr2);大小端,寻址!

本文通过一个具体的C语言程序示例,详细解释了数组寻址的两种不同方式:&a+1 和 (int)a+1 的含义及区别,并探讨了它们在内存中的表现形式,特别是针对小端存储系统的输出结果。

 (2011-02-17 23:33:27

大小端,数组寻址,综合例子

来自C语言深度解剖

#include "stdafx.h"
#include "string.h"

int main()
{
int a[5]={1,2,3,4,5};
int *ptr1=(int *)(&a+1); //1
int *ptr2=(int *)((int)a+1); //2
printf("%x,%x",ptr1[-1],*ptr2);//3
return 0;
}

内存中的值如图所示,为简化问题,假设数组内存从0开始。因为我们的pc机采用的小端存储(这个很重要),所以会出现如图所示的内部分布。如果a+1的方 式寻址,含义是按照数组元素的大小为寻址单元,但是数组取了一次地址后+1,则是按照数组本身大小作为寻址单位了。所以&a+1指向的应该是20

而a[i]表示的含义是 a + i * sizeof(a[0])c语言不对下标做检查,所以负数也无所谓,那么指向的就是最后一个数5.

2语句呢,先将数组首地址转成int,也就是0,然后用将结果1再转成int指针,而int大小为4,所以这个int应该是4321这四个字节。这个时候大小端的概念就十分有用了,小端存储,所以最后输出的结果应该是02000000.

 


ptr1[-1]是什么意思?*ptr2的值是什么意思?int *ptr2=(int *)((int)a+1)中((int)a+1)怎么理解?

/* main.c STM32F103C8T6 I2C2 -> AHT10 (PB10=SCL, PB11=SDA) SPI1 -> SSD1680 (152x152) res -> PA1 dc -> PA2 cs -> PA3 busy-> PA4 sck -> PA5 (SPI1_SCK) sda -> PA7 (SPI1_MOSI) SPI wrapper prefix: spd_spi_ All code in one file, simple 8x16 font included. */ #include "main.h" #include "i2c.h" #include "spi.h" #include "gpio.h" #include <string.h> #include <stdio.h> #include <stdint.h> /* ------------------------- AHT10 ------------------------- */ #define AHT10_ADDR (0x38 << 1) #define AHT10_CMD_TRIGGER 0xAC #define AHT10_CMD_ARG1 0x33 #define AHT10_CMD_ARG2 0x00 float g_temperature = 0.0f; float g_humidity = 0.0f; /* ------------------------- EPD pins ------------------------- */ #define EPD_RES_LOW() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET) #define EPD_RES_HIGH() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET) #define EPD_DC_CMD() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET) #define EPD_DC_DATA() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET) #define EPD_CS_LOW() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET) #define EPD_CS_HIGH() HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET) #define EPD_BUSY_LEVEL GPIO_PIN_SET #define EPD_IS_BUSY() (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_4) == EPD_BUSY_LEVEL) /* ------------------------- display ------------------------- */ #define EPD_WIDTH 152 #define EPD_HEIGHT 152 #define EPD_BUFFER_BYTES ((EPD_WIDTH * EPD_HEIGHT) / 8) static uint8_t frame_buf[EPD_BUFFER_BYTES]; extern I2C_HandleTypeDef hi2c2; extern SPI_HandleTypeDef hspi1; /* ------------------------- simple 8x16 font ------------------------- */ static const uint8_t font_8x16_digits[][16] = { /* '0' */ {0x00,0x3C,0x66,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, /* '1' */ {0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00}, /* '2' */ {0x00,0x3C,0x66,0xC3,0x03,0x06,0x0C,0x18,0x30,0x60,0xC0,0xFF,0x00,0x00,0x00,0x00}, /* '3' */ {0x00,0x3C,0x66,0xC3,0x03,0x06,0x1C,0x06,0x03,0x03,0x66,0x3C,0x00,0x00,0x00,0x00}, /* '4' */ {0x00,0x06,0x0E,0x1E,0x36,0x66,0xC6,0xFF,0x06,0x06,0x06,0x1F,0x00,0x00,0x00,0x00}, /* '5' */ {0x00,0xFF,0xC0,0xC0,0xC0,0xFC,0xCE,0x03,0x03,0x03,0x66,0x3C,0x00,0x00,0x00,0x00}, /* '6' */ {0x00,0x3C,0x66,0xC3,0xC0,0xFC,0xCE,0xC3,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, /* '7' */ {0x00,0xFF,0x03,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00}, /* '8' */ {0x00,0x3C,0x66,0xC3,0xC3,0x66,0x3C,0x66,0xC3,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, /* '9' */ {0x00,0x3C,0x66,0xC3,0xC3,0xC3,0x67,0x3F,0x03,0xC3,0x66,0x3C,0x00,0x00,0x00,0x00}, }; static const uint8_t font_8x16_misc[][16] = { /* '.' */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, /* '-' */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, /* '%' */ {0x00,0xC1,0xC6,0x0C,0x18,0x30,0x60,0xC1,0x86,0x0C,0x18,0x30,0x60,0x00,0x00,0x00}, /* ':' */ {0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00}, /* 'C' */ {0x00,0x0F,0x1F,0x38,0x70,0x70,0x70,0x70,0x70,0x38,0x1F,0x0F,0x00,0x00,0x00,0x00}, /* 'c' */ {0x00,0x00,0x00,0x00,0x1E,0x30,0x60,0x7E,0x66,0x66,0x3E,0x00,0x00,0x00,0x00,0x00}, /* 'T' */ {0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00}, /* 'e' */ {0x00,0x00,0x00,0x00,0x1E,0x30,0x7E,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00,0x00}, /* 'm' */ {0x00,0x00,0x00,0x00,0xEE,0x92,0x92,0x92,0x92,0x92,0x92,0x00,0x00,0x00,0x00,0x00}, /* 'p' */ {0x00,0x00,0x00,0x00,0xDE,0x63,0x63,0x63,0x7E,0x60,0x60,0x00,0x00,0x00,0x00,0x00}, /* 'H' */ {0x00,0xC3,0xC3,0xC3,0xC3,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0x00,0x00,0x00,0x00,0x00}, /* 'u' */ {0x00,0x00,0x00,0x00,0xC3,0xC3,0xC3,0xC3,0xC3,0xC7,0x3B,0x00,0x00,0x00,0x00,0x00}, /* 'i' */ {0x00,0x18,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00}, /* ' ' */ {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} }; static const uint8_t *get_font_ptr(char c) { if(c >= '0' && c <= '9') return font_8x16_digits[c - '0']; switch(c) { case '.': return font_8x16_misc[0]; case '-': return font_8x16_misc[1]; case '%': return font_8x16_misc[2]; case ':': return font_8x16_misc[3]; case 'C': return font_8x16_misc[4]; case 'c': return font_8x16_misc[5]; case 'T': return font_8x16_misc[6]; case 'e': return font_8x16_misc[7]; case 'm': return font_8x16_misc[8]; case 'p': return font_8x16_misc[9]; case 'H': return font_8x16_misc[10]; case 'u': return font_8x16_misc[11]; case 'i': return font_8x16_misc[12]; case ' ': return font_8x16_misc[13]; default: return font_8x16_misc[13]; } } /* ------------------------- framebuffer ------------------------- */ static void fb_set_pixel(int x,int y,int color) { if(x<0||x>=EPD_WIDTH||y<0||y>=EPD_HEIGHT) return; int byte_index = (x+y*EPD_WIDTH)/8; int bit = 7-(x&7); if(color) frame_buf[byte_index] &= ~(1<<bit); else frame_buf[byte_index] |= (1<<bit); } static void fb_clear(uint8_t white) { memset(frame_buf, white?0xFF:0x00, EPD_BUFFER_BYTES); } static void fb_draw_char8x16(int x,int y,char c) { const uint8_t *p = get_font_ptr(c); for(int row=0;row<16;row++){ uint8_t bits = p[row]; for(int col=0;col<8;col++){ int bit=(bits&(0x80>>col))?1:0; fb_set_pixel(x+col,y+row,bit); } } } static void fb_draw_string8x16(int x,int y,const char *s) { while(*s){ fb_draw_char8x16(x,y,*s); x+=8; s++; } } /* ------------------------- SPI wrapper ------------------------- */ static void spd_spi_write_cmd(uint8_t cmd) { uint8_t d=cmd; EPD_DC_CMD(); EPD_CS_LOW(); HAL_SPI_Transmit(&hspi1,&d,1,100); EPD_CS_HIGH(); } static void spd_spi_write_data(uint8_t data) { uint8_t d=data; EPD_DC_DATA(); EPD_CS_LOW(); HAL_SPI_Transmit(&hspi1,&d,1,100); EPD_CS_HIGH(); } static void epd_wait_busy(void) { uint32_t timeout=5000; while(EPD_IS_BUSY() && timeout--){ HAL_Delay(1); } } static void epd_init(void) { spd_spi_write_cmd(0x12); // soft reset HAL_Delay(10); epd_wait_busy(); spd_spi_write_cmd(0x01); spd_spi_write_data((EPD_HEIGHT-1)&0xFF); spd_spi_write_data(((EPD_HEIGHT-1)>>8)&0xFF); spd_spi_write_data(0x00); spd_spi_write_cmd(0x0C); spd_spi_write_data(0xD7); spd_spi_write_data(0xD6); spd_spi_write_data(0x9D); spd_spi_write_cmd(0x2C); spd_spi_write_data(0xA8); spd_spi_write_cmd(0x3A); spd_spi_write_data(0x1A); spd_spi_write_cmd(0x3B); spd_spi_write_data(0x08); spd_spi_write_cmd(0x11); spd_spi_write_data(0x03); HAL_Delay(10); } static void epd_display_frame(const uint8_t *buf) { spd_spi_write_cmd(0x24); for(int i=0;i<EPD_BUFFER_BYTES;i++) spd_spi_write_data(buf[i]); spd_spi_write_cmd(0x20); epd_wait_busy(); } static void epd_clear(void) { fb_clear(1); epd_display_frame(frame_buf); } /* ------------------------- AHT10 ------------------------- */ static uint8_t aht10_read(I2C_HandleTypeDef *hi2c,float *t,float *h) { uint8_t cmd[3]={AHT10_CMD_TRIGGER,AHT10_CMD_ARG1,AHT10_CMD_ARG2}; uint8_t data[6]; if(HAL_I2C_Master_Transmit(hi2c,AHT10_ADDR,cmd,3,100)!=HAL_OK) return 1; HAL_Delay(80); if(HAL_I2C_Master_Receive(hi2c,AHT10_ADDR,data,6,100)!=HAL_OK) return 2; uint32_t raw_h=((uint32_t)data[1]<<12)|((uint32_t)data[2]<<4)|((data[3]&0xF0)>>4); uint32_t raw_t=(((uint32_t)(data[3]&0x0F))<<16)|((uint32_t)data[4]<<8)|data[5]; *h=(raw_h/1048576.0f)*100.0f; *t=(raw_t/1048576.0f)*200.0f-50.0f; return 0; } /* ------------------------- UI ------------------------- */ static void draw_temp_hum_ui(float t,float h) { char line1[32],line2[32]; fb_clear(1); snprintf(line1,sizeof(line1),"temp: %.1f C",t); snprintf(line2,sizeof(line2),"humi: %.1f %%",h); fb_draw_string8x16(8,24,line1); fb_draw_string8x16(8,48,line2); epd_display_frame(frame_buf); } /* ------------------------- main ------------------------- */ void SystemClock_Config(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_I2C2_Init(); MX_SPI1_Init(); // reset EPD EPD_RES_HIGH(); HAL_Delay(10); EPD_RES_LOW(); HAL_Delay(20); EPD_RES_HIGH(); HAL_Delay(20); epd_init(); epd_clear(); while(1) { if(aht10_read(&hi2c2,&g_temperature,&g_humidity)==0){ draw_temp_hum_ui(g_temperature,g_humidity); } HAL_Delay(3000); } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; // ??????? HSE,HSI ???? RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; // 8MHz HSE -> 72MHz SYSCLK if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK| RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } } /* CubeMX generated SystemClock_Config and Error_Handler already present */ void Error_Handler(void){__disable_irq();while(1){}} 代码哪里有问题
最新发布
11-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值