【Advanced C Language】Analysis of Pointer and Array Written Test Questions

insert image description here

1. One-dimensional array

1.1 Review knowledge points

  1. Array and pointer
    Array - can store a group of elements of the same type, the size of the array depends on the number of elements and the element type of the array
    Pointer - address/pointer variable, the size is 4/8 bytes
    The array is an array, and the pointer is a pointer, The two are not equivalent.
    The array name is the address of the first element of the array. This address can be stored in the pointer variable, and we can use the pointer to traverse the array.
  2. Array name
    In most cases, the array name is the address of the first element of the array,
    but there are 2 exceptions:
    sizeof(array name) - the array name represents the entire array, and the calculation is the size of the entire array
    &Array name - the array name represents the entire array, take it out is the address of the array

1.2 Think about what the outcome is?

int main()
{
    
    
	int a[] = {
    
     1,2,3,4 };
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof(a + 0));
	printf("%d\n", sizeof(*a));
	printf("%d\n", sizeof(a + 1));
	printf("%d\n", sizeof(a[1]));
	printf("%d\n", sizeof(&a));
	printf("%d\n", sizeof(*&a));
	printf("%d\n", sizeof(&a + 1));
	printf("%d\n", sizeof(&a[0]));
	printf("%d\n", sizeof(&a[0] + 1));
	return 0;
}

Detailed explanation:

int main()
{
    
    
	int a[] = {
    
     1,2,3,4 };
	printf("%d\n", sizeof(a));//16
	//sizeof(a)就是数组名单独放在sizeof内部,计算的数组总大小,单位是字节
	printf("%d\n", sizeof(a + 0));//4/8 个字节
	//a+0 其实是数组首元素的地址
	printf("%d\n", sizeof(*a));//4  它是一个元素的大小并不是一个地址的大小,所以不可能是4/8个字节
	//a是数组首元素的地址 - &a[0]
	//*a -> *&a[0] -> a[0]
	printf("%d\n", sizeof(a + 1));//4/8
	//a是数组首元素的地址 -- int*
	//a+1 跳过1个整型, 是第二个元素的地址
	//
	printf("%d\n", sizeof(a[1]));//4
	printf("%d\n", sizeof(&a));//4/8
	//&a - 取出的是数组的地址,但是数组的地址也是地址呀,是地址大小就是4/8字节
	//int (*pa)[4] = &a;//int(*)[4]
	//
	printf("%d\n", sizeof(*&a));//16
	//sizeof(a)
	//int(*)[4]数组指针
	//
	printf("%d\n", sizeof(&a + 1));//4/8
	//&a -->  int (*)[4]
	//&a+1 跳过一个数组

	printf("%d\n", sizeof(&a[0]));//取出首元素的地址 4/8
	printf("%d\n", sizeof(&a[0] + 1));//第二个元素的地址

	return 0;
}

Picture explanation:
insert image description here

2. Character array

2.1 Review knowledge points

  1. sizeof calculates the size of the occupied memory space, and the unit is bytes, regardless of what is stored in the memory.
  2. sizeof is not a function, but an operator.
  3. strlen is a function.
  4. strlen is for strings, and it seeks the length of the string. Essentially, it counts the number of characters that appear before \0.

2.2 Think about what the outcome is?

int main()
{
    
    
	char arr[] = {
    
     'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr + 0));
	printf("%d\n", sizeof(*arr));
	printf("%d\n", sizeof(arr[1]));
	printf("%d\n", sizeof(&arr));
	printf("%d\n", sizeof(&arr + 1));
	printf("%d\n", sizeof(&arr[0] + 1));
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr + 0));
	printf("%d\n", strlen(*arr));
	printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr + 1));
	printf("%d\n", strlen(&arr[0] + 1));
	return 0;
}

Detailed explanation:

