How do strings and constants differ in C from other languages? Pointers are everything, so what is the relationship between Pointers and strings and constants?

string

C has no explicit string type. Strings in C are stored as string constants or arrays, and C provides a series of library functions to manipulate strings in the String.h header. In C, a string ends when it meets \0.

  1. Strings stored in arrays are stored on the stack
    // Array char is in the stack
    char data[] = {'a'.'b'.'c'.'d'.'e'.'\ 0'};// Add \0 to the array manually
    printf("%s\n", data);// Prints the string abcde
Copy the code
  1. There is a problem with using an array to print a string without ending it with \0, as follows:
    // if you do not define \0
    char data2[] = {'a'.'b'.'c'.'d'.'e'};//data2:abcdeabcde does not stop until it encounters \0 in memory
    printf("data2:%s\n", data2);
    char data3[5] = {'h'.'e'.'l'.'l'.'o'};
    printf("data3=%s\n", data3);//data3=helloabcdeabcde
Copy the code
  1. If an array is equal to a string directly, it automatically adds a \0 by default
    char data[] = "abc";// a \0 is added by default
Copy the code
  1. A string pointed to by a pointer is stored in the constant area

Note: The contents of the constant field cannot be modified. An error is reported if * STR =” ABC “. A string declared by a char * pointer does not use \0; the compiler automatically adds the \0 terminator

%s type STR without *

    // The pointer definition char abcde is in the constant area. Note that the contents of the constant area cannot be modified
    char *str = "abcde";// In C, the string is terminated by default with \0
    //%s Enter STR instead of *
    printf("%s\n", str);// Prints the string abcde
    while(*str ! ='\ 0') {
        //%c requires *
        printf("%c ", *str++);
    }
    printf("\n");

    // Data defined in constant fields cannot be modified
// *str = "hello"; / / an error
Copy the code

The difference between an array declaration string and a pointer declaration string is shown below:

  1. Scanf accepts the string input from the console

Note: scanf outputs a newline when a space is encountered, and automatically adds the \0 terminator when a carriage return is encountered.

 	// Define an array to input a string through scanf
    char data4[10];
    printf("input:\n");
    // Console input string
    scanf("%s", data4); // Note that scanf prints a line when it encounters a space and ends when it encounters a carriage return
    printf("data4=%s\n", data4);//data4=hello scanf will automatically add \0
Copy the code
  1. Gets is similar to scanf

Gets does the same thing as scanf, except that gets prints Spaces as strings.

char data4[10];    
gets(data4);//gets ends with a blank space as a string in a carriage return
printf("gets:%s\n",data4);
Copy the code
  1. fgets

Fgets is also a string that receives input from the console. In both gets and scanf, we need to fix the size of the array. Fgets is a loop output of a set of fixed lengths

    // Groups are of fixed length instead of array size
    while (1) {
        char str[10];
        fgets(str, 10.stdin);
        printf("str=%s\n", str);
    }
Copy the code

Input and output: Group output in a 10-string array length

input:
hello world this is fgets out 10The output is as follows: STR =hello wor STR =ldthis i
str=s fgets o
str=ut 10
Copy the code
  1. gets orscanf Can accept achar *Pointer to?

As mentioned above, the string declared by char * is in the constant area, and the contents of the constant area are not modifiable, so gets and scanf will get an error if they accept a char *. However, the point of a pointer can be changed, and the content of a pointer cannot be changed by a pointer.

    // Note that the input cannot use char * because the string declared by char * is in the constant area and cannot be modified
    char *s1 = "abc";
    *s1 = "a";// This does not work, it is to change the constant content
    s1 = "bcd";// Change the pointer pointer without changing the constant
    gets(s1);*s1 = XXXX *s1 = XXXX *s1 = XXXX *s1 = XXXX
    printf("s1:%s\n",s1);
Copy the code

Constant Pointers and pointer constants

Const const const const const const const const const const const const const const const const const const const const const const const const const const const const const const char * STR = “ABC “; STR is a constant pointer, because “ABC” is stored in the constant area, and the pointer points to a constant.

  • And const first read: * pointer, const constant

Constant pointer: A pointer to a constant. It cannot point to a variable. It cannot change what it points to.

    // Constant pointer: a pointer to a constant can be changed, but the contents of the address cannot be changed
    char *s = "abc";
    const int *ptr;//const closest to * PTR cannot be modified
    int const *ptr2;//const closest to *ptr2 cannot be modified
Copy the code

Pointer constants: A pointer is a constant. The address to which it points cannot be changed, but the contents of the address can be changed by a pointer. Therefore, a pointer constant must be assigned a value when it is defined, and the address to which it points remains with it for life.

    // Pointer constant: A pointer is a constant. The address to which it points cannot be changed
    int a = 2;
    int * const b = &a;//b is a pointer constant, and whoever is closest to const cannot change the address pointed to by b
Copy the code

Common operations on strings

  1. Length of string

The length of a string can be defined in two ways:

  1. Sizeof gets the length of the string, but that’s not an accurate way to get it why? Because strings in C have one by default\ 0End character, andsizeofwill\ 0If you add that in, it’s going to be greater than 1.
  2. Strlen () function: can get the actual string length, get the string size before the \0 terminator, but if encountered"abc\0de" strlenThe size you get is 3, encountered\ 0The end.
    char *s = "abc";
    printf("string size:%d\n".strlen(s));//string size:3
    printf("s sizeof:%d\n".sizeof(s));/ / 8
    printf("data sizeof:%d\n".sizeof(data));// the extra one is \0
