欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語(yǔ)言char s[]和char* s的區(qū)別

 更新時(shí)間:2021年06月28日 12:03:12   作者:一只不出息的程序員  
本文主要介紹了C語(yǔ)言char s[]和char* s的區(qū)別,詳細(xì)講述了數(shù)組,指針的使用,具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

C語(yǔ)言指針可以代替數(shù)組使用

1、數(shù)組本質(zhì)

數(shù)組是多個(gè)元素的集合,在內(nèi)存中分布在地址連續(xù)的單元中,因此可以通過(guò)其下標(biāo)訪問(wèn)數(shù)組的不同數(shù)組。
例如:
下面展示一些

char s[3] = "0x1";
printf("s2字符串:\n");
printf("%c\n", s[0]);
printf("%c\n", s[1]);
printf("%c\n", s[2]);

2、指針

指針也是一種變量,只不過(guò)它的內(nèi)存單元中保存的是一種標(biāo)識(shí)其他位置的地址,而地址也是整數(shù),在32位平臺(tái)下,就是32位,4個(gè)字節(jié)(bytes)。

指針的指向
指針的指向是指 指針變量所保存的其他的地址單元中 所存放的數(shù)據(jù)類(lèi)型。
例如:

int *ptr;//ptr指針保存的地址所在內(nèi)存單元中的數(shù)據(jù)類(lèi)型是整型
float *p;//這個(gè)p指針指向的內(nèi)存地址存放的元素類(lèi)型就是浮點(diǎn)型

而不管指向的數(shù)據(jù)類(lèi)型是哪種,其實(shí)對(duì)于指針本身的值永遠(yuǎn)是整型,因?yàn)樗4娴牡刂肪褪钦麛?shù)

3、字符數(shù)組

字符數(shù)組首先是數(shù)組,數(shù)組中的元素都是字符。

char s[10];//定義了一個(gè)含有10個(gè)元素的數(shù)組,元素類(lèi)型為字符 %c

C語(yǔ)言中定義一個(gè)變量時(shí),可以初始化,如下:

char s[10] = {"hello world"};

當(dāng)編譯器遇到上面的定義和賦值時(shí),會(huì)將 hello world 和 \0 依次逐個(gè)填入連續(xù)數(shù)組內(nèi)存中。

C語(yǔ)言中是沒(méi)有真正的字符串類(lèi)型,可以通過(guò)字符數(shù)組表示字符串,并且字符數(shù)組的元素地址也是連續(xù)的。C語(yǔ)言中規(guī)定數(shù)組代表數(shù)組所在內(nèi)存位置的首地址,即 str字符串是等于str[0]的,str = &str[0];

對(duì)于printf("%s",str); 為什么用首地址就可以輸出字符串?

因?yàn)閷?duì)于C語(yǔ)言中字符串常量的本質(zhì)就是一個(gè)地址,例如:

char  *s ;
s = "Hello";

這里把一個(gè)字符串賦值給一個(gè)字符串指針變量,起始就是C語(yǔ)言中編譯器會(huì)給字符串常量分配地址,如果"Hello", 存儲(chǔ)在內(nèi)存中的 0x3000 0x3001 0x3002 0x3003 0x3004 0x3005 ,可以看出真正的意義就是
s = “Hello” = 0x3000

因此我們可以把Hello看做是字符串,而編譯器會(huì)把他看做是地址 0x3000 ,即字符串常量的本質(zhì)就是代表它的第一個(gè)字符的地址。

char *s;
s = "Hello";
printf("%p\n",s);//%p代表表示按十六進(jìn)制輸出數(shù)據(jù),如果輸出數(shù)據(jù)不夠8位數(shù),則左邊補(bǔ)0

輸出00796BD0,也就是"Hello"的首地址。

對(duì)于字符數(shù)組:

char str[10] = “Hello”;
也就是說(shuō)str = &str[0]

C語(yǔ)言中操作字符串是通過(guò)它在內(nèi)存中的存儲(chǔ)單元的首地址進(jìn)行的,這是字符串的終極本質(zhì)。。。

4、char * 與 char a[ ]

