iT邦幫忙

0

C-string的arry bound?

  • 分享至 

  • xImage

想問一個基礎的問題
假如我有一個字串
char* a="abc"
那寫「a[3]」這個東西是undefined behaviour嗎?
因為我寫

if(a[3]=='\0')
cout<<"yes";

是有順利output出yes的
讓我有點納悶

另外如果不能這樣寫的話是不是就沒有方法access那個字元(null terminator)了?

(同問如果寫 char a[]="abc"
可不可以使用a[3]呢)

謝謝!!

meebox iT邦新手 4 級 ‧ 2024-04-08 09:46:55 檢舉
你可以寫 a[3] 沒問題, 如果是字串, 在字串尾端編譯器本來就會加上 '\0' 字元, strlen() 也是利用這個方式判斷字串結尾才能得到字串長度。

超過陣列長度就要看該記憶體位置的內容了。但如果指定的位置不在你的程式可存取的區域, 也可能會引發系統錯誤, 讓你的程式直接當掉。
感謝!!因為問ai說不能這樣寫讓我很疑惑,謝謝大大回答!
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中
1
thomasfrank
iT邦見習生 ‧ 2024-04-08 09:16:21

You can use strlen(a) (from string.h) to get the string length excluding the null terminator. You can then compare it to 3 to see if there are at least 3 characters. Buckshot Roulette

#include <stdio.h>
#include <string.h>

int main() {
    char* a = "abc";
    int len = strlen(a);

    if (len >= 3) {
        printf("String has at least 3 characters (including null terminator)\n");
    } else {
        printf("String has less than 3 characters\n");
    }
    return 0;
}

Thank you!!But what I'am asking is if using "a[3]" is correct.^^

1
YC
iT邦好手 1 級 ‧ 2024-04-08 15:11:26

參考
字串

char a[] = "abc"
//等同
char a[4]= {'a', 'b', 'c', '\0'}

然後,
char* a="abc"等同

char abc[4] = {'a', 'b', 'c', '\0'}`
char* a=abc

a是一個指向abc的指標,所以a[3] = abc[3] = '\0'

感謝!

0
cpc0935
iT邦研究生 5 級 ‧ 2024-04-11 09:53:29

最近剛好在複習這個
https://ithelp.ithome.com.tw/upload/images/20240411/200296187NgNQtke7B.png

0
samlin961112
iT邦新手 4 級 ‧ 2024-04-12 23:14:08

你的問題涉及到 C/C++ 中字串的定義和存儲方式,讓我來解釋一下:

首先,讓我們看看兩種不同的字串定義:

  1. 對於 char* a = "abc"; 這種方式,a 是一個指向字元串首位的指標。這意味著 a 實際上是指向 "abc" 字串常量的開始地址。這種定義方式是將字串存儲在只讀區域,並且不允許修改。因此,使用 a[3] 來訪問字串中的第四個元素(即索引為 3 的元素)是未定義行為(undefined behavior),因為你在超出了指向 "abc" 的範圍。儘管在某些情況下可能能正常運行,但不應該依賴這種行為,因為它不符合語言標準。

  2. 對於 char a[] = "abc"; 這種方式,a 是一個字符數組,長度為 4(包括 null 終止符 \0)。在這種情況下,a 是可修改的,並且 "abc" 的內容將被拷貝到 a 中。因此,使用 a[3] 是合法的,並且 a[3] 將為 null 終止符 \0,因為 "abc" 在這裡被看作是一個包含四個字符的字元數組({'a', 'b', 'c', '\0'})。

現在回答你的問題:

  • 如果你寫 char* a = "abc";,使用 a[3] 來訪問字串的第四個元素是未定義行為,因為它超出了字串的範圍,但在某些實現中可能會正常運行(因為後面可能恰好有一個 null 終止符),但這是不可靠的行為。

  • 如果你寫 char a[] = "abc";,則可以使用 a[3] 來訪問 null 終止符(即空字符 \0),這是合法的。這樣做可以用來確定字串的實際長度或操作字串的最後一個字符。

總之,對於字串的處理,最好確保按照 C/C++ 語言的規範進行,以避免未定義行為和不可預測的結果。

不好意思,不過chae* c="abc"中,不是也是有\0存在abc的後面嗎?

是的,所以才說可能會是對的。那麼我在說仔細一點

  • char* a="abc"中,這代表的並不是一個陣列,它只是一個指標,因此,而且在C中,除了你設定好的之外,通常會是\0,所以你叫算打a[-1]都可能是正確的。
  • char a[]="abc"中,它就是一個有四的字元的陣列所以你用a[3]當然會正確,然而,與前者不同的,若非0,1,2,3,則必會報錯。

我要發表回答

立即登入回答