-3

Consider an array arr[10] of size 10. While getting/displaying data, we use a for loop of the following common syntax

for(int i=0;i<10;i++)

In case of a string, it is like

for(int i=0;strlen(arr)>i;i++)

But I've read somewhere that a simpler expression like arr[i] could just be used in the place of condition. I've tried running a code with that condition. But I get an error. So is there a similar, simple condition expression that can be used with arrays/string?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • No no. Not range based for loops. Just a simpler condition. – Mohamed Safeuq J Aug 30 '17 at 13:23
  • what do you mean by simpler? – rakwaht Aug 30 '17 at 13:24
  • 3
    Perhaps you are thinking of `for(int i = 0; arr[i]; ++i)` where you iterate until you find a `false`, `nullptr` or zero element? – François Andrieux Aug 30 '17 at 13:24
  • @FrançoisAndrieux Yes. Will that work?? Does it belong to C or C++?? – Mohamed Safeuq J Aug 30 '17 at 13:26
  • 2
    C or C++, these are two very different languages? Also you're talking about an error, so I ask: Wich error do you get? Please provide a [mcve]. This is possibly a [XY-Problem](https://meta.stackexchange.com/q/66377/299866) – muXXmit2X Aug 30 '17 at 13:27
  • 1
    Show the code that gives an error. – Jabberwocky Aug 30 '17 at 13:31
  • There are some functions that will take the pointer to the first element and keep producing output from the string of characters until it reaches the terminating zero. Is that perhaps what you were thinking of? Something like `std::cout << arr;`? – wally Aug 30 '17 at 13:33
  • @DavidBowling: this should be an answer like there are already several, except that it is wrong. It works for litteral strings but not for strings that were filled in during runtime and can be smaller than the used array.. – stefaanv Aug 30 '17 at 13:48
  • @stefaanv-- well, it would only work for string literals like `i < sizeof "some string" - 1`. Comment removed. – ad absurdum Aug 30 '17 at 13:56
  • 1
    @MohamedSafeuqJ-- from the answers below, you may notice that the choice of language can affect availability and choice of solutions. C and C++ are not the same language, and you should choose only the relevant language tag, unless the goal is explicitly to compare C and C++. – ad absurdum Aug 30 '17 at 14:00
  • Ok. Changed it now. – Mohamed Safeuq J Aug 30 '17 at 14:02

7 Answers7

7

As stated in the for statement documentation:

condition may be a declaration

With the following code to demonstrate:

int main(){
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
    for (int i = 0; int x = arr[i]; ++i){
        std::cout << x << std::endl;
    }
}

The loop will exit once arr[i] becomes 0 and gets assigned to x causing the whole condition to evaluate to false. Why that is in more details:

a declaration of a single variable with a brace-or-equals initializer. the initializer is evaluated before each iteration, and if the value of the declared variable converts to false, the loop is exited.

Ron
  • 14,674
  • 4
  • 34
  • 47
  • 4
    How the hell did I never know that ._. – Quentin Aug 30 '17 at 13:35
  • Nice example to show the condition, but I hope for your boss that you are not doing this in your work :) – Chiel Aug 30 '17 at 13:36
  • 1
    _The above code should (probably) be of only intellectual interest._ Why? Just because it is a rather uncommon feature doesn't mean it is bad. Same question goes out to @Chiel. – muXXmit2X Aug 30 '17 at 13:42
  • 1
    Matter of opinion of course, but even simpler would be `int i = 0; int x = arr[i++];` – eerorika Aug 30 '17 at 13:43
  • Does this work in C++? You can't declare a variable in the controlling expression like that in C. – ad absurdum Aug 30 '17 at 13:51
  • @DavidBowling It [works](https://wandbox.org/permlink/9mvUx0vCN3YTtEUP) in C++ but [won't](https://wandbox.org/permlink/LHkd7gDSOtLbgUy5) in C, as expected. – muXXmit2X Aug 30 '17 at 13:57
  • @DavidBowling C++ allowed declaring a variable in a *condition statement*. Since the middle part of a for loop is a *condition statement* it is allowed and the variable will be scoped to the loop body. – NathanOliver Aug 30 '17 at 14:01
  • @NathanOliver-- thanks for the clarification; this is why I asked if it was OK in C++, instead of asserting that it is wrong (which it is in C) ;) And another example of why askers should choose the correct language tag.... – ad absurdum Aug 30 '17 at 14:04
  • @DavidBowling For sure. They really should pick on or the other. – NathanOliver Aug 30 '17 at 14:10
  • @muXXmit2X. I like it, but I had the same reaction as Quentin! – Chiel Aug 30 '17 at 14:49