對(duì)于char *s 與 char a[ ] :
a代表的是字符串的首地址,而s代表的這個(gè)指針保存字符串的首地址(第一個(gè)字符的地址),即可以看做: s =a ,即可以將數(shù)組名賦值給指針表示地址,但是 不能這樣賦值 a = s ,即:不能將指針賦值給數(shù)組名
因?yàn)閿?shù)組名是一個(gè)常量,是不可以修改的
可以通過(guò)如下方式訪問(wèn)數(shù)組元素:

char a[] = "Hello";
char*s = a;
int i;
for(i = 0;i < strlen(a);i++)
{
printf("%c",s[i]);
//printf("%c",*s++);也可以
}

字符指針可以用 間接操作符 * 取其內(nèi)容,也可以用數(shù)組的下標(biāo)形式 [ ],數(shù)組名也可以用 *操作,因?yàn)樗旧肀硎疽粋€(gè)地址 。。

比如 printf("%c",*a); 將會(huì)打印出 ‘H',

char * s 與 char a[ ] 的本質(zhì)區(qū)別

當(dāng)定義char a[10]的時(shí)候,編譯器會(huì)給數(shù)組分配10個(gè)單元,每個(gè)單元的數(shù)據(jù)類(lèi)型都是字符,而定義char *s時(shí),s是一個(gè)指針變量,只占4個(gè)字節(jié),32位,用來(lái)保存一個(gè)地址。
sizeof(a) = 10,sizeof(s) = 4
a的長(zhǎng)度是10,s的長(zhǎng)度是4,因?yàn)閟是一個(gè)int型

printf("%p",s)----------這個(gè)表示 s 的單元中所保存的地址。

printf("%p",&s);--------這個(gè)表示變量本身所在內(nèi)存單元地址。。。。,不要搞混了。。

總結(jié):char * s 只是一個(gè)保存字符串首地址的指針變量,char a[]是許多連續(xù)的內(nèi)存單元,單元中的元素是char型,char * 和 char a[]具有相同的效果,源于字符串的本質(zhì),即給一個(gè)字符串地址,便可以操作字符串,但char* 和 char a[]的本質(zhì)屬性不一樣。

5、char ** 和char *a[]

char *a[]

[]的優(yōu)先級(jí)高于 * ,所以先是a[],它是一個(gè)數(shù)組,數(shù)組中的元素是char類(lèi)型,char元素是一個(gè)變量,保存地址。
對(duì)于char *a[ ] = {“Dog”,“Cat”,“Chicken”};
數(shù)組中元素是字符串,sizeof(a)是12,并不是4+4+8,是因?yàn)樽址A康谋举|(zhì)是地址,a數(shù)組中元素是char *指針,指針變量是整數(shù)類(lèi)型,占4個(gè)字節(jié),則3個(gè)元素就是12個(gè)字節(jié)。

char *a[] = { "Dog","Cat","Chicken" };
printf("%p %p %p \n", a[0], a[1], a[2]);

可以看到數(shù)組中的三個(gè)元素保存了三個(gè)內(nèi)存地址,這三個(gè)地址代表了三個(gè)字符串的首地址,而不是字符串本身,且三個(gè)地址不是連續(xù)的,它是編譯器為"Dog",“Cat”,“Chicken” 分配的內(nèi)存空間的地址,因此沒(méi)有關(guān)聯(lián)。

char *a[] = { "Dog","Cat","Chicken" };
printf("數(shù)組元素單元本身的地址:%p %p %p \n", &a[0], &a[1], &a[2]);//數(shù)組元素單元本身的地址

可以看到三個(gè)元素單元所在的地址是連續(xù)的,每個(gè)地址相差四個(gè)字節(jié)。

char ** s

char ** 為二級(jí)指針,s保存一級(jí)指針char *的地址,
例如:

char *a [ ] = { "Dog","Cat","Chicken" };
char **s =   a;//---有問(wèn)題

數(shù)組a代表數(shù)組元素內(nèi)存單元的首地址,,即a = &a[0] = 010FFD44,即 *s = 001D6BE0 = “Dog”,
這樣可以通過(guò)s訪問(wèn)a中的數(shù)據(jù)

printf(“%s”,*s);
printf("%s",a[0]);
printf("%s",*a);

