1

I wrote a C Programm that tells me the length, the lowest and highest ANSI character. The one thing I didn`t understand, why do I have to declare cString in the main function, and not sString?

#include<stdio.h>
#define LENGTH 64

int stringstats(char sString[], char* cHighest, char* cLowest) {
    int iLength = 0;
    int i = 0;
    *cLowest = sString[0];
    *cHighest = sString[0];

    while(sString[iLength] != '\0') {
        iLength++;
    }

    for(i = 0; i <= iLength-1; i++) {
        if(sString[i] < *cLowest)
            *cLowest = sString[i];

        if(sString[i] > *cHighest)
            *cHighest = sString[i];
    }

    return iLength;
}

int main(void) {
    char cString[LENGTH] = {0};
    int iLength = 0;
    char cHighest = 0;
    char cLowest = 0;

    while(1) {
        printf("input String ('q') to exit) \n");
        scanf("%62s", cString);

        if(cString[0] == 'q')
            break;

        iLength = stringstats(cString, &cHighest, &cLowest);

        printf("Length = %i \n", iLength);
        printf("Lowest Character = %c \n", cLowest);
        printf("Highest Character = %c \n\n", cHighest);
    }

    return 0;
}
Nick
  • 1,361
  • 1
  • 14
  • 42
cauchy100000
  • 29
  • 1
  • 5
  • 1
    You do not have to declare `cString` using that name; you could use any name as long as you're consistent. – Jonathan Leffler Dec 09 '14 at 14:42
  • 1
    What and where would you have expected to declare `sString`? – Bill Lynch Dec 09 '14 at 15:12
  • Or is this just a duplicate of: http://stackoverflow.com/questions/22677415/why-do-c-and-c-compilers-allow-array-lengths-in-function-signatures-when-they/22677793#22677793? – Bill Lynch Dec 09 '14 at 15:14
  • 1
    The name in the *function declaration* does not matter; it is local to the function *only*. This even overrides a global variable with the same name. – Jongware Dec 09 '14 at 15:15

2 Answers2

2

Fundamentally in C strings are character arrays. To be very technical they should be terminated with a null character '\0' for use with cstd string lib, string.h.

So what then is an array? It is a continuous block of elements that all have the same type. You can consider array notation just another form of pointer notation to access that contiguous block of memory**.

Saying x = array[0] is really the same as x = *array, and x = array[5] is really the same as x = *(array+5)

When you pass an array in C as a function parameter you're really just passing a pointer to the head of the character array. Your code could just as easily be

int stringstats(char * sString, ... )

So to answer your question:

why do I have to declare cString in the main function, and not sString?

Your array is defined in main() - that's where it exists in memory. It is allocated on the stack and its scope is limited to main(). You did not need to declare it in stringstats(), nor could you. But when you passed a pointer to sString you referenced the array. In doing so you actually defined a pointer to the array on the stack - another auto variable whose scope is limited to stringstats().

If cString was global variable in the same file as main() and stringstats() were in another file you could have then declared cString in stringstats() via extern. This is not the same as defining cString because you wouldn't be allocating new storage for it.

Here is a related post: C pointer notation compared to array notation: When passing to function

** They are almost the same thing, but I would like to point out one caveat. In C there is something called the array type. Because of it sizeof() (which runs at compile time) can give you the size of the entire array. But when you pass this array it will 'decay' to a pointer, even if you pass it with a size, e.g. foo(array[x]). That x is effectively useless. sizeof() will now just give you the size of the element you are pointing at.

Community
  • 1
  • 1
Nick
  • 1,361
  • 1
  • 14
  • 42
  • You can **not** consider arrays as "pointer notation" and this just makes an already confusing topic for beginners even worse. The array *is* a contiguous block of memory. A pointer is a thing that can point to a memory location. A pointer should not be confused with the thing it is currently pointing to, they are distinct objects. – M.M Dec 19 '14 at 05:23
  • @Matt McNabb I added to my post the bold text to further clarify: "**It is a continuous block of elements that all have the same type**. You can consider **array notation** just another form of pointer notation to access that contiguous block of memory**". It is important to make that point that array notation can be considered pointer notation because the array type decays into a pointer. Fundamentally everyone needs to know that when passing arrays to functions you are actually passing a reference to the first element. – Nick Dec 19 '14 at 14:56
2

I like Nick's answer, but it glosses over some items.

Fundamentally in C, strings are arrays of characters, which are eight bits long, which you may need one or more of to get something you can draw to the screen called a glyph.

So when you see the letter 'a' you are really seeing a glyph, which might be stored in one, two, three, or four characters. (In this case, it is stored in one character, but generally it depends).

For characters in the numeric range of 0-127, it is very safe to use 1 "C-char" to 1 "glyph" which is roughly what a person thinks of "1 character"; however, when you get into 128 and above, you need to know which set of rules (character set) you are following or you might find errors in logic because your logic doesn't follow the character encoding for your character set.

An example, if 'a' took two 'C characters', then if you wrote a simplistic routine to get the length, you might want to return 1 or 2 depending on what is needed.

Edwin Buck
  • 69,361
  • 7
  • 100
  • 138
  • Thanks for that - that's new for me. I have never ventured out of the standard ASCII set for my work so I've never needed a value over 127. – Nick Dec 09 '14 at 16:57
  • @Nick It's new for many people, and everyone starts out with the "1 C char == 1 character" idea. The main idea here is to just make you aware that it doesn't really hold in many scenarios. Later on you'll be aware of the limitations and learn the rest. Have a great day. --Edwin – Edwin Buck Dec 09 '14 at 19:23