Мне просто интересно, есть ли разница между использованием
for(i = 0; i < sizeof(argv[1]) / sizeof(argv[1][0]); i++) {
и
while (argv[1][i] != '\0')
Мне просто интересно, и я ничего не могу найти об этом.
(Цель состоит в том, чтобы putchar
каждый персонаж char*
)
@WeatherVane Похоже, ОП ищет длину одного параметра, а не их количество.
Чтобы получить длину argv[1]
, используйте strlen(argv[1])
Вы должны понимать разницу между указателями и массивами. Если вы получаете argv
из main()
, это указатель на (массив) указателей на (массив) char
. argv[1]
— это указатель, и sizeof argv[1]
вернет размер указателя, а не массива.
while (argv[1][i] != '\0')
то же, что while (argv[1][i])
см. также stackoverflow.com/questions/14298710/…
В этих двух условиях есть существенная разница.
Выражение argv[1]
является указателем типа char *
и обычно занимает либо 4, либо 8 байт в зависимости от используемой системы, что равно значению выражения sizeof(argv[1]) / sizeof(argv[1][0])
или эквивалентно выражению sizeof( argv[1] )
, поскольку sizeof( argv[1][0] )
совпадает с sizeof( char )
, а последнее всегда равно 1
С другой стороны, указатель может указывать на строку с гораздо большим (или меньшим) количеством символов, чем 4 или 8.
Но даже если вы примените оператор sizeof
для массива символов (вместо указателя), объявленного, например, как
char s[] = "Hello";
то и в этом случае условия петель будут другими. Это цикл for
for(i = 0; i < sizeof( s ) / sizeof( s[0]); i++) {
эквивалентно
for(i = 0; i < 6; i++) {
потому что завершающий ноль также включен в массив. То есть тело цикла получит управление и для символа '\0'
.
Пока этот цикл
while ( s[i] != '\0')
останавливает свои итерации, когда встречается символ '\0'
.
Вот демонстрационная программа, которая показывает разницу. Программа выводит ASCII-коды символов.
#include <stdio.h>
int main(void)
{
char s[] = "Hello";
for ( size_t i = 0; i < sizeof( s ) / sizeof( s[0]); i++ )
{
printf( "%d ", s[i] );
}
putchar( '\n' );
size_t i = 0;
while ( s[i] != '\0' )
{
printf( "%d ", s[i] );
++i;
}
putchar( '\n' );
return 0;
}
Вывод программы
72 101 108 108 111 0
72 101 108 108 111
Это не одно и то же (хотя и близко).
Первый
for(i = 0; i < sizeof(argv[1]) / sizeof(argv[1][0]); i++) {
означает:
Установите i
на 0
sizeof(argv[1]) / sizeof(argv[1][0])
означает strlen(argv[1])
, значит
while i is less than the length of argv[1]
что в основном то же самое, что и
int i = 0;
while(argv[1][i++] != '\0')
Есть 2 отличия:
Во втором i
никогда не устанавливается на 0
Во втором i
никогда не увеличивается (хотя в самом цикле может увеличиваться)
sizeof(argv[1]) / sizeof(argv[1][0])
не значит strlen(argv[1])
. Первый представляет собой размер указателя argv[1]
, деленный на размер char
argv[1][0]
, и обычно он не будет таким же, как длина строки, начинающейся с argv[1]
, поскольку размер указателя не имеет отношения к какой бы то ни было строке. перешли в программу.
sizeof(argv[1])
— размер указателя.argc
говорит вам длину массива*argv[]
.