int main()
{
    
    
	char arr[] = {
    
     'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//6
	printf("%d\n", sizeof(arr + 0));//arr+0是数组首元素的地址 4/8
	printf("%d\n", sizeof(*arr));//*arr是首元素的,计算的是首元素的大小 1
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//&arr是数组的地址 4/8
	printf("%d\n", sizeof(&arr + 1));//&arr + 1跳过一个数组后的地址,4/8
	printf("%d\n", sizeof(&arr[0] + 1));//4/8 第二个元素的地址
	return 0;
}

Picture explanation:
insert image description here
Detailed explanation:

int main()
{
    
    
	char arr[] = {
    
     'a','b','c','d','e','f' };
	
	printf("%d\n", strlen(arr));//随机值,因为不知道\0的位置
	printf("%d\n", strlen(arr + 0));//随机值
	printf("%d\n", strlen(*arr));//非法访问  我需要的是一个地址,你却给了我一个元素,强行访问。
	printf("%d\n", strlen(arr[1]));//'b' - 98 当成地址,形参非法访问
	printf("%d\n", strlen(&arr));//随机值
	printf("%d\n", strlen(&arr + 1));//随机值-6
	printf("%d\n", strlen(&arr[0] + 1));//随机值-1
}

Picture explanation:
insert image description here
The reasons for the formation of illegal access:

What I need is an address, but you gave me an element, forced access, and regarded the ASCII value of a as an address.

insert image description here

2.3 Thinking about another group

int main()
{
    
    
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));
	printf("%d\n", sizeof(arr + 0));
	printf("%d\n", sizeof(*arr));
	printf("%d\n", sizeof(arr[1]));
	printf("%d\n", sizeof(&arr));
	printf("%d\n", sizeof(&arr + 1));
	printf("%d\n", sizeof(&arr[0] + 1));
	printf("%d\n", strlen(arr));
	printf("%d\n", strlen(arr + 0));
	printf("%d\n", strlen(*arr));
	printf("%d\n", strlen(arr[1]));
	printf("%d\n", strlen(&arr));
	printf("%d\n", strlen(&arr + 1));
	printf("%d\n", strlen(&arr[0] + 1));
	return 0;
}

Detailed explanation:
sizeof part:

int main()
{
    
    
	char arr[] = "abcdef";//[a b c d e f \0]

	printf("%d\n", sizeof(arr));//7
	printf("%d\n", sizeof(arr + 0));//4/8
	printf("%d\n", sizeof(*arr));//*arr -是数组首元素 1
	//arr[0]  =  *(arr+0) = *(&arr[0])
	//int sz = sizeof(arr)/sizeof(*arr);
	//int sz = sizeof(arr)/sizeof(arr[0]);两种表达形式一样

	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//数组的地址,是地址就是4 / 8
	printf("%d\n", sizeof(&arr + 1));//4 / 8
	printf("%d\n", sizeof(&arr[0] + 1));//4 / 8

	return 0;
}

The strlen part:

int main()
{
    
    
	char arr[] = "abcdef";//[a b c d e f \0]

	printf("%d\n", strlen(arr));//6
	printf("%d\n", strlen(arr + 0));//6
	printf("%d\n", strlen(*arr));//err
	printf("%d\n", strlen(arr[1]));//err
	printf("%d\n", strlen(&arr));//6
	//&arr - char(*)[7]  数组指针
	printf("%d\n", strlen(&arr + 1));//随机值
	printf("%d\n", strlen(&arr[0] + 1));//5

	return 0;
}

Picture explanation:
insert image description here

2.4 Another set of comparison exercises

int main()
{
    
    
	char* p = "abcdef";  //p里面放的是a的地址
	printf("%d\n", sizeof(p));
	printf("%d\n", sizeof(p + 1));
	printf("%d\n", sizeof(*p));
	printf("%d\n", sizeof(p[0]));
	printf("%d\n", sizeof(&p));
	printf("%d\n", sizeof(&p + 1));
	printf("%d\n", sizeof(&p[0] + 1));
	printf("%d\n", strlen(p));
	printf("%d\n", strlen(p + 1));
	printf("%d\n", strlen(*p));
	printf("%d\n", strlen(p[0]));
	printf("%d\n", strlen(&p));
	printf("%d\n", strlen(&p + 1));
	printf("%d\n", strlen(&p[0] + 1));
	return 0;
}

Detailed explanation:
sizeof part:

int main()
{
    
    
    char* p = "abcdef";
	printf("%d\n", sizeof(p));//4 / 8  p里面放的是a的地址
	printf("%d\n", sizeof(p + 1));//'b'的地址,4/8
	printf("%d\n", sizeof(*p));//1
	printf("%d\n", sizeof(p[0]));//*(p+0)--'a' 1
	printf("%d\n", sizeof(&p));//4 /8
	printf("%d\n", sizeof(&p + 1));//4/8
	printf("%d\n", sizeof(&p[0] + 1));//&p[0]+1是'b'的地址 4/8

	return 0;
}

Picture explanation:
insert image description here
insert image description here
insert image description here

The strlen part:

