我用 C 語言撰寫了一個函式,它以引數為引數const char *p
,我想檢查該陣列中元素的數量,但效果不佳。
#include <stdlib.h>
#include <stdio.h>
int arrSize(const char *a){
int it = 0;
int size = 0;
while(a[it] != '\0'){
size;
it;
}
return size;
}
int main(){
const char a[5] = {'a', 'b', 'b', 'v', 's'};
const char b[4] = {'c', 'b', 'b', 'v'};
const char c[4] = {'c', 'b', 'b', 'v'};
printf("%d %d %d", arrSize(a), arrSize(b), arrSize(c));
}
但是上面的代碼給出了 8、12、16 的輸出,我不知道為什么。
uj5u.com熱心網友回復:
while(a[it] != '\0'){
當陣列元素等于空終止符時,此回圈結束。
const char a[5] = {'a', 'b', 'b', 'v', 's'}; const char b[4] = {'c', 'b', 'b', 'v'}; const char c[4] = {'c', 'b', 'b', 'v'};
您的陣列都不包含空終止符。回圈不會在元素上停止,它會訪問陣列邊界之外的不存在的元素,并且程式的行為是未定義的。這是不好的。不要這樣做。
如果將空終止符添加到陣列,則該函式將成功計算第一個空終止符之前的非空終止符字符的數量:
const char a[6] = {'a', 'b', 'b', 'v', 's', '\0'};
//const char a[] = "abbvs"; // equivalent
printf("%d", arrSize(a)); // 5
請注意,無需撰寫此arrSize
代碼,因為它是由標準庫以 name 提供的strlen
。
當您將指向陣列元素的指標傳遞給函式時,沒有一般的方法可以使用該指標確定陣列的大小,而不依賴于終止符值,例如在空終止字串的情況下。
當函式需要訪問任意長度的非終止陣列時,一個常見的 C 習慣用法是將該大小作為引數傳遞給函式。現代 C 習語是使用std::span
或等效的,除了編譯器可以推斷出陣列的大小外,基本相同。
您可以在宣告陣列的范圍內確定陣列變數的大小。一個常見的 C 習慣用法是將sizeof
陣列與sizeof
元素型別分開。現代 C 習語是使用std::size
. 例子:
const char a[5] = {'a', 'b', 'b', 'v', 's'};,
void operate_on_array(const char *arr, size_t size);
// C
operate_on_array(a, sizeof a / sizeof *a);
// C with std::size
operate_on_array(a, std::size(a));
// C with std::span
operate_on_array(std::span<const char> arr);
operate_on_array(a);
uj5u.com熱心網友回復:
如果沒有字串結束字符0x0
(或'\0'
,您的函式將繼續運行,直到一個零值的記憶體位元組,這是不安全和越界訪問。
使固定:
主.cpp 1:
#include <stdio.h>
int arrSize(const char *a) {
int it = 0;
int size = 0;
while (a[it] != '\0') {
size;
it;
}
return size;
}
int main() {
const char a[5 1] = {'a', 'b', 'b', 'v', 's', '\0'};
const char b[4 1] = {'c', 'b', 'b', 'v', '\0'};
const char c[4 1] = {'c', 'b', 'b', 'v', '\0'};
printf("%d %d %d", arrSize(a), arrSize(b), arrSize(c));
}
uj5u.com熱心網友回復:
您需要將 '\0' 顯式放在陣列的末尾或將其初始化為字串:
int main(){
const char a[] = "abbvs";
const char b[] = "cbbv";
const char c[] = "cbbv";
printf("%d %d %d", arrSize(a), arrSize(b), arrSize(c));
return 0;
}
在這種情況下,編譯器會自動將 '\0' 放在陣列的末尾。
uj5u.com熱心網友回復:
除非您將其明確設定為元素,否則您不能假設陣列末尾有 0。(符號"abbvs"
- 這是一個const char[6]
文字 - 為你做的。)
訪問陣列邊界之外的元素的行為是未定義的。不要這樣做。
改為使用std::string
,或將大小作為引數傳遞;可能作為一種std::size_t
型別。
綜上所述,您可以使用std::size(a)
代替arrSize(a)
etc.,盡管您需要將格式說明符更改為%zu
. std::size
使用一些巧妙的模板技巧來避免指標衰減。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/470458.html
上一篇:在C 中下標/索引指標
下一篇:列印矩陣行的函式