最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

c語言之char*和unsigned?char*的區(qū)別及說明

 更新時間:2023年08月01日 09:29:05   作者:guotianqing  
這篇文章主要介紹了c語言之char*和unsigned?char*的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教

最近在項目中遇到了一個編譯警告,是因為定義的變量為char[],而在使用時作為函數(shù)的unsigned char*類型的參數(shù)調用。

這個警告很容易避免,但是char*和unsigned char*到底有什么區(qū)別呢?

char 和 unsigned char 的區(qū)別

在C中,默認的基礎數(shù)據(jù)類型均為signed,如定義變量為int,long等,都為有符號的。如果要定義無符號類型,必須顯式地在變量類型前加unsigned。

char vs unsigned char

  • 相同點:在內存中都是一個字節(jié),8位(2^8=256),都能表示256個數(shù)字
  • 不同點:char的最高位為符號位,因此char能表示的數(shù)據(jù)范圍是-128~127,unsigned char沒有符號位,因此能表示的數(shù)據(jù)范圍是0~255

實際使用中,如普通的賦值,讀寫文件和網(wǎng)絡字節(jié)流都沒有區(qū)別,不管最高位是什么,最終的讀取結果都一樣,在屏幕上面的顯示可能不一樣。

但是要把一個char類型的變量賦值給int、long等數(shù)據(jù)類型或進行類似的強制類型轉換時時,系統(tǒng)會進行類型擴展,這時區(qū)別就大了。對于char類型的變量,系統(tǒng)會認為最高位為符號位,然后對最高位進行擴展,即符號擴展。若最高位為1,則擴展到int時高位都以1填充。

對于unsigned char類型的變量,系統(tǒng)會直接進行無符號擴展,即0擴展。擴展的高位都以0填充。所以在進行類似的操作時,如果char和unsigned char最高位都是0,則結果是一樣的,若char最高位為1,則結果會大相徑庭。

可以使用的下面的小程序驗證一下:

#include <stdio.h>
static void func(unsigned char uc)
{
    char c;
    int i, j;
    unsigned int ui, uj;
    c = uc;
    i = (int)c;
    j = (int)uc;
    ui = (unsigned int)c;
    uj =(unsigned int)uc;
    printf("%%c: %c, %c\n", c, uc);
    printf("%%x: %x, %x\n", c, uc);
    printf("%%u: %u, %u\n", ui, uj);
    printf("%%d: %d, %d\n", i, j);
}
int main(int argc, char *argv[])
{
    func(0x80);
    func(0x7f);
    return 0;
}

運行結果如下:

%c: ?, ?
%x: ffffff80, 80
%u: 4294967168, 128
%d: -128, 128
---------------------------
%c:, 
%x: 7f, 7f
%u: 127, 127
%d: 127, 127

對于char來說,0x80用二進制表示為1000 0000,當它作為char賦值給unsigned int或 int 時,系統(tǒng)認為最高位是符號位,會對最高位進行擴展。而0x7F用二進制表示為0111 1111,最高位為0,不會擴展。

對于unsigned char來說,不管最高位是0,還是1,都不會做擴展。

char* 和 unsigned char*區(qū)別說明

char* 和 unsigned char* 也具有類似的區(qū)別,如下面測試程序所示:

#include <stdio.h>
int main(int argc, char *argv[])
{
    unsigned char k = 0;
    int i = -1;
    short a = -12345;
    char *p;
    unsigned char *q;
    printf("sizeof(i) = %d\n",sizeof(i));
    printf("sizeof(a) = %d\n",sizeof(a));
    printf("-----------------------------\n");
    printf("begin p(char):\n");
    p = (char*)&a;
    printf("a = %u | %d\n",a,a);
    for(k=0;k<sizeof(a);k++)
    {
        printf("0x%x ",*(p++));
    }
    printf("\n");
    p = (char*)&i;
    printf("i = %u | %d\n",i,i);
    for(k=0;k<sizeof(i);k++)
    {
        printf("0x%x ",*(p++));
    }
    printf("\n");
    printf("-1 > 0u: %s\n",(-1>0u ? "true":"false"));
    printf("-----------------------------\n");
    printf("begin q(unsigned char):\n");
    q = (unsigned char*)&a;
    printf("a = %u | %d\n",a,a);
    for(k=0;k<sizeof(a);k++)
    {
        printf("0x%x ",*(q++));
    }
    printf("\n");
    q = (unsigned char*)&i;
    printf("i = %u | %d\n",i,i);
    for(k=0;k<sizeof(i);k++)
    {
        printf("0x%x ",*(q++));
    }
    printf("\n");
    printf("-1 > 0u: %s\n",(-1>0u ? "true":"false"));
    return 0;
}

輸出結果為:

sizeof(i) = 4
sizeof(a) = 2
-----------------------------
begin p(char):
a = 4294954951 | -12345
0xffffffc7 0xffffffcf 
i = 4294967295 | -1
0xffffffff 0xffffffff 0xffffffff 0xffffffff 
-1 > 0u: true
-----------------------------
begin q(unsigned char):
a = 4294954951 | -12345
0xc7 0xcf 
i = 4294967295 | -1
0xff 0xff 0xff 0xff 
-1 > 0u: true