int main()
{
    
    
	char* p = "abcdef";
	printf("%d\n", strlen(p));//6
	printf("%d\n", strlen(p + 1));//p+1是'b'的地址 5
	printf("%d\n", strlen(*p));//err  //把a的ASCII值当成了地址
	printf("%d\n", strlen(p[0]));//err
	printf("%d\n", strlen(&p));//随机值
	printf("%d\n", strlen(&p + 1));//随机值
	printf("%d\n", strlen(&p[0] + 1));//5
	return 0;
}

Picture explanation:
insert image description here

3. Two-dimensional array

3.1 Think about what the outcome is?

int main()
{
    
    
	int a[3][4] = {
    
     0 };
	printf("%d\n", sizeof(a));
	printf("%d\n", sizeof(a[0][0]));
	printf("%d\n", sizeof(a[0]));
	printf("%d\n", sizeof(a[0] + 1));
	printf("%d\n", sizeof(*(a[0] + 1)));
	printf("%d\n", sizeof(a + 1));
	printf("%d\n", sizeof(*(a + 1)));
	printf("%d\n", sizeof(&a[0] + 1));
	printf("%d\n", sizeof(*(&a[0] + 1)));
	printf("%d\n", sizeof(*a));
	printf("%d\n", sizeof(a[3]));
	return 0;
}

Detailed explanation:

int main()
{
    
    
	int a[3][4] = {
    
     1,2,3,4,5,6,7,8,9,10,11,12 };

	printf("%d\n", sizeof(a));//48 - a这个二维数组的数组名单独放在sizeof内部,计算整个数组的大小
	printf("%d\n", sizeof(a[0][0]));//第一行第一个元素,4个字节
	printf("%d\n", sizeof(a[0]));//16
	//a[0] 第一行的数组名,这时数组名单独放在sizeof内部了
	//计算的是第一行数组的大小,单位是字节,16
	printf("%d\n", sizeof(a[0] + 1));//4
	//a[0]不是单独放在sizeof内部,a[0]表示的首元素的地址,即第一行第一个元素的地址 - &a[0][0]
	//a[0] + 1 是第一行第2个元素的地址 &a[0][1]
	printf("%d\n", sizeof(*(a[0] + 1)));//a[0][1] 大小是:4个字节
	printf("%d\n", sizeof(a + 1));//
	//a作为二维数组的数组名并非单独放在sizeof内部,所以表示首元素的地址
	//二维数组的首元素是第一行,这里的a就是第一行的地址---  int (*)[4]数组指针
	//a+1是跳过第一行,指向了第二行

	printf("%d\n", sizeof(*(a + 1)));//16
	//*(a+1)-->a[1]
	printf("%d\n", sizeof(&a[0] + 1));//4/8
	//&a[0]是第一行的地址
	//&a[0]+1是第二行的地址
	printf("%d\n", sizeof(*(&a[0] + 1)));//16  a[1]
	printf("%d\n", sizeof(*a));//16 *a - 就是第一行
	//*a -- *(a+0) -- a[0]
	printf("%d\n", sizeof(*arr+1);//4 /8
	//*arr--arr[0],arr[0]+1 = &arr[0][0]+1-->&arr[0][1]
	printf("%d\n", sizeof(a[3]));//16  并不会越界
	//不会越界的原因:
	int a = 5;
	short s = 11;
	printf("%d\n", sizeof(s = a + 2));//发生截断,2
	printf("%d\n", s);//按理说结果为7但真正结果为11,因为sizeof内部不会真正计算

	return 0;
}

Picture explanation:
insert image description here
insert image description here

3.2 Reasons for not crossing the boundary

Reasons not to cross the line:

int a = 5;
	short s = 11;
	printf("%d\n", sizeof(s = a + 2));//发生截断,2
	printf("%d\n", s);//按理说结果为7但真正结果为11,因为sizeof内部不会真正计算

sizeof is disposed of during the compilation process, and will not be used in the subsequent process. It is divided into value attributes and type attributes. The value attribute is 7, the type attribute is 2, and the type attribute is calculated first, so no out-of-bounds access will occur. .

insert image description here

4. Summary

The meaning of the array name:

  1. sizeof(array name), where the array name represents the entire array, and the calculation is the size of the entire array.
  2. &Array name, where the array name represents the entire array, and the address of the entire array is taken out.
  3. In addition, all array names represent the address of the first element.
  4. The first element of a two-dimensional array is the first row.

If this blog is helpful to everyone, I hope you give Hengchuan a free like as encouragement, and comment and bookmark it, thank you! ! !
It is not easy to make, if you have any questions or give Heng Chuan's opinion, welcome to leave a message in the comment area.

Supongo que te gusta

Origin blog.csdn.net/m0_75058342/article/details/129776568
Recomendado
Clasificación