string in c programming

Thread Starter

vead

Joined Nov 24, 2011
629
Hello everyone
I need help to understand how does below code work. whole code I tested. it show the message "ELECTRONICS"; on LCD. but I am not getting idea . how does below part of program work
Code:
void main()
{
    unsigned char a[15]="ELECTRONICS";    //string of 14 characters with a null terminator.
    int l=0;         // integer data type  with 0 variable value 
    lcd_init();
    while(a[l] != '\0') // I don't understand this line
    {
        lcd_data(a[l]); // whats the use of this line
        l++;              // increment
        msdelay(50); // this is delay
    }
}
 

nsaspook

Joined Aug 27, 2009
12,777
Hello everyone
I need help to understand how does below code work. whole code I tested. it show the message "ELECTRONICS"; on LCD. but I am not getting idea . how does below part of program work
Code:
void main()
{
    unsigned char a[15]="ELECTRONICS";    //string of 14 characters with a null terminator.
    int l=0;         // integer data type  with 0 variable value
    lcd_init();
    while(a[l] != '\0') // I don't understand this line
    {
        lcd_data(a[l]); // whats the use of this line
        l++;              // increment
        msdelay(50); // this is delay
    }
}
Give it your best try to explain it to us first.
 

Thread Starter

vead

Joined Nov 24, 2011
629
okay trying best
Code:
void main()
The line void main() is the main function where program execution begins.
Code:
 unsigned char a[15]="ELECTRONICS";
Here a is variable of character type and the length of array is 15. , when we assign a string value, it will assign ASCII values associated with characters
Code:
lcd_init();
call the lcd_init function. start LCD set position of cursor send command ..etc
Code:
  while(a[l] != '\0')
here is while loop . but I don't understand what is this (a[l] != '\0')
Code:
 lcd_data(a[l]);
send the data
Code:
 l++;
increment variable by 1
Code:
 msdelay(50)
give delay
 

nsaspook

Joined Aug 27, 2009
12,777
"here is while loop . but I don't understand what is this (a[l] != '\0')"

What does C use to MARK the end of a 'string' in a char array like this one: unsigned char a[15]="ELECTRONICS"; ?
The length of a C string is found by searching for the (first) NUL byte. This can be slow as it takes O(n) (linear time) with respect to the string length. It also means that a NUL cannot be inside the string, as the only NUL is the one marking the end.

Why are you asking about advanced programming concepts like RTOS kernels if you don't know the answers to basic questions like this?
 

WBahn

Joined Mar 31, 2012
29,857
In C, strings are NUL terminated, meaning that after the ASCII code of the final character in the string, the ASCII code for the NUL character, which is '\0', is added.
 

Thread Starter

vead

Joined Nov 24, 2011
629
"
Why are you asking about advanced programming concepts like RTOS kernels if you don't know the answers to basic questions like this?
yas I have asked question about RTOS.. if you see in my post. I am not asking to develop RTOS kernel program. I have only asked. what is kernel in programming. I asked for simple Learning example so that I can get idea on what I need to do and where I have to start. I know I am a too long to develop RTOS program.
 

nsaspook

Joined Aug 27, 2009
12,777
yas I have asked question about RTOS.. if you see in my post. I am not asking to develop RTOS kernel program. I have only asked. what is kernel in programming. I asked for simple Learning example so that I can get idea on what I need to do and where I have to start. I know I am a too long to develop RTOS program.
I feel your pain but this string in C question tells me you only have a shallow understanding of C programming.

Slow down, you're tipping over your own feet in your enthusiasm. Learning is a building process that needs a good foundation for the entire learning structure to be solid. Parroting code from random examples will only build a shack that will collapse at the slightest touch.
 

Thread Starter

vead

Joined Nov 24, 2011
629
I feel your pain but this string in C question tells me you only have a shallow understanding of C programming.

Slow down, you're tipping over your own feet in your enthusiasm. Learning is a building process that needs a good foundation for the entire learning structure to be solid. Parroting code from random examples will only build a shack that will collapse at the slightest touch.
That's why now I am learning basic to make good foundations. Thanks for your advice
 

