Analysis of Pointer and Array Pen Test Questions
1. One-dimensional array
1.1 Review knowledge points
- 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.- 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:
2. Character array
2.1 Review knowledge points
- sizeof calculates the size of the occupied memory space, and the unit is bytes, regardless of what is stored in the memory.
- sizeof is not a function, but an operator.
- strlen is a function.
- 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:
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:
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.
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:
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:
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:
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:
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. .
4. Summary
The meaning of the array name:
- sizeof(array name), where the array name represents the entire array, and the calculation is the size of the entire array.
- &Array name, where the array name represents the entire array, and the address of the entire array is taken out.
- In addition, all array names represent the address of the first element.
- 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.