成都网站建设设计

将想法与焦点和您一起共享

指针(C语言)-创新互联

文章目录
  • 1 指针是什么
  • 2 指针和指针类型
    • 2.1 指针+-整数
    • 2.2 指针的解引用
  • 3 野指针
    • 3.1 指针未初始化
    • 3.2 指针越界访问
    • 3.3 指针指向的空间释放
    • 3.4 避免野指针
  • 4 指针运算
    • 4.1 指针±整型
  • 4.2 指针减指针
  • 5 指针和数组
  • 6 二级指针
  • 7 指针数组

创新互联于2013年开始,先为林口等服务建站,林口等地企业,进行企业商务咨询服务。为林口企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。

在这里插入图片描述

1 指针是什么
  • 指针是内存中一个最小单元(1字节byte)编号,也就是地址
  • 平时口语中说的指针,通常指的是指针变量,是用来存放内存地址的变量
  • 我们可以通过&(取地址操作符)取出变量的内存 (起始地址),把地址可以存放到一个变量中,这个变量就是指针变量
int a = 10;
int * pa = &a;
*pa = 20;
printf("%d\n", a);

20

在这里插入图片描述

  • 存放在指针中的值都被当成地址处理
  • 对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平(高电压)和低电平(低电压)就是(1或者0),有2的32次方个地址. 在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所以一个指针变量的大小就应该是4个字节.那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。
    在这里插入图片描述
2 指针和指针类型

指针的定义方式是:type + *

int* pa;
	char* pc;
	float* pf;

	printf("%d\n", sizeof(pa));
	printf("%d\n", sizeof(pc));
	printf("%d\n", sizeof(pf));

4
4
4

在x86下,指针变量的大小都是4.