WBahn

Joined Mar 31, 2012
29,857
A good place to start (or at least peruse in parallel) is the C language standard. You can find the C99 draft standard for free in lots of places. Don't try to read the entire document or understand every detail, but rather use it like a detective trying to ferret out information relative to a specific question or issue. At first you will find it difficult to understand a lot of what you see, but it will introduce you to a lot of concepts about programming and compilers in general, as well as C in specific, that will become hooks for further investigation. Over time you will find yourself drawn to exploring more of these concepts and playing with them and with each pass you will learn something new and gain an increasingly complete understanding of these topics.
 

ErnieM

Joined Apr 24, 2011
8,375
I don't agree reading the language specification will be of any use to a ,, as it just describes the "what" without answering any of the "how" or "why."

If you have any programming experience at all a very good book is "The C Programming Language" written by Brian W. Kernighan and Dennis Ritchie, who happen to have also written C itself.

This book does not teach programming, it does show you how to use C to perform many useful tasks.

(I do hope the above link to a PDF version of the book is to a legal public domain copy. Mods please take note if this is not so.)

MOD NOTE: At the very least, the second edition of K&R is still in print and under copyright. So the link to the PDF file has been removed.
 
Last edited by a moderator:

dl324

Joined Mar 30, 2015
16,675
Also note that the while loop is more verbose than it need be.
Code:
void main() {
  unsigned char a[15]="ELECTRONICS";
  int l=0;
  lcd_init();
  while(a[l]) {
    lcd_data(a[l++]);
    msdelay(50); // this is delay
  }
}
And that most would use a pointer (which the compiler probably does anyway):
Code:
void main() {
  unsigned char a[15]="ELECTRONICS";
  char *cptr = a;
  lcd_init();
  while(*cptr) {
    lcd_data(*cptr++);
    msdelay(50);
  }
}
 

nsaspook

Joined Aug 27, 2009
12,777
Also note that the while loop is more verbose than it need be.
Code:
void main() {
  unsigned char a[15]="ELECTRONICS";
  int l=0;
  lcd_init();
  while(a[l]) {
    lcd_data(a[l++]);
    msdelay(50); // this is delay
  }
}
And that most would use a pointer (which the compiler probably does anyway):
Code:
void main() {
  unsigned char a[15]="ELECTRONICS";
  char *cptr = a;
  lcd_init();
  while(*cptr) {
    lcd_data(*cptr++);
    msdelay(50);
  }
}
I usually don't replace array semantics with pointers unless it's needed because they are not exactly equivalent.
C:
char array_place[100] = "don't panic";
char* ptr_place = "don't panic";

int main()
{
char a = array_place[7];
char b = ptr_place[7];

return 0;
}
The semantics of arrays in C dictate that the array name is the address of the first element of the array. Hence in the assignment to a, the 8th character of the array is taken by offsetting the value of array_place by 7, and moving the contents pointed to by the resulting address into the al register, and later into a.

On the other hand, the semantics of pointers are quite different. A pointer is just a regular variable that happens to hold the address of another variable inside. Therefore, to actually compute the offset of the 8th character of the string, the CPU will first copy the value of the pointer into a register and only then increment it. This takes another instruction [1].
http://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c[/code]
 

WBahn

Joined Mar 31, 2012
29,857
I don't agree reading the language specification will be of any use to a ,, as it just describes the "what" without answering any of the "how" or "why."

If you have any programming experience at all a very good book is "The C Programming Language" written by Brian W. Kernighan and Dennis Ritchie, who happen to have also written C itself.

This book does not teach programming, it does show you how to use C to perform many useful tasks.

(I do hope the above link to a PDF version of the book is to a legal public domain copy. Mods please take note if this is not so.)
We'll have to agree to disagree on this one. I know I've learned a LOT from the draft standard that I never learned from any of the couple dozen C texts that I've got. For just one example, I had never heard of "sequence points" until I was looking for other information in the standard. The information in the standard was more than sufficient to understand what they are and how they impact the logic of a program. Most texts merely state that doing such and such (for example, statements like i = i++ + ++i;) invoke undefined behavior and seldom state why? The language reveals why, so that instead of memorizing a list of things that you shouldn't do, you can understand how the language works and thus not only avoid the things on the list without having to memorize them, but also avoid things that aren't on your list because you've never run across them before or to analyze why your code is misbehaving when you inadvertently run into a new one.

I have problems with the K&R book just because it is too outdated as far as the language goes (although this is far less the case in the second edition). Several things in it are strongly deprecated or even simply not allowed by the later standards, and hence it teaches some bad programming habits (which weren't "bad" in the original language because you didn't have any other choice). That aside, I agree that it is a well-written text with a lot to offer.
 

WBahn

Joined Mar 31, 2012
29,857
(I do hope the above link to a PDF version of the book is to a legal public domain copy. Mods please take note if this is not so.)
I'm checking on this but I'm pretty sure it is not in the public domain. It is still in print by Prentice Hall and bears the copyright of Bell Labs. Will check some more.
 

WBahn

Joined Mar 31, 2012
29,857
Also note that the while loop is more verbose than it need be.
Code:
void main() {
  unsigned char a[15]="ELECTRONICS";
  int l=0;
  lcd_init();
  while(a[l]) {
    lcd_data(a[l++]);
    msdelay(50); // this is delay
  }
}
And that most would use a pointer (which the compiler probably does anyway):
Code:
void main() {
  unsigned char a[15]="ELECTRONICS";
  char *cptr = a;
  lcd_init();
  while(*cptr) {
    lcd_data(*cptr++);
    msdelay(50);
  }
}
I don't know that "most would use a pointer". Pointer syntax is, for the most part, syntactic sugar, but it's there for a reason. It makes the code much more readable for most people.

It also relieves the writer and reader from having to remember fine details of the precedence of operators. For instance, whether *cptr++ evaluates to (*cptr)++ or *(cptr++). Even if the writer gets it right, it can cause confusion on the part of the reader, either because they get it wrong or they have to spend time recalling it or looking it up. The array notation is completely unambiguous.

If you don't need the char array to be exactly 15 characters long, a better way to declare it is just

unsigned char a[] = "ELECTRONICS";

and let the compiler determine how much memory to allocate. That way if you lengthen the string later you don't create a bounds violation.
 

MrSoftware

Joined Oct 29, 2013
2,169
Side note; the way the original code checks for the end of the string (searching for a null character) is generally not a safe way to do it, so don't use that as-is in other code. If for whatever reason the string does not end with a null character, then the loop will continue on into memory that doesn't belong to the array. One way to make it safe is to also check the index value to be sure you don't go past the end of the allocated memory. Obviously this method works when the string is created correctly, but in more complex code it's not unheard of for a string to not be terminated properly for various reasons.

Code:
void main()
{
    unsigned char a[15]="ELECTRONICS";    //string of 14 characters with a null terminator.
    int l=0;         // integer data type  with 0 variable value
    lcd_init();
    while(l < 15 && a[l] != '\0') // Check for the end of string NULL,
                                             // AND that you don't pass your allocated memory while searching for the NULL
    {
        lcd_data(a[l]); // send a character to the lcd_data() function, probably to display the character
        l++;              // increment
        msdelay(50); // this is delay
    }
}
 
Last edited:

dl324

Joined Mar 30, 2015
16,675
Obviously this method works when the string is created correctly, but in more complex code it's not unheard of for a string to not be terminated properly for various reasons.
The correct method is to let the compiler do it as @WBahn mentioned in the post just before yours. If the string is being assigned dynamically, you can add code to malloc enough space. That way, the string will always be constructed properly and kludgey code can be avoided.
 

WBahn