Copy the code
  1. Strcpy string copy function

Strcpy replaces the target string with: hellotest -> jake Copy jake to helloTest and the result is: jake\0test. Note: The size of the target string does not change, strlen is terminated by \0, so strlen is not necessarily equal to the size of the target string

As shown below:

The string should be an array, not a constant pointer, because the contents of the constant area cannot be changed

    char s1[] = "hellotest";// Stored on the stack
    printf("len:%d\n".strlen(s1));//9 strlen = 0
    printf("sizeof:%d\n".sizeof(s1));// The size of the 10 array is too large for \0
// Copy jake to s1
    strcpy(s1,"jake");// Hello before jake\0test has been replaced

    printf("%s\n",s1);// Jake output string is automatically terminated when it encounters \0
    printf("len:%d\n".strlen(s1));//4 strlen = 0
    printf("%d\n",s1[4]);// The fifth element is 0. In C the string ends when it encounters \0
    printf("%c\n",s1[5]);// The sixth element t
    printf("sizeof:%d\n".sizeof(s1));// The size of the 10 array has not changed
Copy the code

Using a constant pointer results in an error

When declaring a string, it is important to note that the contents of the string declared as an array can be changed in the stack area. If the string declared as a pointer is stored in the constant area, the contents of the constant area cannot be changed

  char *s3 = "abc";
  strcpy(s3,"d"); // Error strcpy cannot be passed
  printf("s3:%s\n",s3);
Copy the code
  1. Concatenation of strings

How to concatenate strings in C? In the Java language, you can concatenate strings directly using the + sign, but not in C

printf("%s\n"."a"+"B");/ / error
Copy the code

You can concatenate strings as Pointers, move the target pointer to the end and then ++ concatenate

Note the string declared as a pointer, the content cannot be changed, note note note!! It’s so important that it should be repeated for three times.

// String concatenation
void mystrcat(char *s1,char *s2){
    //s1 and s2 point to strings stored on the stack so they can be manipulated by Pointers
    while (*s1) s1++;//while(\0) loop ends s1 -> \0
    // change the pointer to s1 -> \0 -> *s2
    while (*s1++=*s2++);//s1 = \0 to end the loop
}
    char s4[] = "abc";/ / stack
    char s5[] = "123";/ / stack

    // String concatenation
    // if char * s4=" ABC "char * s5 =" 123" this will not work because the contents of the constant section cannot be modified
    mystrcat(s4,s5);
    printf("s4:%s\n",s4);//s4:abc123
    printf("s4:%d\n",s4[6]);/ / 0
Copy the code
  1. String array

A string is itself an array, so a string array is a two-dimensional array.

Array of strings: Pointer constants

    // Pointer constants
    char arr[4] [6] = {"abc"."def"."123"."wer"};
    // Arr -> * const
// arr[0] = "sds"; Arr [0] = "ABC" is a pointer constant
    printf("arr[0]:%s\n", arr[0]);//arr[0]:abc
    // You can change what you point to
    strcpy(arr[0]."aabbcc");//arr[0]: aABbcc can modify the content can not modify the address: pointer constant
    printf("arr[0]:%s\n", arr[0]);
Copy the code

Array of strings: constant Pointers

 Arr1 [0]: char *,char *,char *,char *}
    char *arr1[4] = {"abc"."123"."sd"."se"};
    arr1[0] = "abd";Char * arr1 = "ABC" is a constant pointer
    printf("value:%s\n", arr1[0]);//value:abd
    strcpy(arr1[0]."aabbcc");// Modify content error
    printf("value:%s\n", arr1[0]);
Copy the code

Pointer constant: Refers to a pointer. The address to which the pointer points cannot be changed, but the content to which the pointer points can be changed. Constant pointer: Modifies content. The address to which a pointer points can be changed. The content to which a pointer points cannot be changed in the constant area.

The structure of the body

Structs are similar to Javabeans and are commonly used to define modle

// A javabean-like structure
    struct stu{
        char *name;
        int num;
        int age;
        char group;
        float scope;
    } person3;// Set the structure when declaring

    // Similar to anonymous inner classes
    struct{
        char *name;/ / 8

        int num;/ / 4
        int age;/ / 4

        // These are also counted as 8 bytes
        char group;/ / 1
        float scope;/ / 4
    } person4;// Set the structure when declaring

    // Define the structure
    struct stu person.person2;
Copy the code

Calculates the size of the structure in bytes

How does the structure calculate the size of the bytes consumed? On a 64-bit machine, Pointers account for 8 bytes, ints for 4 bytes, chars for 1 byte, floats for 4 bytes, and doubles for 8 bytes.

    struct stu{
        char *name;/ / 8
        int num;/ / 4
        int age;/ / 4
        char group;/ / 1
        float scope;/ / 4
    } person;
printf("person:%d\n".sizeof(person));// Total size: 24 bytes
Copy the code

However, the above code results in 24 bytes. In fact, we calculate 8+4+4+1+4 = 21. On a 64-bit machine, C usually reads 8 bytes at a time, and moves to the next 8 bytes if it exceeds them.