char*是有符號的,如果大于127即0x7F的數(shù)就是負數(shù)了,使用%x格式化輸出,系統(tǒng)自動進行了符號擴展,就會產(chǎn)生變化。

所以在涉及到類型提升的上下文中,要注意使用char*和unsinged char*的區(qū)別。

幾個區(qū)別:const char *, unsigned char *

1.char*是有符號的, 如果大于127即0x7F的數(shù)就是負數(shù)了,使用%x格式化輸出,就會產(chǎn)生變化,所以使用%x格式化輸出數(shù)據(jù)時,記得一定要轉換成無符號類型;

2.char *是字符串,以'/0'為結束符,unsigned char *是普通的指針;

3.有符號的字符型數(shù)據(jù)C7,CF分別傳入printf,此時會將類型提升為int,由于是有符號數(shù),所以符號位要進行擴展,得到FFFFFFCF和FFFFFFC7。無符號的字符型數(shù)據(jù)C7,CF分別傳入printf,此時會將類型提升為unsigned int,由于無符號數(shù)不進行符號位擴展,所以得到000000CF和00000C7。

總結

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關文章

  • C++中const char*、char const*、char * const三者的區(qū)別

    C++中const char*、char const*、char * const三者的區(qū)別

    這篇文章主要介紹了C++中const char*、char const*、char * const三者的區(qū)別,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C語言之數(shù)組名與數(shù)組起始地址的關系解析

    C語言之數(shù)組名與數(shù)組起始地址的關系解析

    這篇文章主要介紹了C語言之數(shù)組名與數(shù)組起始地址的關系,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C++的程序流程結構你了解多少

    C++的程序流程結構你了解多少

    這篇文章主要為大家詳細介紹了C++的程序流程結構,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • C語言詳細分析講解struct與union使用方法

    C語言詳細分析講解struct與union使用方法

    最近開始自學C語言,從最基礎部分的開始學起。今天看書的時候注意到了struct和union似乎很像,除了名字不同,看起來幾乎沒有區(qū)別。<BR>既然C中定義了struct和union兩個關鍵字,那么它們肯定是有區(qū)別的,在查了一些資料之后我來總結一下他們的使用
    2022-04-04
  • 基于C++實現(xiàn)kinect+opencv 獲取深度及彩色數(shù)據(jù)

    基于C++實現(xiàn)kinect+opencv 獲取深度及彩色數(shù)據(jù)

    本文的主要思想是Kinect SDK 讀取彩色、深度、骨骼信息并用OpenCV顯示,非常的實用,有需要的小伙伴可以參考下
    2015-12-12
  • C++的靜態(tài)聯(lián)編和動態(tài)聯(lián)編詳解

    C++的靜態(tài)聯(lián)編和動態(tài)聯(lián)編詳解

    這篇文章主要介紹了C++的靜態(tài)聯(lián)編和動態(tài)聯(lián)編詳解,對于深入理解C++編譯運行原理有很大幫助,需要的朋友可以參考下
    2014-07-07
  • C++?move()函數(shù)及priority_queue隊列使用記錄

    C++?move()函數(shù)及priority_queue隊列使用記錄

    move(obj)函數(shù)的功能是把obj當做右值處理,可以應用在對象的移動上,這篇文章主要介紹了C++?move()函數(shù)及priority_queue隊列使用記錄,需要的朋友可以參考下
    2023-01-01
  • C++ 情懷游戲掃雷的實現(xiàn)流程詳解

    C++ 情懷游戲掃雷的實現(xiàn)流程詳解

    掃雷是電腦上很經(jīng)典很經(jīng)典的傳統(tǒng)老游戲,從小編第一次摸到計算機開始就玩過掃雷,雖然當時并不理解玩法原理,但終是第一次玩電腦游戲,下面來從掃雷的前世今生講起
    2021-11-11
  • C語言實現(xiàn)UDP通信

    C語言實現(xiàn)UDP通信

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)UDP通信,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C++線程同步實例分析

    C++線程同步實例分析

    這篇文章主要介紹了C++線程同步實例分析,以實例的形式較為深入的分析了C++的線程同步問題,是一個較為經(jīng)典的線程同步問題,需要的朋友可以參考下
    2014-10-10

最新評論

双鸭山市| 子长县| 呼图壁县| 滦南县| 东安县| 洛浦县| 怀仁县| 英吉沙县| 阳城县| 穆棱市| 凤城市| 盐池县| 遂溪县| 安丘市| 井陉县| 泽普县| 昆明市| 巴中市| 寿阳县| 错那县| 青铜峡市| 鄂温| 大石桥市| 普兰店市| 安塞县| 西林县| 积石山| 成武县| 安远县| 甘谷县| 潞西市| 马边| 韶关市| 宜兰市| 钦州市| 银川市| 青州市| 东乡| 白朗县| 德阳市| 北碚区|