三個(gè)一樣,,但是不能把a(bǔ) = s,因?yàn)閍是一個(gè)常量;

char **s = “hello world”; ------是錯(cuò)誤的;

因?yàn)閟的類(lèi)型是char ** ,而 “hello world”的類(lèi)型是char *;

雖然都是地址, 但是指向的類(lèi)型不一樣,因此,不能這樣用。,從其本質(zhì)來(lái)分析,“Hello world”,代表一個(gè)地址,比如0x000001,這個(gè)地址中的內(nèi)容是 ‘H',為char型,而s也保存一個(gè)地址,這個(gè)地址內(nèi)容是char*,是一個(gè)指針類(lèi)型。

char  **s;
*s = "hello world";

編譯沒(méi)有問(wèn)題,但是 printf("%s",s),就會(huì)崩潰, printf ("%s", s); 時(shí),首先得有s 保存的地址,再在這個(gè)地址中找到 char * 的地址,即*s;

若s = 0x1000;
在0x1000所在的內(nèi)存單元保存了“hello world”的地址0x000001,*s = 0x000001,這樣printf("%s",*s)會(huì)先找到0x1000,然后找到0x000001,如果直接使用char **s,令 * s = “hello world”,s變量中保存的是一個(gè)無(wú)效隨機(jī)不可用的值,不知道他指向哪里,所以用char **s時(shí),要給他分配一個(gè)內(nèi)存地址。

char  **s ;
s = (char **) malloc(sizeof(char**));
*s =  "hello world";

這樣s給分配了一個(gè)可用的地址,s = 0x1234,然后再地址0x1234所在的內(nèi)存中的位置,保存了“hello world”的值。

下列程序中,定義了字符指針s,s中存放了字符串"message"的地址。

#include  <stdio.h>
void  buf( char **s)
{
 *s = "message";
}
int main()
{
 char *s ;
 buf(&s);
 printf("%s\n",s);
}

即:二級(jí)指針保存的是一級(jí)指針的地址,它的類(lèi)型就是指針變量,一級(jí)指針保存的是指向數(shù)據(jù)所在的內(nèi)存單元的地址。

參考:
https://blog.csdn.net/daiyutage/article/details/8604720

6、C語(yǔ)言中char s[] 和 char *s的區(qū)別

有關(guān)于這兩者的區(qū)別,下面的來(lái)自Stack Overflow的解釋非常清晰:

http://stackoverflow.com/questions/1704407/what-is-the-difference-between-char-s-and-char-s-in-c

The difference here is that

char *s = "Hello world";

will place Hello world in the read-only parts of the memory and making s a pointer to that, making any writing operation on this memory illegal. While doing:

char s[] = "Hello world";

puts the literal string in read-only memory and copies the string to newly allocated memory on the stack. Thus makings[0] = 'J' legal.

總結(jié)一下,要點(diǎn)如下:

  1. char [] 定義的是字符串數(shù)組,該字符數(shù)組在內(nèi)存中的存儲(chǔ)是先分配新空間,再去填充,因此該數(shù)組的內(nèi)容可以改變,即通過(guò)s[0] = 'J'是合法的。
  2. char *s定義的是字符串指針變量,該指針變量指向一個(gè)字符串,該指針的值是該字符串在內(nèi)存中的地址。對(duì)于這個(gè)指針變量來(lái)說(shuō),改變它的值=改變地址=改變指針指向,比如從指向第一個(gè)字符變?yōu)橹赶虻诙€(gè)字符。然后改字符指針變量并沒(méi)有權(quán)力去更改它指向的字符的值,比如*(s+1) = 'J'。換句話說(shuō),就是可以修改指針的值,但不能修改指針指向的值。

