For more blog posts, see the complete catalog of the romantic carriage of audio and video systems learning

The last ramble on C language pointer (I) mainly talked about the basic concept of pointer related and basic use, today based on the last blog to further talk about the relationship between pointer and array, string pointer, pointer variable as a function parameter.

Pointers and arrays

An array is a collection of data of the same type. Each piece of data is called an array element.All elements of an array are arranged consecutively in memory, with no gaps between themThe entire array occupies one block of memory.In C,The array name can be converted to a pointer to the first address of the 0th element of the array.

So the traversal number group in addition to the usual:

int main(a){
    int arr[] = { 3.34.44.67.234 };
    int len = sizeof(arr) / sizeof(int);  // Find the length of the array
    int i;
    for(i=0; i<len; i++){
        printf("%d ", arr[i] ); }}Copy the code

Can also:

int main(a){
    int arr[] = { 3.34.44.67.234 };
    int len = sizeof(arr) / sizeof(int);  // Find the length of the array
    int i;
    for(i=0; i<len; i++){
        printf("%d ", *(arr+i) );  //*(arr+ I) = arr[I]}}Copy the code

(*(arr+ I) calculation can be seen in the ramble C language pointer (a) on the pointer arithmetic operation that section)

In fact, arr[I] is exactly equivalent to * (arr+ I), both representing a pointer to the starting address of the array plus the offset. A reference to an array, a[I], is always overwritten by the compiler at compile time as * (a+ I), a behavior that is required by the C standard.

So, are array names and Pointers exactly equivalent? This is a confusing point in the learning pointer.

int a[6] = {0.1.2.3.4.5};
    int *p = a;
    int len_a = sizeof(a) / sizeof(int);
    int len_p = sizeof(p) / sizeof(int);
    printf("a length = %d, p length = %d\n", len_a, len_p);
}
Copy the code

A is the name of the array, so it refers to the address of the 0th element of array A, and a pointer p is defined and initialized to the value of a, so p refers to the address of the 0th element of array A.

a length = 6, p length = 2

Sizeof (a) equals the sizeof the array, sizeof(p) equals the sizeof the pointer variable itself in the current environment.

A is an array, p is a pointer to an int, p is a pointer to an int, p is a pointer to an int, p is a pointer to an int, and p is a pointer to an int. But in general, a is converted to a pointer to the first address of the 0th element.

What’s interesting is the relationship between a and ampersand a, what does ampersand a stand for? One would think that since a representative array the zeroth element of a first address, and the pointer itself a & a is address – the recruit, above, having said that, in general, will be converted to a pointer to the first address of the zeroth element, in addition to the sizeof, still have a kind of situation, is & a, also belong to “the general”. When ampersand is used, the array name is still an array, not a pointer. ** Look at this example:

int main(a){
    int a[6] = {0.1.2.3.4.5};
    int *p = a;
    printf("a = %d\n", a);
     printf("a+1 = %d\n", a+1);
    printf("*(&a) = %d\n", *(&a));
    printf("*(&a + 1) = %d\n", *(&a + 1));
    printf("p = %d\n",p);
    printf("p+1 = %d\n",p+1);
}
Copy the code

Running result: A = 6487536 *(&A) = 6487536 *(&A +1) = 6487560 P = 6487536 P +1 = 6487556

See that both a and ampersand a and p are equal, so ampersand a does not address pointer A, it addresses array A. Notice that (&a +1) = 6487560, and a+1 = 6487556, which is kind of weird. The sizeof a pointer depends on the type to which the pointer points. A +1 prints 4 times larger than a, and is the sizeof sizeof (int). So, (&a + 1) is 24 bytes larger than a, that is, the 1 of (&a + 1) corresponds to 24 bytes. The array A consists of exactly six ints, and the array has five consecutive gaps in memory. &a refers to int A [6] (each array can also be treated as a type), so the step size is different, resulting in different arithmetic results

The name of the array, when defined or used with sizeof and &, is converted to a pointer to the 0th element in the array.

An array name is a pointer constant that cannot point to any other memory address:

If STR is assigned this way, the compilation will report an error.

char str[] = "abcdefg";
str = 'tddd';
Copy the code

String pointer

There is no specific string type in C. Strings are essentially an array of characters. Therefore, strings can be defined in C as follows:

char str[] = "abcdefg";
Copy the code

The string can be printed directly, or it can be printed using normal array traversal:

	printf("%s\n", str);
    // Output one character at a time
    for(i=0; i<len; i++){
        printf("%c", str[i]);
    }
Copy the code

Of course, as we’ve already seen, array names can be converted to Pointers in expressions, so strings can be traversed using Pointers:

 for(i=0; i<len; i++){
        printf("%c", *(str+i));
    }
Copy the code

For special character creation, we can also use character Pointers to define strings:

char *str = "abcdefg";
Copy the code

I don’t know if you remember, in the article on MEMORY management in C, we mentioned that the character pointer definition of the string is stored in the constant area, while the array definition is stored in the heap or stack, since it is in the constant area, even though it is not modifiable.

If you try to modify:

char *str = "abcdefg";
 *(str + 1) = 't';
Copy the code

An error is reported when running because an attempt is made to modify a constant area that cannot be modified: Process Finished with exit code -1073741819 (0xC0000005)

But Pointers can be used to point to other strings:

 char* str1 = "dfafdf";
 str1 = "abc";
 printf("%s\n", str1); ` ` `Copy the code

Run result: ABC

So character Pointers are constant Pointers, that is, Pointers to constants.

Pointer variables as function parameters

In the discussion on pointer (1) of C language, “changing the value of variable outside the function by passing a pointer parameter” mentioned that function passing a parameter is essentially copying a copy of the parameter inside the function. If array is used as parameter, do you also need to copy a copy?

We can verify this by printing the first address of the array passed to the function and comparing it with the first address of the array passed to the function:

void arrayMethod(int x[],int len) {
    printf("changeValue %#X\n", x);
}
Copy the code
int main(a) {
    int x[] = {1.2.3.4.5};
    arrayMethod(x,5);
    printf("main %#X\n", &x);
}
Copy the code

Result: changeValue 0X62FE00 main 0X62FE00

The result is not the same as the result of the C pointer (1). In the C pointer (1), the printed address is different, but in this case, the printed address is the same, indicating that there is no copy of the array passed inside the function.

In fact, arrays passed as arguments to functions are essentially also passed as array Pointers:

void arrayMethod(int *x,int len) {}Copy the code

We can use sizeof /sizeof to determine the number of elements in an array. Now we are trying to find the same number of elements in an array as in a function that takes an array:

Sizeof (a)/sizeof(int
void arrayParam(int a[]) {
    int len_a = sizeof(a) / sizeof(int);
    printf("arrayParam len_a %d\n", len_a);
}

int main(a) {
    int a[] = {1.2.3.4.5.6};
    int len_a = sizeof(a) / sizeof(int);
    int *p = a;
    printf("main len_a %d\n", len_a);
    arrayParam(a);
    printf("main len_p %d\n".sizeof(int*) /sizeof(int));// the sizeof a pointer in the current environment (to make it easier to compare len_a, divide by sizeof (int), of course you can substitute any other type of pointer)
}
Copy the code

Run result: main len_A 6 arrayParam len_A 2 main len_p 2

It can be seen outside the function and the function of array element number is different, the result of the change and here no matter how the number of array elements, seeking out the length of the function and the pointer to the current environment of the same length, which further proves the array passed as a parameter to function, nature will be converted to an array of Pointers to functions.

Why do we do that? Because the array is a collection of an unknown number inside, is likely to be very big, so if the reference is also directly in a data copy function in the stack, the space and time are very big, so by the address, just need to copy the pointer variable itself, so you can easily process incoming array within the function.

On C language pointer (3)