Summary of Pointers and Arrays Exercises

Looking at my head dizzy here, I can take a break.

Table of contents

1. Array

1.1 One-dimensional array:

1.2 Character arrays

1.3 Strings

1.4 Two-dimensional array

2. pointer


Before we start, let's briefly review the relevant knowledge of arrays and pointers

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 size 4/8 bytes (32 bits, 64 bits)
The array is an array, and the pointer is 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 traverse the array.

for the array name

In most cases, the array name is the address of the first element of the array
, but there are two exceptions
1. sizeof(array name) - the array name represents the entire array, and the calculation is the size of the entire array
2. & array name - the array name represents the entire array, take it out is the address of the entire array

1. Array

1.1 One-dimensional array:

#include <stdio.h>
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
	printf("%d\n", sizeof(*a)); //*a 第一个元素 
	//*a == *&a[0]  == a[0]  整形元素 4
	printf("%d\n", sizeof(a + 1));//第二个元素地址 指针变量 4/8
	printf("%d\n", sizeof(a[1]));//第二个整形数组元素  4
	printf("%d\n", sizeof(&a));//整个数组的地址 也是 指针变量 4/8
	//int (*pa)[4] = &a;
	printf("%d\n", sizeof(*&a));//  整个数组大小 *&抵消 相等于sizeof(a) 16
	printf("%d\n", sizeof(&a + 1));//数组指针+1 还是地址指针变量 4/8
	printf("%d\n", sizeof(&a[0]));//第一个元素地址 指针变量 4/8
	printf("%d\n", sizeof(&a[0] + 1));//第二个元素地址 指针变量 4/8  
	return 0;
}

1.2 Character arrays

sizeof() operator and strlen() function

1. sizeof calculates the size of the occupied memory space, the unit is byte, do not pay attention to 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. It is the length of the string
5. The strlen() function is to pass in an address, and the backward count is the number of characters that appear before '\0'

Look at the question:

#include<stdio.h>
#include<string.h>

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };

	printf("%d\n", sizeof(arr));//没有'\0' 6
	printf("%d\n", sizeof(arr + 0));//地址 4/8
	printf("%d\n", sizeof(*arr));//第一个字符大小 1
	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

	printf("%d\n", strlen(arr));  //随机值  因为不知道'\0'在哪里
 	printf("%d\n", strlen(arr + 0)); // 随机值
	//printf("%d\n", strlen(*arr));//*arr 'a' ASCII码值97 会造成非法访问,报错
	//printf("%d\n", strlen(arr[1]));//'b' ASCII码值98 会造成非法访问,报错
	printf("%d\n", strlen(&arr));//随机值
	printf("%d\n", strlen(&arr + 1));//上面随机值 - 6
	printf("%d\n", strlen(&arr[0] + 1));//上面随机值 - 1

	return 0;
}

1.3 Strings

3.1 Put the string in the character array 

#include<stdio.h>
#include<string.h>

int main()
{
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//有'\0' 7
	printf("%d\n", sizeof(arr + 0));//地址 4/8
	printf("%d\n", sizeof(*arr));//第一个字符大小 1
	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

	printf("%d\n", strlen(arr));  //6
	printf("%d\n", strlen(arr + 0)); //6
	//printf("%d\n", strlen(*arr));//*arr 'a' ASCII码值97 会造成非法访问,报错
	//printf("%d\n", strlen(arr[1]));//'b' ASCII码值98 会造成非法访问,报错
	printf("%d\n", strlen(&arr));//6
	//&arr 类型是 char (*)[7] 在strlen函数内部会强制类型转换为const char* ,编译器会有警告
	printf("%d\n", strlen(&arr + 1));//地址跳到'\0'之后 随机值
	printf("%d\n", strlen(&arr[0] + 1));//5

	return 0;
}

3.2 Put the address of the first character of the constant string into the pointer variable

Note: The content of the constant string cannot be modified

#include<stdio.h>
#include<string.h>

int main()
{
	char* p = "abcdef";//将常量字符串的首字符地址放到p中 

	printf("%d\n", sizeof(p)); //a的地址 指针  4/8
	printf("%d\n", sizeof(p + 1));//b的地址 指针 4/9
	printf("%d\n", sizeof(*p));//'a'  字符型 1
	printf("%d\n", sizeof(p[0]));//*(p+0) 'a'  字符型 1
	printf("%d\n", sizeof(&p));//二级指针  4/8
	printf("%d\n", sizeof(&p + 1));//跳过一个char** 还是指针变量 4/8
	printf("%d\n", sizeof(&p[0] + 1));//'b'  指针变量 4/8

	printf("%d\n", strlen(p));//从a地址开始 6
	printf("%d\n", strlen(p + 1));//从b地址开始 5
	//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));//从'b'地址开始 5

	return 0;
}

1.4 Two-dimensional array

Note: The name of the two-dimensional array array is the address of the first row element

#include<stdio.h>

