文章目录
- 前言
- 一、指针 +- 整数
- 二、指针 - 指针
- 三、指针的关系运算
- 四、指针和数组
- 五、二级指针
- 六、指针数组
- 指针数组可以将几个一维数组模拟成二维数组
- 总结
前言
C语言指针±整数、指针-指针、指针关系运算、指针和数组、二级指针、指针数组等介绍,还包括指针数组将几个一维数组模拟为二维数组等的介绍。
一、指针 ± 整数
// 指针加1遍历数组
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int* p = arr;
for (i = 0; i < sz; i++)
{
*p = 1;
p++; // p+1 跳过4个字节,直接操作第二个元素
}
for (i = 0; i < sz; i++)
{
printf("%d", arr[i]);
}
return 0;
}
二、指针 - 指针
- 指针 - 指针, 就是两个指针之间元素的个数。
- 指针 - 指针的前提条件是 指向同一个空间的2个指针才能相减。
#include <stdio.h>
// 求字符数组的长度
// 1. 指针 - 指针求字符串长度
int my_strlen(char* p)
{
char* start = p;
while (*p != '\0')
{
p++;
}
return (p - start);
}
int main()
{
int num = my_strlen("abcdef");
printf("%d", num); // 6
return 0;
}
---------------------------------------------------------------------------------
// 2. 求字符串长度通过while循环计数
int my_strlen(char* p)
{
int count = 0;
while (*p != '\0')
{
count++;
p++;
}
return count;
}
int main()
{
int num = my_strlen("abcdef");
printf("%d", num); // 6
return 0;
}
-------------------------------------------------------------------------------------
// 3. 递归求字符串长度
int my_strlen(char* p)
{
if (*p == '\0')
return 0;
else
return 1 + my_strlen(p + 1);
}
int main()
{
int num = my_strlen("abcdef");
printf("%d", num); // 6
return 0;
}
- 指针加指针一般没有意义
- 比如:
- 日期加天数 -----有意义
- 日期减天数 -----有意义
- 日期减日期 -----有意义
- 日期加日期 -----无意义
三、指针的关系运算
#include <stdio.h>
#define N 5
int main()
{
int* vp = NULL;
int arr[N] = { 1,2,3,4,5 };
--------------------------------------------------------------------------------
for (vp = &arr[N]; vp > &arr[0];)
{
*--vp = 0;
}
--------------------------------------------------------------------------------
// N = 5 是 arr[4] 和 它后面的内存位置的指针进行比较
int i = 0;
for (i = 0; i < N; i++)
{
printf("%d", arr[i]); // 数组元素修改为0
}
return 0;
}
#define N 5
int main()
{
int* vp = NULL;
int arr[N] = { 1,2,3,4,5 };
-----------------------------------------------------------------------------------------
for (vp = &arr[N-1]; vp >= &arr[0]; vp--)
{
*vp = 0;
}
// 这种写法 当 vp 为 0 的时候,是 arr[0] 和 它之前的内存位置指针比较
-----------------------------------------------------------------------------------------
int i = 0;
for (i = 0; i < N; i++)
{
printf("%d", arr[i]); // 数组元素修改为0
}
return 0;
}
- 实际上绝大部分的编译器上两种都是可以顺利完成任务的,但是我们应该避免这种写法,因为表中并不保证它可行。
- 标准规定:
- 允许指向数组元素的指针与指向数组最后一个元素后面的哪个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
四、指针和数组
- 指针就是用来存放地址的。
- 数组就是一组相同类型的数值的组合。
- 数组名一般情况下表示首元素地址。
- 所以可以通过一下三种方法打印数组。
#include <stdio.h>
void test(int* arr, int sz)
{
int i = 0;
int* p = arr; // 首元素地址存入指针变量 p
for (i = 0; i < sz; i++)
{
printf("%d------------%d \n", *(arr + i), *(p + i));// 均可以打印出数组
// arr 表示首元素地址, p 也表示首元素地址
}
}
void test1(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]); // 打印数组
}
}
int main()
{
int arr[10] = { 0 };
test(arr, 10);
test1(arr, 10);
return 0;
}
五、二级指针
- 一级指针
int main()
{
int a = 0;
int* pa = &a; // 我们说,这里的pa 是一个一级指针
*pa = 20;
printf("%d", a);
return 0;
}
- 二级指针
int main()
{
int a = 0;
int* pa = &a; // 我们说,这里的pa 是一个一级指针
// 此时获取a的地址存放到pa变量中
// pa 变量是在内存中开辟了 4 个大小空间(32位)存放 a 的地址
&pa; // 获取 pa 变量的地址
int** ppa = &pa; // 获取 pa 的地址,在内存中申请大小为 4 的空间 ppa,存放pa地址
// 这里的ppa就是一个二级指针
**ppa = 20;
// *ppa 指向变量 pa
// **ppa 指向变量 a
printf("%d", a);
return 0;
}
六、指针数组
- 存放指针的数组就是指针数组,本质上是一个数组。
#include <stdio.h>
int main()
{
int a = 10;
int b = 20;
int c = 30;
int* parr[10] = { &a, &b, &c };
int i = 0;
for (i = 0; i < 3; i++)
{
printf("%d ", *parr[i]);
// parr[i] <==> *(parr+i)
// 以i = 0 来说明
// 这里的*(parr+i)指向的是 &a
// 再解引用指向 a
}
return 0;
}
指针数组可以将几个一维数组模拟成二维数组
int main()
{
int arr1[4] = { 1,2,3,4 };
int arr2[4] = { 2,3,4,5 };
int arr3[4] = { 3,4,5,6 };
int* parr[10] = { &arr1, &arr2, &arr3 };
int i = 0;
for (i = 0; i < 3; i++)
{
int j = 0;
for (j = 0; j < 4; j++)
{
printf("%d ", parr[i][j]);
// 这里 parr[i] <==> *(parr+i)
//
// parr[i][j] <==> *(parr[i]+j) <==> *(*(parr+i)+j)
// 以 i = 0 j = 0 为例
// *(parr+i) 指向 &arr1
// *(*(parr+i)+j) <==> *(&arr1) 指向 arr1 的首元素
}
printf("\n");
}
return 0;
}
总结
C语言指针±整数、指针-指针、指针关系运算、指针和数组、二级指针、指针数组等介绍,还包括指针数组将几个一维数组模拟为二维数组等的介绍。