The array name is not equal to the pointer---sizeof() function to find the wrong size of the array

Preface: Today, in the project, we need to find the number of sampling points and traverse them. The sampling points are stored in an array. I have customized a function to use sizeof to find its length, and then traverse it. The result fails. After consulting, I found the following problems:

In the main function, sizeof works fine

#include <stdio.h>

int Number[10];   

int main()
{
    
    
	int size = sizeof(Number);
	printf("数组大小为:%d\n",size);
	int len = sizeof(Number)/sizeof(int);
	printf("数组共有%d个数据\n",len);

	return 0;
}

Output:
insert image description here
But not in a custom function, as follows:

#include <stdio.h>

int Number[10]; 

void print_1(int n[])
{
    
    
	int size = sizeof(n);
	printf("数组大小为:%d\n",size);
	int len = sizeof(n)/sizeof(int);
	printf("数组共有%d个数据\n",len);
}
  

int main()
{
    
    
	
	print_1(Number); 
	
	return 0;
}

insert image description here
Then we first need to know the function of the sizeof function:

sizeof is the storage space occupied by the obtained data in memory, counted in bytes.

Then some students will have problems at this time. The first address of the array is passed in twice. Why is it possible in the main function, but not in the custom function?

Thanks to the popularity and sales of Mr. Tan's C language books, many people think that the array name is a pointer to the first address of the array, but in fact this statement is wrong!

Let's use a simplest example, assuming that the array name is a pointer, then:

#include <stdio.h>

int Number[10]; 

int *Number2;
  
int main()
{
    
      
	int a=sizeof(Number);
	int b=sizeof(Number2);
	
	printf("a的大小为:%d \n b的大小为 %d\n",a,b); 
	
	return 0;
}

Number is a pointer, and Number2 is also a pointer. Normally, the size should be 8,
but the actual output is indeed a=40 b=8

That is to say, the array name is not equal to the pointer in some cases, but it will degenerate into a pointer in some cases

First of all, we need to know that a simple array name, not a pointer

The array name is an identifier that identifies a series of memory spaces we have previously applied for, and the element types in this space are the same - that is, the array name represents a memory block and the element type in this memory block.

It's just that in most cases the array name "degenerates" (the C standard uses the words decay and converted) to be a pointer to the first element. The pointer is not an aggregate data structure, it holds the address of a certain type of object (except void*), and it also points to this object. We can access this object through this address. Explain with a diagram, where a represents the entire memory block we declared, and p only points to an object of type char

char a[] = {
    
    'h' 'e' 'l' 'l' 'o'};
char b[] = {
    
    'w' 'o' 'r' 'l' 'd'};

char *p=b;

insert image description here
so, what happened?

Let's take a look at the C99 standard:

The third paragraph of C99 6.3.2.1 Lvalues, arrays, and function designators says this:

Except when it is the operand of the sizeof operator or the unary & operator, or is a
string literal used to initialize an array, an expression that has type ‘‘array of type’’ is
converted to an expression with type ‘‘pointer to type’’ that points to the initial element of
the array object and is not an lvalue. If the array object has register storage class, the
behavior is undefined.

The meaning of this passage is: The array name is only in the

  1. sizeof operator
  2. address & operator
  3. String constant-initialized array Str[]="abcdef"

No degeneration (array decay) occurs in these three cases

In other cases, calling the array name will degenerate into a pointer to the first address of the array


To go deeper, it is necessary to understand the sizeof of pointers

The pointer is used to record the address of another object, so the memory size of the pointer is equal to the width of the computer's internal address bus.

The size of an address is 4 if it is a 32-bit system, and 8 if it is a 64-bit system, so, in the function sizeof obtains the length of the pointer instead of the length of the array

The sizeof value of a pointer variable has nothing to do with the object pointed to by the pointer.


Conclusion:
That is to say, in the C language, the array name degenerates into a pointer in the function call. Use Sizeof for the parameters of the function. The result obtained by sizeof is the size of the pointer, not the size of the array itself.


Take another look at the processing time of Sizeof

sizeof is a unary operator in C language (but some people think it is a special macro), like other operators in C language ++, – and so on. It's not a function .
The sizeof operator gives the storage size of its operand in bytes. The operand can be an expression or a type name enclosed in parentheses. The storage size of the operand is determined by the type of the operand. Simply put, its function is to return the number of bytes of memory occupied by an object or type.

That is to say, Sizeof is a C language operator, then its processing stage is in the compilation stage, that is to say, before your program is not running, sizeof(arr) is replaced by a fixed constant, then for dynamically generated The size of an array cannot be calculated using sizeof.

Solution:

Add one more parameter to the function, indicating the length of the array,

#include <stdio.h>

int Number[10]; 

void print_1(int n[], int len)
{
    
    

	printf("数组大小为:%d\n",len);
	
	printf("数组共有%d个数据\n",len/sizeof(int));

}
  
int main()
{
    
    
	
	print_1(Number,sizeof(Number)); 
	
	return 0;
}

The above is the summary of the problem.

Please add image description
Please add image description

Guess you like

Origin blog.csdn.net/as480133937/article/details/123512497