到此這篇關(guān)于C語(yǔ)言char s[]和char* s的區(qū)別的文章就介紹到這了,更多相關(guān)C語(yǔ)言 char s[]和char* s內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++學(xué)習(xí)之算術(shù)運(yùn)算符使用詳解

    C++學(xué)習(xí)之算術(shù)運(yùn)算符使用詳解

    運(yùn)算符是計(jì)算機(jī)語(yǔ)言提供的能對(duì)數(shù)據(jù)進(jìn)行基本運(yùn)算操作的功能體。而算術(shù)運(yùn)算符用來(lái)對(duì)數(shù)字型數(shù)據(jù)進(jìn)行數(shù)學(xué)語(yǔ)義上的加、減、乘、除。本文通過(guò)講解清楚算術(shù)運(yùn)算符,讓大家了解使用C++運(yùn)算符時(shí)應(yīng)該注意的事項(xiàng)
    2022-06-06
  • C++ 11 std::function和std::bind使用詳解

    C++ 11 std::function和std::bind使用詳解

    這篇文章主要介紹了C++ 11 std::function和std::bind使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 深入理解C語(yǔ)言sizeof()計(jì)算空間大小為8的問(wèn)題

    深入理解C語(yǔ)言sizeof()計(jì)算空間大小為8的問(wèn)題

    本文將介紹C語(yǔ)言中的sizeof()函數(shù),以及如何使用它來(lái)計(jì)算變量、數(shù)據(jù)類(lèi)型和數(shù)組在內(nèi)存中的大小,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • C++ Qt實(shí)現(xiàn)瀏覽器網(wǎng)頁(yè)內(nèi)嵌的音視頻播放器

    C++ Qt實(shí)現(xiàn)瀏覽器網(wǎng)頁(yè)內(nèi)嵌的音視頻播放器

    這篇文章主要為大家詳細(xì)介紹了如何利用C++ Qt實(shí)現(xiàn)瀏覽器網(wǎng)頁(yè)內(nèi)嵌的音視頻播放器,并支持軟硬解碼,支持音頻,支持錄像截圖,支持多路播放等,感興趣的可以了解下
    2024-01-01
  • C++類(lèi)基本語(yǔ)法實(shí)例分析

    C++類(lèi)基本語(yǔ)法實(shí)例分析

    這篇文章主要介紹了C++類(lèi)基本語(yǔ)法實(shí)例分析,非常適合初學(xué)者學(xué)習(xí)借鑒,需要的朋友可以參考下
    2014-08-08
  • C++?函數(shù)的介紹

    C++?函數(shù)的介紹

    本篇主要介紹了函數(shù)的基礎(chǔ)概念以及一些特殊的函數(shù)方法和類(lèi)型,函數(shù)重載以及函數(shù)指針,下面一起進(jìn)入文章學(xué)習(xí)詳細(xì)的內(nèi)容吧,需要的朋友也可以參考一下
    2021-12-12
  • 深入分析C++派生類(lèi)中的保護(hù)成員繼承

    深入分析C++派生類(lèi)中的保護(hù)成員繼承

    這篇文章主要介紹了C++派生類(lèi)中的保護(hù)成員繼承,深入對(duì)C++面向?qū)ο缶幊痰睦^承機(jī)制進(jìn)行了解析,需要的朋友可以參考下
    2015-09-09
  • c++實(shí)現(xiàn)簡(jiǎn)單的線程池

    c++實(shí)現(xiàn)簡(jiǎn)單的線程池

    本文介紹的線程池采用C++語(yǔ)言,在windows平臺(tái)下實(shí)現(xiàn)。本著技術(shù)分享的精神寫(xiě)作本文同時(shí)公布源代碼。歡迎大家指出該線程池存在的問(wèn)題并對(duì)當(dāng)前性能進(jìn)行討論。
    2015-03-03
  • C語(yǔ)言實(shí)現(xiàn)貪吃蛇小游戲

    C語(yǔ)言實(shí)現(xiàn)貪吃蛇小游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)貪吃蛇小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • Qt5.14.2使用虛擬鍵盤(pán)的關(guān)鍵代碼

    Qt5.14.2使用虛擬鍵盤(pán)的關(guān)鍵代碼

    對(duì)于Qwidget程序,使用qtvirtualkeyboard彈出鍵盤(pán)之后,鍵盤(pán)會(huì)浮于表面。使用VirtualkeyboardPushView模塊,自動(dòng)根據(jù)情況把輸入視圖往上面推移,這篇文章主要介紹了Qt5.14.2使用虛擬鍵盤(pán)的關(guān)鍵代碼,需要的朋友可以參考下
    2022-09-09

最新評(píng)論