Ⅰ、指针的运算
指针+-整数
例 求解字符串的长度 (法一):
指针-指针
地址-地址
1.前提:两个指针指向同一块空间 指针的类型是一致的
2.指针 - 指针得到的是指针和指针之间的元素个数 (小地址 - 大 结果为负)
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int n = &arr[9] - &arr[0];
printf("%d\n",n);
return 0;
}
例 求解字符串的长度(法二)
指针的关系运算
代码一:
#define N_VALUES 5
float values[N_VALUES];
float *vp;
for(vp = &values[N_VALUES]; vp > &values[0];)
{
*--vp = 0;
}
代码二:
#define N_VALUES 5
float values[N_VALUES];
float *vp;
for(vp = &values[N_VALUES-1]; vp >= &values[0];vp--)
{
*vp = 0;
}
实际在绝大部分的编译器上代码二是可以顺利完成任务的,然而我们还是应该避免代码二这样写,因为标准并不保证它可行。
标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与
指向第一个元素之前的那个内存位置的指针进行比较。
Ⅱ、指针和数组
指针就是指针,不是数组
数组就数组,也不是指针
指针的大小:4/8个字节,指针是存档地址的,地址的存放需要多大空间,指针变量的大小就是多少
数组的大小:取决于数组的元素个数和每个元素的类型
修改数组的内容例题:
int main()
{
int arr[10] = {0};
int* p = arr;//&arr[0] 数组名是首元素的地址
//存放
for(i = 0;i<10;i++)
{
*p = i+1;
p++; //或者 用 (*p+i) = i+1; 替换这两行代码
}
//打印
p = arr;
for(i = 0;i <10;i++)
{
printf("%d ",*(p+i));
}
return 0;
}
1.指针可以指向数组元素的
2.因为指针可以运算,所以借助于指针可以访问数组
Ⅲ、二级指针
指针变量也是变量,是变量就有地址,那指针变量的地址存放在哪里?
这就是
二级指针
int main()
{
int a = 10;//a是要在内存中申请4个字节的空间的
//一级指针
int* pa = &a; //0x0012ff40,pa是指针变量,用来存放地址,也得向内存申请,申请4/8
//二级指针
int** ppa = &pa;//0x0012ff48
printf("%d\n",**ppa);
return 0;
}
Ⅳ、指针数组
指针数组是存放指针的数组
指针数组和 二级指针的应用:
int main()
{
char* arr[5];//[char* char* char* char* char*]
char** p = arr;//&arr[0] char**
return 0;
}
一维数组模拟二维数组:
补充:
一维数组:
*(p+i) <==> arr[i] <==> *(arr+i) <==> *(i+arr) <==> i[arr]
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10}
int i = 0;
int*p = arr;
//*(p+i) <==> arr[i] <==> *(arr+i) <==> *(i+arr) <==> i[arr] 符合交换律
for(i=0;i<10;i++)
{
printf("%p = %p\n",&arr[i],p+i);
}
return 0;
}
二维数组:
arr[i][j] 等价于 (*(arr+i))[j] 等价于 *(*(arr+i)+j)
int main()
{
int arr[3][5];
//arr[i][j]
//(*(arr+i))[j]
//*(*(arr+i)+j)
return 0;
}