1

This is a function to reverse a given arguments , why we used argc - 1 in this context,as long as there's not null to compare in int type, is it to subtract file name from count ? and if you could show other use of argc - 1 that would be great.

int     main(int argc, char **argv)
{
    int i;

    i = argc - 1;
    while (i > 0)
    {
        printf("%s", argv[i]);
        putchar('\n');
        i--;
    }
    return (0);
}
Question
  • 63
  • 7
  • 3
    If an array has length n, the last element is stored at index n-1 because arrays are indexed from 0. – Paul Hankin Jul 07 '21 at 14:28
  • 3
    `argv` is an array of `char*` that has `argc` elements. As arrays in C start with the index `0`, they run up to `argc - 1` (the last element). – Adrian Mole Jul 07 '21 at 14:28

3 Answers3

2

I read the previous answers and I notice that they try to give you another way to re-write your code instead I'm going to explain to you how argc and argv works.

as you may notice why we declare the argument in the main function we do this :

int main(int argc, char **argv

this means that when you try to launch the executable program you should give it some addition arguments.

  1. argc is the number of arguments being passed into your program from the command line
  2. argv is the array of arguments.

and you should know that the array starts from 0 this means that if you want to print the last arguments in the array you can do this:

printf("%s\n", argv[argc - 1]);

for example:

I have a program that takes a list of arguments and prints one by one and every argument followed by newline \n.

the code:

#include <unistd.h>

int main(int argc, char **argv)
{
    int i;
    int j;

    while (argv[i])
    {
        j = 0;
        while (argv[i][j])
        {
            write(1, &argv[i][j], 1);
            j++;
        }
        write(1, "\n", 1);
        i++;
    }
}

NOTE: this program doesn't use any built-in function (except wite).

if you try to compile this code and execute it:

➜  Desktop gcc test.c 
➜  Desktop ./a.out test test1 test2
./a.out
test
test1
test2
➜  Desktop 
DarkSide77
  • 719
  • 1
  • 4
  • 21
0

It's just badly written code, it is nothing to study or learn from. By applying common sense, we can re-write this as:

for(int i=1; i<argc; i++)
{
  puts(argv[argc-i]);
}

Assuming we don't want to print argv[0].

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • agreed, very bad written, by the way I'm allowed to use no for loop neither any other function other than write, printf and putchar I should recreate them in order to use the them. – Question Jul 07 '21 at 14:35
  • @RidaEN-Nasry So you are taking some strange class where the goal is to become bad at C programming? Anyway, rewriting the code in worse ways is trivial: `int i=1; while(i – Lundin Jul 07 '21 at 14:40
  • @RidaEN-Nasry Good or bad, it's useful to understand that every `for` loop can theoretically be rewritten using `while`, and vice versa. This point is discussed at the end of [this course notes page](https://www.eskimo.com/~scs/cclass/notes/sx3e.html). – Steve Summit Jul 07 '21 at 14:56
  • @Lundin re-writing a built-in functions in C, make you understand how those functions work so when you use them next time you have an Idea how/why you use them.. so the class he's taking is a good one specially if he really want to learn how those function works – DarkSide77 Jul 07 '21 at 17:17
  • @SteveSummit Obscure loops having complex end conditions or complex iteration etc, or being weird in general, is a massive source of bugs. As is the plague known as "write the code as complex as you possibly can". Often for the sake of showing off some obscure C knowledge. The end result is bugs, worse optimization and worse cache performance. So it's not a matter about `for` vs `while` but a matter about common sense vs insanity and discipline vs sloppiness. – Lundin Jul 08 '21 at 06:38
  • @DarkSide77 Not sure what you mean. What built-in functions are you talking about? – Lundin Jul 08 '21 at 06:39
0

For comparison, here are two more ways to write the same loop.

Method 2:

int main(int argc, char **argv)
{
    int i;
    for(i = argc - 1; i > 0; i--)
    {
        printf("%s\n", argv[i]);
    }
}

Method 3:

int main(int argc, char **argv)
{
    int i = argc;
    while(--i > 0)
    {
        printf("%s\n", argv[i]);
    }
}
Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Now benchmark all versions posted and keep the one with best results. My money is on the most simplistic and readable loop. – Lundin Jul 08 '21 at 06:41