【发布时间】:2012-03-20 08:01:24
【问题描述】:
char* names[]={"A", "B", "C"};
有没有办法找到数组中字符串的数量?例如,在这种情况下,它应该输出:3。
【问题讨论】:
-
这是一个如何获取数组大小的具体案例,这里已经有了一个通用的答案:stackoverflow.com/questions/37538/… 即重复。
char* names[]={"A", "B", "C"};
有没有办法找到数组中字符串的数量?例如,在这种情况下,它应该输出:3。
【问题讨论】:
下面的答案是什么
size_t arrLength( char** arr) {
size_t i = 0;
size_t count = 0;
int len;
len = sizeof(**arr) / sizeof(arr[0]);
for (i = 0; i < len; i++) {
printf("%zu - %s\n", count + 1, *(arr + i));
count++;
}
return count;
}
int main(void) {
char* names[] = { "Jimmy", "Tom", "Michael", "Maria", "Sandra", "Madonna" };
size_t length, size;
//size = sizeof(names) / sizeof(names[0]);
length = arrLength(names);
printf("\n");
printf("The number of strings found are %zu\n", length);
return 0;
}
我得到 1
【讨论】:
使用增量运算符使 字符串数组 在 While 循环 中运行,直到循环变为 NULL,给出数组大小:
#include<stdio.h>
char* names[]={"A", "B", "C"};
int main(){
int nameSize = 0;
while(names[++nameSize]!='\0');
}
for(i=0;i<nameSize;i++){
printf("%s\n", names[i]);
}
return 0;
}
输出:
A
B
C
【讨论】:
您在这里定义的并不是字面上的字符串数组,而是字符指针数组。如果你想知道字符串的数量,你只需要计算指针,就像
size_t size = sizeof(names)/sizeof(char*);
会这样做,这样你就可以将数组的大小除以单个指针的大小。但请注意,这只适用于在编译时知道数组大小的情况(即数组是静态分配的) ,如果它是动态定义的(即 char** 字符串),那么 sizeof(strings) 将返回指针的大小而不是数组。
p.s.:字符串的长度不相关,因为数组甚至不“知道”指针指向的内容。
【讨论】:
有没有办法找到数组中字符串的个数
当然有,试试这个:
#include<stdio.h>
int main(void){
size_t size, i=0;
int count=0;
char* names[]={"A", "B", "C"};
size = sizeof(names)/sizeof(char*);
for(i=0;i<size;i++){
printf("%d - %s\n",count+1, *(names+i));
count++;
}
printf("\n");
printf("The number of strings found are %d\n",count);
return 0;
}
1 - A 2 - B 3 - C
The number of strings found are 3
同样的事情:
#include<stdio.h>
int main(void){
size_t size, i=0;
int count=0;
char *names[]={"Jimmy", "Tom", "Michael", "Maria", "Sandra", "Madonna"};
size = sizeof(names)/sizeof(char*);
for(i=0;i<size;i++){
printf("%d - %s\n",count+1, *(names+i));
count++;
}
printf("\n");
printf("The number of strings found are %d\n",count);
return 0;
}
输出:
1 - Jimmy 2 - Tom 3 - Michael 4 - Maria 5 - Sandra 6 - Madonna
The number of strings found are 6
或者使用这样的函数:
#include<stdio.h>
size_t arrLength(size_t len, char **arr){
size_t i=0;
size_t count=0;
for(i=0;i<len;i++){
printf("%zu - %s\n",count+1, *(arr+i));
count++;
}
return count;
}
int main(void){
char *names[]={"Jimmy", "Tom", "Michael", "Maria", "Sandra", "Madonna"};
size_t length,size;
size = sizeof(names)/sizeof(char*);
length = arrLength(size, names);
printf("\n");
printf("The number of strings found are %zu\n",length);
return 0;
}
输出:
1 - Jimmy 2 - Tom 3 - Michael 4 - Maria 5 - Sandra 6 - Madonna
The number of strings found are 6
【讨论】:
在 C 中查找字符串数组中的字符串数
查找数组中对象数量的简单方法是用数组的大小除以其中一个元素的大小。使用sizeof 运算符返回对象的大小(以字节为单位)。
// For size_t
#include <stddef.h>
char* names[] = { "A", "B", "C" };
size_t number_of_strings = sizeof names / sizeof names[0];
printf("Number of strings %zu\n", number_of_strings);
重要的是要考虑从sizeof 返回的类型是size_t,这是一种能够索引任何数组以及任何对象大小的无符号整数类型。要打印size_t 类型的变量,请使用修饰符z。
【讨论】:
对于数组,如赏金中的示例,执行sizeof(names)/sizeof(names[0]) 足以确定数组的长度。
示例中的字符串长度不同这一事实并不重要。 names 是 char * 的数组,因此数组的总大小(以字节为单位)是数组中元素的数量乘以每个元素的大小(即 char *)。这些指针中的每一个都可以指向任意长度的字符串,或者指向 NULL。没关系。
测试程序:
#include<stdio.h>
int main(void)
{
char* names1[]={"A", "B", "C"}; // Three elements
char* names2[]={"A", "", "C"}; // Three elements
char* names3[]={"", "A", "C", ""}; // Four elements
char* names4[]={"John", "Paul", "George", "Ringo"}; // Four elements
char* names5[]={"", "B", NULL, NULL, "E"}; // Five elements
printf("len 1 = %zu\n",sizeof(names1)/sizeof(names1[0]));
printf("len 2 = %zu\n",sizeof(names2)/sizeof(names2[0]));
printf("len 3 = %zu\n",sizeof(names3)/sizeof(names3[0]));
printf("len 4 = %zu\n",sizeof(names4)/sizeof(names4[0]));
printf("len 5 = %zu\n",sizeof(names5)/sizeof(names5[0]));
}
输出:
len 1 = 3
len 2 = 3
len 3 = 4
len 4 = 4
len 5 = 5
编辑:
澄清一下,这仅适用于您定义了一个数组,即char *names[] 或char names[][],并且您处于定义数组的范围内。如果它被定义为char **names,那么你有一个指针,它作为一个数组起作用,上述技术将不起作用。同样,如果char *names[] 是函数参数,则数组衰减到第一个元素的地址。
【讨论】:
返回数组中的数字或字符串的一种简单方法是遍历数组,直到字符串用完。这是一个例子。
#include <stdio.h>
int main()
{
char* names[] = {"John", "Paul", "George", "Ringo", '\0'};
int size = 0;
while(names[++size]!='\0');
printf("Size: %d\n", size); // Prints "4"
return 0;
}
这种方法的优点是它即使在字符串长度不同时也能工作。注意 names 数组中的终止 NULL 字节,以及用于关闭 while 语句的 ; 字符,因为没有要运行的语句体。
【讨论】:
NULL 是最后一条记录的理想候选者。这样,您可以通过与NULL 进行比较,轻松地在while 循环中识别它。我希望我的解释是清楚的,我的理解是正确的。
'\0',而正确原则上语义不清晰。最后一个'\0' 代表一个空指针常量——最好使用NULL 或0。
'\0' 这样的字符常量与指向字符的指针进行比较。
这取决于您的数组是如何创建的。在 C 中,没有办法检查作为指针的数组的长度,除非它具有哨兵元素,或者与数组一起传递的整数作为数组中元素的计数。在你的情况下,你可以使用这个:
int namesLen = sizeof(names) / sizeof(char);
但是,如果你的数组是一个指针,
char **names = { "A", "B", "C" };
你可以有一个整数,对于数组的长度是恒定的:
int namesLen = 3;
或者添加一个标记值(例如NULL)
char **names = { "A", "B", "C", NULL };
int namesLen = -1;
while (names[++namesLen] != NULL) { /* do nothing */}
// namesLen is now the length of your array
作为另一种方式,您可以创建一个填充有您想要的值的结构:
struct Array {
void **values;
int length;
};
#define array(elements...) ({ void *values[] = { elements }; array_make(values, sizeof(values) / sizeof(void *)); })
#define destroy(arr) ({ free(arr.values); })
struct Array array_make(void **elements, int count)
{
struct Array ret;
ret.values = malloc(sizeof(void *) * count);
ret.length = count;
for (int i = 0; i < count; i++) {
ret.values[i] = elements[i];
}
return ret;
}
你会这样使用它:
struct Array myArray = array("Hi", "There", "This", "Is", "A", "Test");
// use myArray
printf("%i", myArray.length);
destroy(myArray);
【讨论】:
int count = sizeof(names)/sizeof(*names);
这将names 的总大小除以names 中一个元素的大小,得到3。
【讨论】:
在这种情况下,您可以将总大小除以第一个元素的大小:
num = sizeof(names) / sizeof(names[0]);
但请注意,这适用于 数组。它不适用于指针。
【讨论】: