Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”

This article has participated in the “Digitalstar Project” and won a creative gift package to challenge the creative incentive money.

Strings are common in programs and are as much a part of code as integers, decimals, and characters. But strings are different from other types and have their own personalities.

Let’s look at this directly in a piece of code.

Define a character 1. A string 1, and print them out as follows:

From the print, there’s no difference.

Now let’s print the length of these two, using sizeof() to calculate the length of s1 and s2 and print them out.

The length of s1 is 1, and the length of s2 is 2

From the memory location, you can see that the character S1 takes up one byte, the string s2 takes up two bytes, and the following byte is empty. So the sizeof s2 by sizeof() is 2.

Sizeof () and strlen(), both of which compute the length of a string, but sizeof() computes the sizeof the actual space taken up, while strlen() computes the length of a valid character. So sizeof() is one more than strlen() for a string.

For example, here we define a string “ABC” and use these two functions separately to calculate its length.

char s2[]="123";
printf( " %d %d\r\n\r\n\r\n".sizeof(s2),strlen(s2));
Copy the code

As you can see from the printed result, the effective length of the string is 3, but the space taken up by the string is 4.

Now let’s see if the operation on characters is the same as the operation on strings.

Reassignment of s1 and s2 is not allowed because strings are stored in memory as character arrays, i.e., in a series of contiguous storage Spaces, one byte for each character. So you can’t manipulate a string as a whole, you can only change the value of a string individually, just like you can change the value of an array.

So to change the character stored in the string, we assign the 0th bit of the array directly.

You can see that reassigning the 0th bit of s1 and S2 changes the data stored in memory as well as the printed data.

Note that the characters stored in the memory are stored in ASCII format, while the characters printed from the serial port are directly characters. ASCII 0x31 corresponds to character 1, and ASCII 0x32 corresponds to character 2.

Similarly, assigning one character to another can be done normally, but one string cannot be directly assigned to another string.

To assign a string to another string, you need to do the same bit by bit assignment as an array.

The print result is as follows

View it in memory

The in-memory results are the same as the printed results. Let’s look at an example of passing s1 and s2 to other functions to operate on.

char s1='1';
char s2[]="1";

void change1(char s3)
{
  s3 = s3 + 1;  
  printf( "s3 -> %c \r\n", s3 );  
}
void change2(char s4[])
{
  s4[0] = s4[0] + 1;
  printf( "s4 -> %s \r\n", s4 );  
}

void main( void )
{
   // omit extraneous code
    while( 1 )
    {     
        change1(s1);
        change2(s2);
        printf( "s1 -> %c s2 -> %s\r\n\r\n\r\n", s1,s2 );   
             
        delay_ms( 5000); }}Copy the code

After passing s1 and S2 values to the external function, increment the characters in the external function and print them out. After exiting from the external function, print s1 and S2 values.

The print result is as follows

S1 is the value of character 1, and s1 is passed to s3, and s3 is incremented by 1 to print character 2, which is code logic.

The value of s2 is the string 1, and s2 is passed to S4, which then increments by 1 to print out character 2, following code logic.

After exiting from the subfunction, print the values of s1 and s2, respectively. You can see that s1 is still 1, but S2 is 2.

If the program continues, s1 and S3 remain the same, but S2 and S4 continue to increase.

What is the reason for this? When a string is passed to a subfunction, the string itself changes, right?

To see what’s going on, let’s step through it and look at what’s happening to the data in memory.

When the code executes to s3 = s3 + 1; In this row, s3 is stored in position A, the value is character ‘1’, and s1 is stored in position 0x00000C. Add 1 to S3.

After the increment, s3 is changed to character ‘2’, while s1 is still character ‘1’.

Next, the second function operates on the string S4.

S4 [0] = S4 [0] + 1; In this line, the memory address of S4 is 0x00000D and the memory address of S2 is 0x00000D. Continue to observe the program.

When the 0 th character in S4 is incremented by 1, the character in S4 becomes ‘2’, and the character in S2 also becomes ‘2’, indicating that S4 and S2 are indeed the same address in memory.

After the execution of the two functions, continue to print the values of s1 and s2. Since the address of S1 has not changed during the execution of the sub-function, s3 is s1 plus 1. S2 and S4 refer to the same address, and S4 is incremented by 1 each time.

Why is there no change for characters, but a change for strings? Is this because in C strings are reference types and characters are value types?

The value types include: byte, short, int, long, float, double, decimal, char, bool, and struct.

Reference types include string and class.

When the system operates on a value type and assigns a value from one value type to another, the system creates a new space, copies the value, and then stores the value into the new space. In this way, when new data is manipulated, the previous data is not affected, because both values are in their own storage space.

System for reference types, if will be a reference type assigned to another reference type, the system detected the two values if finished all the same, then the system would not have to open up space for new reference types, but directly to the new address of a reference type pointing to the old reference types, and let the two values Shared memory space, This is the equivalent of giving an address space two names, so that when you change either value, the value in the address space will also change.

So be aware of this when using strings. This is the biggest difference between strings and other types of values. If you’re not careful, data can easily go wrong in passing values.