博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(原創) char s[]字串和char *s字串有什麼差別? (C/C++) (C)
阅读量:6371 次
发布时间:2019-06-23

本文共 1791 字,大约阅读时间需要 5 分钟。

Abstract

C語言有兩種字串宣告方式char s[]和char *s,兩者有什麼差異呢?
Introduction

char
 s[] 
=
 
"
Hello World
"
;
char
 
*
s  
=
 
"
Hello World
"
;

皆宣告了s字串,在C-style string的函數皆可使用,但兩者背後意義卻不相同。

char
 s[] 
=
 
"
Hello World
"
;

的s是個char array,含12個byte(包含結尾\0),"Hello World"對s來說是initializer,將字元一個一個地copy進s陣列。

char
 
*
=
 
"
Hello World
"
;

的s是一個pointer指向char,由於"Hello World"本身就是一個string literal,所以s指向"Hello World"這個string literal的起始記憶體位置。
做個簡單的實驗證明兩者不同

 1
None.gif
#include 
<
iostream
>
 2
None.gif
 3
None.gif
using
 
namespace
 std;
 4
None.gif
 5
ExpandedBlockStart.gifContractedBlock.gif
int
 main() 
dot.gif
{
 6InBlock.gif char s1[] = "Hello World";
 7InBlock.gif char *s2  = "Hello World";
 8InBlock.gif 
 9InBlock.gif cout << "size of s1: " << sizeof(s1) << endl;
10InBlock.gif cout << "size of s2: " << sizeof(s2) << endl;
11ExpandedBlockEnd.gif}

執行結果

None.gif
size of s1: 
12
None.gifsize of s2: 
4
None.gif

s1是陣列,所以占了12 byte,而s2只是pointer,所以占了4 byte,實驗結果與預期相同。

實際使用有什麼不同嗎?兩種寫法皆可使用substring和pointer寫法,但只有char *s可以直接使用*s++寫法。

char s[]

 1
None.gif
#include 
<
iostream
>
 2
None.gif
 3
None.gif
using
 
namespace
 std;
 4
None.gif
 5
ExpandedBlockStart.gifContractedBlock.gif
int
 main() 
dot.gif
{
 6InBlock.gif char s[] = "Hello World";
 7InBlock.gif 
 8ExpandedSubBlockStart.gifContractedSubBlock.gif for(int i = 0; i != 11++i) dot.gif{
 9InBlock.gif  cout << s[i];
10ExpandedSubBlockEnd.gif }
11InBlock.gif cout << endl;
12InBlock.gif 
13ExpandedSubBlockStart.gifContractedSubBlock.gif for(int i = 0; i != 11++i) dot.gif{
14InBlock.gif  cout << *(s + i);
15ExpandedSubBlockEnd.gif }
16InBlock.gif cout << endl;
17ExpandedBlockEnd.gif}
18
None.gif

執行結果

None.gif
Hello World
None.gifHello World

char *s

 1
None.gif
#include 
<
iostream
>
 2
None.gif
 3
None.gif
using
 
namespace
 std;
 4
None.gif
 5
ExpandedBlockStart.gifContractedBlock.gif
int
 main() 
dot.gif
{
 6InBlock.gif char *= "Hello World";
 7InBlock.gif 
 8ExpandedSubBlockStart.gifContractedSubBlock.gif for(int i = 0; i != 11++i) dot.gif{
 9InBlock.gif  cout << s[i];
10ExpandedSubBlockEnd.gif }
11InBlock.gif cout << endl;
12InBlock.gif 
13ExpandedSubBlockStart.gifContractedSubBlock.gif for(int i = 0; i != 11++i) dot.gif{
14InBlock.gif  cout << *(s + i);
15ExpandedSubBlockEnd.gif }
16InBlock.gif cout << endl;
17ExpandedBlockEnd.gif}

執行結果

None.gif
Hello World
None.gifHello World

但卻只有char *s可以使用*s++寫法。

 1
None.gif
#include 
<
iostream
>
 2
None.gif
 3
None.gif
using
 
namespace
 std;
 4
None.gif
 5
ExpandedBlockStart.gifContractedBlock.gif
int
 main() 
dot.gif
{
 6InBlock.gif char *= "Hello World";
 7InBlock.gif 
 8InBlock.gif while(*s) 
 9InBlock.gif  cout << *s++;
10ExpandedBlockEnd.gif}
11
None.gif
12
None.gif

執行結果

None.gif
Hello World

理由何在呢?

char s[]為陣列,雖然s = &s[0],但s是『常數』,恆等於&s[0]無法改變,但char *s為pointer,指向s[0],但卻是變數,可以任意改變,故可用*s++任意更改pointer值。

Conclusion

一般人很少分辨char s[]和char *s的差異,大部分狀況下用法相同,但char *s速度略快,因為不需copy的動作,且*s++為C語言常用的寫法,只有char *s才支援。

Reference

C Primer Plus 5/e中文版 p.480

转载地址:http://tquqa.baihongyu.com/

你可能感兴趣的文章
关于 Promise 的 9 个提示
查看>>
算法复习
查看>>
安卓中高级开发面试知识点之——缓存
查看>>
Java的初始化顺序
查看>>
js 判断回文字符串
查看>>
shields小徽章是如何生成的?以及搭建自己的shield服务器
查看>>
猫头鹰的深夜翻译:spring事务管理
查看>>
记一次使用Spring REST Docs + travis + github自动生成API接口文档的操作步骤(下)...
查看>>
1、集合 2、Iterator迭代器 3、增强for循环 4、泛型
查看>>
关于/var/run/docker.sock
查看>>
SCrapy爬虫大战京东商城
查看>>
用 JavaScript 实现链表操作 - 11 Alternating Split
查看>>
Laravel优秀扩展包整理
查看>>
日志分析之识别真假蜘蛛与处理办法
查看>>
太多脚本将会毁掉持续交付
查看>>
一地鸡毛 OR 绝地反击,2019年区块链发展指南
查看>>
卢森堡大学发布RepuCoin系统,可破解区块链51%攻击
查看>>
国内云计算厂商众生相:四大阵营十几家企业生存盘点
查看>>
细说Unicode(一) Unicode初认识
查看>>
Node.js有了新的管理者
查看>>