7

Since you said simple and c++, use std::string.

std::string str = ???;
for(char& c : str) {
    do_things_with(c);
}

Taken from this post.

schorsch312
  • 5,553
  • 5
  • 28
  • 57
2

Yes, for a zero-terminated c-string you can use the following

for(int i=0; arr[i]; i++)

because the loop will stop when it encounters the nul-terminator.

This does not work for arrays, only for zero-terminated strings. (It would also work for arrays terminated by something that converts to false, but this is quite rare IMO. Thanks @François Andrieux)

alain
  • 11,939
  • 2
  • 31
  • 51
0

You probably want something likes this:

int main() {
  char arr[] = "Hello";

  for (int i = 0; char c = arr[i]; i++)
  {
    putc(c, stdout);
  }
}

The output will be

Hello

c = arr[i] will be 0 when yolu come to the end of the string, ans thus the loop will be terminated.

BTW: for(int i = 0; strlen(arr) > i; i++) is correct but inefficient. I let you find out why as an exercise.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
  • @JonathanLeffler see Rons answer, you can in C++. And since the OP has finally decided to use C++, this answer is totally valid ;-) – muXXmit2X Aug 30 '17 at 14:05
  • @muXXmit2X-- do note, though, that both this answer and Jonathan Leffler's comment were posted before OP removed the C tag – ad absurdum Aug 30 '17 at 14:08
  • @muXXmit2X: Since the C tag was removed, I'll remove my comment. That it is valid C++ is intriguing; it's a sufficiently recent change that I'd not noticed it fully. Thanks. – Jonathan Leffler Aug 30 '17 at 14:16
0

I am not sure if this is simplier but it is a bit different and works well for strings, not for other generic types;

You can use array[] to check for the string terminator

char array[10] = "hello";
for (int i = 0; array[i] != 0; i++) 
     myFunction(array[i]);

for string you can use pointer arithmetic instead

for (char *aPtr = array; *aPtr != 0; aPtr++)
    myFynction(*aPtr);
Serge
  • 11,616
  • 3
  • 18
  • 28
0

I'm aware that writing this:

for(int i=0; arr[i]; i++)

will save a few microseconds over writing this:

int array_length = strlen (arr);
for(int i=0; i < array_length; i++)

I'm also aware that constructions like the first are pretty idiomatic in C, and experienced C programmers are used to seeing them.

However, in my view, the circumstances have to be very particular for saving a few cycles to be more important than writing code that other folks will understand easily. As a person who spends a significant part of his working day looking for defects in other people's code, I really appreciate expressive coding practices.

Kevin Boone
  • 4,092
  • 1
  • 11
  • 15
  • 1
    `arr[i]` is only a valid condition if you are dealing with a null terminated sequence. If you're not you'll run of the back of the data. – NathanOliver Aug 30 '17 at 13:39
-1

you have many options but calling the strlen is the most ineffective one (especially if you do it the way shown). arr has to be the pointer to be incremented

while(*arr)
{
   /* do something */
   arr++;
}

while(arr[i])
{
   /* do something */
   i++;
}

do
{
   /* do something */
}while(*++arr);

do
{
   /* do something */
}while(arr[++i]);



for(;*arr;arr++) 
{
   /* do something */
}

do  // is you need to do somethingh with the trailing zero
{
   /* do something */
}while(*arr++);

do // is you need to do somethingh with the trailing zero
{
   /* do something */
}while(arr[i++]);

etc etc.

0___________
  • 60,014
  • 4
  • 34
  • 74
  • 3
    calling the `strlen` is the most __ineffective__ one – Jabberwocky Aug 30 '17 at 13:32
  • @Michael Walz |of course. good point. My tablet dictionary has right opposite opinion :D – 0___________ Aug 30 '17 at 13:34
  • I know it's inefficient, but why would it be ineffective? It does what is says on the tin, just not in the fastest possible way. – stefaanv Aug 30 '17 at 13:42
  • 3
    If `arr` is an array then you cannot increment it like you are doing – NathanOliver Aug 30 '17 at 13:42
  • @stefaanv: The `strlen` counts every character (each iteration) to determine the length of a character array. If the length doesn't change, the size only needs to be calculated once (preferable before the loop). Thus the efficiency issue: calculating a constant length each time in the loop. *Note: smarter compiles with optimization set high may apply optimization and store the length in a temporary variable or register.* – Thomas Matthews Aug 30 '17 at 16:03
  • @ThomasMatthews: kindly look up the difference between effective and efficient to understand my comment. – stefaanv Aug 30 '17 at 16:18