我知道 C 不是一種容易讓開發人員創建泛型型別函式的語言。但是,作為一個學習練習,我正在嘗試撰寫一個函式,該函式允許用戶傳遞任何資料型別(即)的陣列和任何資料型別(即void)的標量void。該函式的目的是用指標遍歷陣列并將標量與陣列索引中的值進行比較,看看它們是否匹配。為此,我將標量和陣列轉換為 achar并strcmp從string.h庫中使用。該函式類似于下面的示例。
void find_vector_indices(void *vec, void *value, size_t num_bytes, size_t arr_size) {
char compare;
char *val = (char *) value;
char *dst;
for (int i = 0; i < arr_size; i ) {
dst = (char *) vec (i * num_bytes);
compare = strcmp(dst, val);
if (compare == 0) printf("Strings Match\n");
}
}
在主函式中,如果我有以下使用整數的代碼,則上述函式可以正常作業并列印Strings Match兩次,正如我所期望的那樣。
int a[3] = {3, 2, 3};
int b = 3;
find_vector_indices(a, &b, sizeof(int), 3);
但是,如果我將主函式修改為浮點陣列和浮點標量,則該函式不再起作用。
float a[3] = {3.1, 2.2, 3.1};
flat b = 3.1;
find_vector_indices(a, &b, sizeof(float), 3);
我假設這與浮點和整數值在記憶體中的表示方式有關。但是,據我所知,它們都消耗 4 個位元組的記憶體,并且應該正確地表示為字串,我相信在這個函式的指標演算法中正確地指出了它。解決方案可能很簡單,但它正在逃避我。任何幫助,將不勝感激。
uj5u.com熱心網友回復:
strcmp()用于比較字串(以 NUL 結尾的字符序列),而不是任意二進制資料。改為使用memcmp()。
代替
compare = strcmp(dst, val);
你應該使用
compare = memcmp(dst, val, num_bytes);
在 little-endian 機器中,小位元組(例如 2 或 3)的第 2、第 3 和第 4 個位元組int將為零,因此它將作為字串終止符作業,并且您的代碼似乎可以正常作業。
另一方面,該float值3.1將表示為0x40466666(根據IEEE-754 浮點轉換器)。這不包含 0x00 位元組,因此strcmp()看起來作業的機會較小。
的型別compare應該是int,不是char。strcmp()并memcmp()回傳int且未指定其范圍。(只是根據比較的結果指定為正數、負數或零)。因此,由于截斷,可能會有一些機會將 unmatch 誤解為 match。
uj5u.com熱心網友回復:
除了@MikeCAT好的答案:
使用一致的型別
// for (int i = 0; i < arr_size; i ) {
for (size_t i = 0; i < arr_size; i ) {
“看看他們是否匹配”?
即使@MikeCAT 建議修復,
0.0 == -0.0是的,但是 viafind_vector_indices()會報告它們不同,因為它們具有相同的值,但不同的位模式。這也可能發生在其他浮點編碼和指標上。
float a[1] = {-0.0};
float b = 0.0;
find_vector_indices(a, &b, sizeof b, 1);
另請參閱@John Bollingerstruct關注點。
選擇
而不是使用memcmp(), strcmp()等,傳入一個比較函式int cmp(const void *, const void *)并回傳第一個零比較地址。
// Illustrative untested code.
void *find_vector_match(const void *vec, const void *value, size_t element_size,
size_t arr_n, int (cmp)(const void *, const void *)) {
while (arr_n > 0) {
arr_n--;
if (cmp(vec, value) == 0) {
return (void *) vec;
}
vec = (const unsigned char*)vec element_size;
}
return NULL;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/493280.html