Joined Mar 31, 2012
29,857
Side note; the way the original code checks for the end of the string (searching for a null character) is generally not a safe way to do it, so don't use that as-is in other code. If for whatever reason the string does not end with a null character, then the loop will continue on into memory that doesn't belong to the array. One way to make it safe is to also check the index value to be sure you don't go past the end of the allocated memory. Obviously this method works when the string is created correctly, but in more complex code it's not unheard of for a string to not be terminated properly for various reasons.

Code:
void main()
{
    unsigned char a[15]="ELECTRONICS";    //string of 14 characters with a null terminator.
    int l=0;         // integer data type  with 0 variable value
    lcd_init();
    while(l < 15 && a[l] != '\0') // Check for the end of string NULL,
                                             // AND that you don't pass your allocated memory while searching for the NULL
    {
        lcd_data(a[l]); // send a character to the lcd_data() function, probably to display the character
        l++;              // increment
        msdelay(50); // this is delay
    }
}
In the above example, what happens when the person goes back later and modifies the first line to

unsigned char a[15]="BASIC ELECTRONICS"; //string of 14 characters with a null terminator.

Or let's say that do catch that they need to increase the size of the array and change it to

unsigned char a[20]="BASIC ELECTRONICS"; //string of 19 characters (max) with a null terminator.

Now what happens when the code gets to

while(l < 15 && a[l] != '\0') // Check for the end of string NULL,
// AND that you don't pass your allocated memory while searching for the NULL

There's an extremely high likelihood that they will miss one of these hardcoded constants someplace, particularly in any meaningfully-sized code base.

If you really must hardcode the size of the array, it is better to do something like

Code:
#define STRINGMAX (14)
#define STRINGARRAYSIZE (STRINGMAX + 1)

void main()
{
    unsigned char a[STRINGARRAYSIZE]="ELECTRONICS";    //string of STRINGMAX characters plus a NUL terminator.
    lcd_init();
   for ((i = 0; i < ( (STRINGARRAYSIZE) && ('\0' != a[i]) ); i++) // Check array bounds then look for NUL
    {
        lcd_data(a[i]); // send a character to the lcd_data() function, probably to display the character
        msdelay(50); // this is delay
    }
}
But this still requires the programmer to manual ensure that STRINGMAX and the actual size of the string are compatible. A much better way is to let the compiler ensure this

Code:
#define DELAYTIME (50)

void main()
{
    unsigned char a[]="ELECTRONICS";    //string of STRINGMAX characters plus a NUL terminator.
    lcd_init();
   for ((i = 0; i < ( sizeof(a) && a[i] ); i++) // Check array bounds then look for NUL
    {
        lcd_data(a[i]); // send a character to the lcd_data() function, probably to display the character
        msdelay(DELAYTIME); // this is delay
    }
}
Notice that I used a symbolic constant for the delay amount. In general, I believe that there should be no informational constants in a program ("informational" does not include "trivial" constants whose value and meaning are fixed and obvious -- but deciding which is which can certainly be a coin flip)

Of course, this code only works with variables of array type. If it is dynamically allocated then you have a bigger problem; then knowing where the end of allocated memory is isn't trivial. You have to track every allocation of memory and record it somehow and then make that information available to every function that accesses the string. You could do this in a global table (essentially making your own stripped-down memory manager) or create a structure for a string object that carries this information.
 

WBahn

Joined Mar 31, 2012
29,857
The correct method is to let the compiler do it as @WBahn mentioned in the post just before yours. If the string is being assigned dynamically, you can add code to malloc enough space. That way, the string will always be constructed properly and kludgey code can be avoided.
The care that must be taken here is that the contents of the string not be changed (or that any function that changes them first finds the length of the string to ensure that changes only take place within it). Using the const modifier appropriately can help the compiler tell you that you are doing something you possibly shouldn't, but there are too many ways to get around the const restrictions.
 

eetech00

Joined Jun 8, 2013
3,820
Hi

my take on this:

If a char variable is Initialized with a specific length, then there is no null character unless it is assigned to an element in the array.

char [2] = "a"; /no null terminator

If the char variable is initialized with an unspecified length, then a null termination character is placed in the array.

char [] = "a"; / null terminated
 
Last edited:
Top