int main()
{
	int a[3][4] = { 0 };

	printf("%d\n", sizeof(a));//整个数组大小 48
	printf("%d\n", sizeof(a[0][0]));//第一行第一个元素 4
	printf("%d\n", sizeof(a[0]));//第一行一维数组名 16
	//第一行的数组名单独放在sizeof内部
	printf("%d\n", sizeof(a[0]+1));//  4/8
	//数组名不是单独放在sizeof内部   a[0]是第一行第一个元素的地址
	//a[0] + 1 是第一行第二个元素地址 == &a[0][1]

	printf("%d\n", sizeof(*(a[0]+1)));//a[0][1] 4
	printf("%d\n", sizeof(a+1));//第二行地址 4/8
	//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
	printf("%d\n", sizeof(*(&a[0]+1)));//第二行元素大小 16
	printf("%d\n", sizeof(*a));//第一行元素大小 16
	//*a==*(a+0) ==a[0]
	printf("%d\n", sizeof(a[3]));// 一行元素大小 16
	//没有越界访问 sizeof()内的内容并不会真正的计算,通过类型得出的
	return 0;
}

sizeof() does not calculate internally

#include<stdio.h>

int main()
{
	int a = 5;
	short s = 11;
	printf("%d\n", sizeof(s = a + 2));//2  sizeof是通过类型推出的, 不用运算
	printf("%d\n", s);//s没有变换
	return 0;
}

test.c -- compile -- link -- test.exe   
completes the calculation of sizeof in the compiling phase.
s = a + 2 has two attributes, value attribute 7 and type attribute short.
s = a + 2 uses the type attribute short to compile The phase has been determined not to be calculated during runtime
, so: the internal expression of sizeof will not be calculated

2. pointer

Exercise 1: 

struct Test
{
	int num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表达式的结果分别是多少
//已知,结构体Test类型的变量大小是20个字节

#include<stdio.h>
int main()
{
	p = (struct Test*)0x100000;
	printf("%p\n", p + 0x1);
	//+1 跳过20个字节  0x00100014  
	printf("%p\n", (unsigned long)p + 0x1);
	//强制类型转换 整形+1  0x00100001
	printf("%p\n", (unsigned int*)p + 0x1);
	//整形指针+1  +4    0x00100004

	return 0;
}

Exercise 2:

#include<stdio.h>

int main()
{
	int a[4] = { 1,2,3,4 };
	int* ptr1 = (int*)(&a + 1);
	int* ptr2 = (int*)((int)a + 1);
	printf("%x,%x", ptr1[-1], *ptr2);
	//*(ptr1+-1)  4    
	//1  00 00 00 01 小端存储 内存中为 01 00 00 00
	//2  00 00 00 02 小端存储 内存中为 02 00 00 00
	//ptr2  00 00 00 02  读取  02 00 00 00 
	//0x2000000
	return 0;
}

%p prints the hexadecimal address x86 8-bit
%x only prints the high bit of the hexadecimal system is 0 and does not print

Draw a picture to understand

 

Exercise 3:

#include<stdio.h>

int main()
{
	int a[3][2] = { (0,1),(2,3),(4,5) };//逗号表达式,只初始化了前三个元素
	//     数组元素为  1,3, 5,0, 0,0
	int* p;
	p = a[0];//第一行数组首元素地址,没有sizeof和&所以 p是第一行一个元素地址
	//p == a[0] == &a[0][0]
	printf("%d", p[0]); 
	//*(p+0)== *p ==  1 
	return 0;
}

Exercise 4:

#include<stdio.h>

int main()
{
	int a[5][5];
	int(*p)[4];//数组指针
	p = a;
	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	//					0x10000004	   	,			-4
	//%p 16进制打印内存中的补码 -4
	//10000000 00000000 00000000 0000 0100  原码
	//11111111 11111111 11111111 1111 1011  反码
	//11111111 11111111 11111111 1111 1100  补码
	//    ff      ff       ff      f    c   16进制补码
	//ff ff ff fc

	return 0;
}

Exercise 5:

#include<stdio.h>

int main()
{
	int aa[2][5] = { 1,2,3,4,5,6,7,8,9,10 };
	int* ptr1 = (int*)(&aa + 1);//aa[10]
	int* ptr2 = (int*)(*(aa + 1));//二维数组首元素地址是第一行 6
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//10,5
	return 0;
}

Exercise 6:

#include<stdio.h>

int main()
{
	char* a[] = { "work","at","alibaba" };
	//				w的地址	  a的地址    a的地址
	char** pa = a;

	pa++;

	printf("%s\n", *pa);//at

	return 0;
}

Exercise 7:

#include <stdio.h>
int main()
{
	char* c[] = { "ENTER","NEW","POINT","FIRST" };
	char** cp[] = { c + 3,c + 2,c + 1,c };
	char*** cpp = cp;

	printf("%s\n", **++cpp);//POINT
	printf("%s\n", *-- * ++cpp + 3);//ER
	printf("%s\n", *cpp[-2] + 3);//ST
	printf("%s\n", cpp[-1][-1] + 1);//EW

	return 0;
}

Draw a picture to understand

 end of article

 

Guess you like

Origin blog.csdn.net/qq_72916130/article/details/131101611