久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2368|回復: 15
收起左側

C語言經過位移運算把指針里面的值賦給變量為什么會在高八位上?

[復制鏈接]
回帖獎勵 5 黑幣 回復本帖可獲得 5 黑幣獎勵! 每人限 1 次
ID:1043477 發表于 2022-10-13 11:18 | 顯示全部樓層 |閱讀模式

程序如下,用的是51單片機
#include "RX8F103.h"
#include "intrins.h"
#include <stdio.h>

//從串口發送一個字符
void EUart0_SendOneChar(char c)
{
        ES0=0;                                //發送數據時關串口中斷
        TI0=0;                                //清TI位
        S0BUF = c;                //將待發送字符放入串口數據緩沖寄存器,并開始傳輸。
        while(!TI0);        //等待傳送結束。當字符發送結束后由硬件置位請求中斷,
                                                                //此時while循環結束,而串口中斷處理函數需等到ES重新置1后才可能響應。
        TI0=0;                                //軟件清TI位,亦可在中斷處理函數中清0
        ES0 = 1;                        //開串口中斷
}

void EUart0_SendString(char *st)
{
        while(*st)
        {
                EUart0_SendOneChar(*st++);
        }
}

unsigned char x[50] ={0x1e,0x00,0x00,0x00,0xca,0xfb,0x5f,0xf8,0x8f,0x00,0x1a,0x00,0x02,0xcf,0x81,
                      0xdb,0xff,0xe7,0xc8,0x00,0x20,0x00,0x01,0x5e,0x46,0xf5,0x71,0xd1,0x50,0x00,
                      0x21,0x00,0x01,0xa9,0xe1,0xfc,0xdf,0xc0,0x85,0x00,0x23,0x00,0x02,0xc8,0x44,
                      0xd7,0xf5,0xe9,0x47,0x00};


void main(void)
{        int a1=8;
        int a2=0x8f;
        int a3;

        unsigned char* iKeyP = x;
        CLKCON |= 0x1F;                                //默認所有時鐘打開
        RSTPORTEN = 1;                                //使能復位功能

        UART0PORTEN = 1;                        //串口端口使能
        S0CON = 0x50;                                        //SCON: Mode 1, 8-bit UART, Enable Rcvr
        S0RELH = 0x03;                                //S0RELH + S0RELL  構成波特率設置S0REL[9:0]
        S0RELL = 0xF7;                                //Baud rate  = SYSCK/(16×(1024-S0REL))  SYSCK跟CLKDIV寄存器有關  波特率為115200
        ES0 = 1;                                                        //允許串口中斷位
        EUart0_SendString("RX8F103 IIC Slave Init! V2.0\r\n");
        a1 = ((long)(a1)) << (9);
        a2 = (a2)+(128);
        a3 = *((short*)(iKeyP + (8)));
  while(1)
        {
                printf("Hello RX8F103 UART0\r\n");
                printf("a1==0x%x\r\n",a1);
                printf("a2==0x%x\r\n",a2);
                printf("a3==0x%x\r\n",a3);
        }
}

char putchar (char c)
{
        EUart0_SendOneChar(c);
        return c;
}

以下位打印的結果
RX8F103 IIC Slave Init! V2.0
Hello RX8F103 UART0
a1==0x1000
a2==0x10f
a3==0x8f00
問題在打印a3,a3不應該是a3=0x8f么,而是a3=0x8f00

回復

使用道具 舉報

ID:526108 發表于 2022-10-13 12:49 | 顯示全部樓層
a3 = *((char*)(iKeyP + (8)));
這樣才是8F
回復

使用道具 舉報

ID:883242 發表于 2022-10-13 13:36 | 顯示全部樓層
qq624353765 發表于 2022-10-13 12:49
a3 = *((char*)(iKeyP + (8)));
這樣才是8F

我沒有c51,但是按說有符號數會擴展符號吧?8位的0x8f擴展成16位會當成負數擴展成0xff8f。
回復

使用道具 舉報

ID:844772 發表于 2022-10-13 15:09 | 顯示全部樓層
沒啥不對的啊,你強制類轉換char型指針為short型,short每次走兩個字節,于是讀出來的是:0x8f,0x00兩個數,不就是0x8f00
回復

使用道具 舉報

ID:883242 發表于 2022-10-13 18:27 | 顯示全部樓層
glinfei 發表于 2022-10-13 15:09
沒啥不對的啊,你強制類轉換char型指針為short型,short每次走兩個字節,于是讀出來的是:0x8f,0x00兩個數 ...

大端是0x8f00,小端是0x8f。

8位機本身根本就沒有大小端問題,但是高級語言編譯器有超過1字節的數據類型,那么必然就有大小端問題,取決于具體的編譯器。對于8051來說,Keil C51是大端,IAR8051和SDCC是小端。
回復

使用道具 舉報

ID:384109 發表于 2022-10-13 20:48 | 顯示全部樓層
這個好像是數據在內存存儲方式和C語言缺省排序的問題
回復

使用道具 舉報

ID:844772 發表于 2022-10-14 09:15 | 顯示全部樓層
Hephaestus 發表于 2022-10-13 18:27
大端是0x8f00,小端是0x8f。