2.1 指针±整数
int main()
{int a = 0x11223344;
	//int*pa = &a;
	//*pa = 0;
	char* pc = &a;
	*pc = 0;

	return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
因为用char*,解引用的时候只能访问1个字节,只能修改44.

2.2 指针的解引用
int main()
{int a = 0x11223344;
	int*  pa = &a;
	char* pc = &a;

	printf("pa=%p\n", pa);
	printf("pc=%p\n", pc);

	printf("pa+1=%p\n", pa -1);
	printf("pc+1=%p\n", pc -1);

	return 0;
}

pa=00AFF7EC
pc=00AFF7EC
pa+1=00AFF7E8 //减4
pc+1=00AFF7EB //减1

在这里插入图片描述

  • 数组名作指针
int arr[10] = {0 };
	int* p = arr;//数组名就是数组首元素的地址arr->&arr[0];

	for (int i = 0; i< 10; i++)
	{*(p + i) = i + 1;
	}

在这里插入图片描述

int arr[10] = {0 };
	char* p = arr;
	
	int i = 0;
	for (i = 0; i< 10; i++)
	{*p = i + 1;
		p++;
	}

在这里插入图片描述
可以看见用char类型解引用整型数组是不对的.01 02 03 04对应arr[0] = 67305985.

3 野指针

野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

3.1 指针未初始化
int* p;
	*p = 20;

在这里插入图片描述

3.2 指针越界访问
int main()
{int arr[10] = {0};
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int* p = arr;
	for (i = 0; i<= sz; i++)
	{*p = i;
		p++;
	}

	return 0;
}

Run-Time Check Failure #2 - Stack around the variable 'arr' was corrupted.

3.3 指针指向的空间释放
int* test()
{int num = 100;
	printf("%p\n", &num);
	return #
}

int main()
{int* p = test();
	*p = 200;
	printf("%d\n", *p);
	printf("%p\n", p);

	return 0;
}


010FF754
200
010FF754
3.4 避免野指针
int main()
{int a = 10;
	int* pa = &a;
	int* p = NULL;

	return 0;
}
  • 判断为NULL
int a = 10;
	//int* p = NULL;
	//*p = 20;

	int* p = &a;

	if (p != NULL)
	{printf("%d\n", *p);
	}
	
10
4 指针运算 4.1 指针±整型
double arr[5] = {0};
	double* p = arr;
	int i = 0;
	for (i = 0; i< 5; i++)
	{printf("%lf ", *(p + i));
	}
0.000000 0.000000 0.000000 0.000000 0.000000
  • 注意浮点%f
#define N_VALUES 5
float values[N_VALUES];
float* vp;

int main()
{for (vp = &values[N_VALUES - 1]; vp >= &values[0]; vp--)
	{*vp = 1;
	}
	for (int i = 0; i< N_VALUES; i++)
	{printf("%f\n", values[i]);
	}
	return 0;
}

1.000000
1.000000
1.000000
1.000000
1.000000

实际在绝大部分的编译器上是可以顺利完成任务的,然而我们还是应该避免这样写,因为标准并不保证它可行。

4.2 指针减指针

两个指针相减的前提是:指针指向的同一块连续的空间

int arr[10] = {0};
	printf("%d\n", &arr[9] - &arr[0]);
	printf("%d\n", &arr[0] - &arr[9]);

	int a = 10;
	char c = 'w';
	printf("%d\n", &a - &c);//err
9
-9
2
5 指针和数组
  • 指针为NULL判断结束
int my_strlen1(char* str)
{int count = 0;
	while (*str)
	{count++;
		str++;
	}
	return count;
}


int my_strlen2(char* str)
{char* start = str;
	while (*str)
		str++;
	return str - start;
}
//
int main()
{char arr[] = "abc";
	int len1 = my_strlen1(arr);
	int len2 = my_strlen2(arr);
	printf("%d\n", len1);
	printf("%d\n", len2);

	return 0;
}

3
3
  • 指针访问数组元素
    在这里插入图片描述
int arr[10] = {1,2,3,4,5,6,7,8,9,10 };
	int* p = arr;
	int i = 0;
	int sz = sizeof(arr) / sizeof(arr[0]);

	for (i = 0; i< sz; i++)
	{printf("%d\n", *(p + i));
	}

1
2
3
4
5
6
7
8
9
10
6 二级指针
  • p就是指针变量,一级指针变量
  • pp二级指针
int main()
{int a = 10;//
	int* p = &a;//
	int** pp = &p;//

	//*(*pp) = 200;
	**pp = 200;
	//*p = 20;
	printf("%d\n", a);

	return 0;
}

200

在这里插入图片描述

7 指针数组

指针数组是指针还是数组?答案:是数组。是存放指针的数组。

int arr[10];
	char arr2[5];
	int* arr3[5];//存放整型指针的数组
	char* arr4[6];//存放字符指针的数组
  • 1
int a = 10;
	int b = 20;
	int c = 30;
	int d = 40;
	int e = 50;

	int* arr3[5] = {&a, &b, &c, &d, &e};//存放整型指针的数组
	int i = 0;
	for (i = 0; i< 5; i++)
	{printf("%d ", *(arr3[i]));
	}
10 20 30 40 50
  • 用一维数组模拟一个二维数组
    在这里插入图片描述
int arr1[] = {1,2,3,4,5 };
	int arr2[] = {2,3,4,5,6 };
	int arr3[] = {3,4,5,6,7 };
	int arr4[] = {4,5,6,7,8 };

	int* arr[4] = {arr1, arr2, arr3, arr4};
	int i = 0;
	for (i = 0; i< 4; i++)
	{int j = 0;
		for (j = 0; j< 5; j++)
		{	printf("%d ", *(*(arr+i)+j));
		}
		printf("\n");
	}

1 2 3 4 5
2 3 4 5 6
3 4 5 6 7
4 5 6 7 8

上面的打印可以写为

int i = 0;
	for (i = 0; i< 4; i++)
	{int j = 0;
		for (j = 0; j< 5; j++)
		{	printf("%d ", arr[i][j]);
		}
		printf("\n");
	}```

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


网页名称:指针(C语言)-创新互联
URL地址:http://chengdu.cdxwcx.cn/article/hghdc.html