结合示例 总结一下 指针的各个概念及指针变量在函数中的传递与应用
如
int a = 3;
int* point =&a;
设内存分布如下
address | 变量名 | 值 |
0x300000 | a | 3 |
.. | ||
.. | ||
0x500000 | point | 0x300000 |
指针变量(用于存储其他变量的空间地址)point (0x300000),指针变量的存储地址(指针变量自身的地址)&point (0x500000),指针的指向存储空间的值 *point ( 3)
示例:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
typedef int* Triplet;
void swap(int* a, int* b);
int InitArray(int* arr, int a, int b, int c);
int InitTriplet(Triplet* T, int a, int b, int c);
int TestPointAssign(Triplet T, int a, int b, int c);
int main()
{
int m = 2, n = 4;
int Array[] = {1, 2, 3};
Triplet T_num = NULL;
swap(&m, &n);
printf("m = %d, n = %d\n", m, n);
//为已分配空间(指针指向/数组)赋值
InitArray(Array, 11, 12, 13);
printf("A[0] = %d, A[1] = %d, A[2] = %d\n", Array[0], Array[1], Array[2]);
//指针变量T_num的值(指向的地址)与自身地址
printf("before test:T_num:%d, &T_num:%d\n", T_num, &T_num);
TestPointAssign(T_num, 111, 112, 113);
//指针变量T_num的值(指向的地址)与自身地址
printf("after test:T_num:%d, &T_num:%d\n", T_num, &T_num);
//指针指针指向新地址之前的地址 (此处 NULL--0000)
//printf("address before resign:%d\n",T_num);
//使指针指向新地址,在新地址处为其分配所指定大小的存储空间
InitTriplet(&T_num, 1, 2, 3);
//T_num存储指针指向新地址之后的地址 (即连续3个存储空间的首地址)
printf("after resign:T_num:%d, *T_num:%d, &T_num:%d\n", T_num, *T_num, &T_num);
printf("Init point:T_num[0] = %d, T_num[1] = %d, T_num[2] = %d\n", T_num[0], T_num[1], T_num[2]);
return 0;
}
void swap(int* a, int* b)
{
int c = *a;
*a = *b;
*b = c;
}
int InitArray(int* arr, int a, int b, int c)
{
arr[0] = a;
arr[1] = b;
arr[2] = c;
return 0;
}
int InitTriplet(Triplet* T, int a, int b, int c)
{
*T = (int*)malloc(sizeof(int) * 3);
if ( !(*T) )
{
printf("overflow");
exit(0);
}
(*T)[0] = a;
(*T)[1] = b;
(*T)[2] = c;
return 0;
}
int TestPointAssign(Triplet T, int a, int b, int c)
{
T = (int*)malloc(sizeof(int) * 3);
if ( !T )
{
printf("overflow");
exit(0);
}
T[0] = a;
T[1] = b;
T[2] = c;
printf("In function 0~2: %d, %d, %d\n", T[0], T[1], T[2]);
printf("In function test address:%d\n",T);
return 0;
}
运行结果:
int* p_num = NULL; //定义指针变量 p_num, 并初始化 使其 指向NULL(0000地址)
即p_numm 为其指向的地址(0x000000)
*p_num 为 指向地址所储存值。 (0x000000 存储数据不可访问)
&p_num 为 指针变量p_num 自身所在的存储空间。 (假设此处为 0x300000 )
p_num = (int*) malloc(sizeof(int) * 3);
p_num 指向一个新的地址存储空间 (假设为 0x500000)
*p_num 为 指向地址所储存值。 (0x500000 中存储的数据)
&p_num 为 指针变量p_num 自身所在的存储空间。 (为 0x300000 与上述一致,保持不变。即指针变量p_num自身的存储空间没变,只是其所指向的存储空间变了。 由原来指向的0x000000空间,变为由3个int构成的连续空间的首地址(低位地址)0x500000
对比
int InitTriplet(Triplet
* T,
int a,
int b,
int c);
int TestPointAssign(Triplet T, int a, int b, int c);
int TestPointAssign(Triplet T, int a, int b, int c);
前者传递的是指针变量T的指针(地址),后者传递的是指针变量
如同swap()函数的作用,如要在函数内 改变传递变量的值--将其带回,需要传递变量的地址,在所在地址处修改变量的值;而非传递一变量。后者 将 实参 T_num 的值传递函数,函数内部 T_num 将值赋值给另一存储空间(变量)T,修改的是变量T--test adress假设为 0x533245,而非变量T_num--须将T_num的地址传递到函数内部。
int InitArray(
int
* arr,
int a,
int b,
int c);
int array[3] = {0};
int* point_t = NULL;
InitArray(array, 1, 2, 3);//ok -- arr为一数组名,有固定的存储空间。在空间地址内赋值即可
InitArray(point_t, 1, 2, 3);//error -- point_t为一指针,需为其所指向地址分配空间,才可赋值
指针与引用
C++中 可以用 引用 来实现下函数
int InitTriplet(Triplet* T, int a, int b, int c) //指针传递
{
*T = (int*)malloc(sizeof(int) * 3);
if ( !(*T) )
{
printf("overflow");
exit(0);
}
(*T)[0] = a;
(*T)[1] = b;
(*T)[2] = c;
return 0;
}
调用 InitTriplet(&T, 1, 2, 3);
int InitTriplet(Triplet& T, int a, int b, int c) //使用
{
T = (int*)malloc(sizeof(int) * 3);
if ( !T )
{
printf("overflow");
exit(0);
}
T[0] = a;
T[1] = b;
T[2] = c;
return 0;
}
调用 InitTriplet(T, 1, 2,3);