8位機本身根本就沒有大小端問題,但是高級語言編譯器有超過1字節的數據類 ...

這不是大小端問題,是偏巧下一個數字是0,它強制類轉換成short,一次提取了兩個字節,合并成一個數。如果加7,也就是 a3 = *((short*)(iKeyP + (7))); 那結果就是0xf88f
回復

使用道具 舉報

ID:883242 發表于 2022-10-14 12:07 | 顯示全部樓層
glinfei 發表于 2022-10-14 09:15
這不是大小端問題,是偏巧下一個數字是0,它強制類轉換成short,一次提取了兩個字節,合并成一個數。如果 ...

short是兩個字節,在內存里面必然有字節序問題,到底是高位在前(小地址)還是低位在前總要有個約定。

16位機、32位機有多字節指令,字節序由指令確定,你可以違反字節序,代價就是代碼長度和運行時間的惡化。以Cortex-M為例,ARM賣出的內核是可以配置成大端或者小端模式,有一個標志位,芯片廠家生產的時候寫死,一旦生產出來大端還是小端已經確定了,目前已知所有Cortex-M單片機都是小端模式。那么根據你的說法,下一數字偏巧是0,根據小端模式高字節在低地址的定義,提取出來的short就是0x008f。

這就叫大端和小端!
回復

使用道具 舉報

ID:384109 發表于 2022-10-14 12:33 | 顯示全部樓層
的確是大小端的問題,簡單的說就是多字節數據在存儲時地址方向的問題,就是存儲地址是增加方向,還是減少方向的問題,不同的芯片會有不同的
回復

使用道具 舉報

ID:883242 發表于 2022-10-17 23:20 | 顯示全部樓層
人中狼 發表于 2022-10-14 12:33
的確是大小端的問題,簡單的說就是多字節數據在存儲時地址方向的問題,就是存儲地址是增加方向,還是減少方 ...

8位機哪來的什么大小端問題?但是編譯器有多字節數據就有大小端問題。至少在8051這個平臺上,大小端問題跟芯片無關,只跟編譯器有關。
回復

使用道具 舉報

ID:1048116 發表于 2022-10-18 09:17 | 顯示全部樓層
51單片機字節存貯是大端模式
回復

使用道具 舉報

ID:883242 發表于 2022-10-18 10:23 | 顯示全部樓層
QW192026 發表于 2022-10-18 09:17
51單片機字節存貯是大端模式

我在5樓的發言——

8位機本身根本就沒有大小端問題,但是高級語言編譯器有超過1字節的數據類型,那么必然就有大小端問題,取決于具體的編譯器。對于8051來說,Keil C51是大端,IAR8051和SDCC是小端。

井底蛤蟆的天空可能只有碗口那么大。
回復

使用道具 舉報

ID:528966 發表于 2022-10-18 16:58 | 顯示全部樓層
qq624353765 發表于 2022-10-13 12:49
a3 = *((char*)(iKeyP + (8)));
這樣才是8F

這是正解
回復

使用道具 舉報

ID:883242 發表于 2022-10-22 20:01 | 顯示全部樓層

16位數據截斷成了8位數據,根本不符合要求,怎么就成了“正解”?
回復

使用道具 舉報

ID:915005 發表于 2022-10-24 13:53 | 顯示全部樓層
glinfei 發表于 2022-10-13 15:09
沒啥不對的啊,你強制類轉換char型指針為short型,short每次走兩個字節,于是讀出來的是:0x8f,0x00兩個數 ...

4樓說得很對 不是 在高八位上 而是 按照short 類型 根據 你給的+8偏移量開始 在數組中取了兩個字節 形成了0x8f00
回復

使用道具 舉報

ID:915005 發表于 2022-10-24 14:03 | 顯示全部樓層
問題的根源 應該還是在各平臺對數據類型的定義的差異上 語言 編譯器和硬件的相關文檔 要拿出來對照
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产一区二区三区久久久久久久久 | 国产一区二区久久久 | 精品亚洲一区二区 | 欧美一区二区三区大片 | 欧美精品一区在线 | 色av一区 | 日韩视频高清 | 亚洲精品电影网在线观看 | 婷婷二区| 天天躁日日躁aaaa视频 | 美女操网站 | 精国产品一区二区三区 | 一级毛片播放 | 暖暖成人免费视频 | 激情五月婷婷丁香 | 国产在线拍偷自揄拍视频 | 国产视频2021 | 国产精品视频999 | 欧美精品片 | 在线观看国产视频 | 成人免费视频在线观看 | 久久久91 | 成人精品一区二区 | 特黄小视频 | 亚洲一区二区精品视频 | 欧美一级免费看 | 天天拍天天插 | 久久久久久亚洲精品 | 中文字幕综合 | 极品销魂美女一区二区 | 国产一区二区三区久久久久久久久 | 久久鲁视频 | 亚洲精品久久久久久久久久久久久 | 天色综合网| 国产电影一区二区 | 精品国产一区一区二区三亚瑟 | 日韩欧美久久 | 丁香久久 | 超碰在线播| 欧美久久一级 | 国产精品2区 |