指针和指针类型

32位

1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
printf("%d\n",
sizeof(int*)); //4
printf("%d\n",
sizeof(char*)); //4
printf("%d\n",
sizeof(short*)); //4
printf("%d\n",
sizeof(double*)); //4
return 0;
}
1
2
3
4
5
6
7
int main()
{
int a = 0x11223344;
char* pa = &a;
*pa = 0;
return 0;
}

指针类型决定了在进行解引用操作的时候,能够访问空间的大小
int* p; p能够访问4个字节char p; p能够访问1个字节double p; *p能够访问8个字节

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
int a = 0x11223344;
int* pa = &a;
char* pc = &a;
printf("%p\n", pa);
//012ffd44
printf("%p\n", pa + 1);
//012ffd48
printf("%p\n", pc);
//012ffd44
printf("%p\n", pc + 1);
//012ffd45
return 0;
}

指针类型决定了指针走一步跳过了几个字节
决定了指针的步长
int* p; p + 1 --> 4
char* p; p + 1 --> 1
double* p; p + 1 --> 8

1
2
3
4
5
6
7
8
9
10
11
12
int main()
{
int arr[10] = { 0 };
char* p = arr;//数组名-首元素的地址
int i;
for (i = 0; i < 10; i++)
{
*(p + i) = 1;
printf("%d\n", *(p + i));
}
return 0;
}

野指针

  1. 指针未初始化
    如果不知道赋值什么,就赋值NULL
  2. 指针越界访问
  3. 指针指向的空间释放

指针运算

  1. 指针加减整数
1
2
3
4
5
6
7
8
9
10
11
12
13
int main()
{
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;
for (i = 0; i < sz; i++)
{
printf("%d ", *p);
p++;
}
return 0;
}
  1. 指针-指针
1
2
3
4
5
6
7
8
9
int main()
{
char ch[5] = { 0 };
int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
printf("%d\n", &arr[9] - &arr[0]);//9
printf("%d\n", &arr[0] - &arr[9]);//-9
printf("%d\n", &arr[9] - &ch[0]);//错误
return 0;
}

指针-指针得到的是中间元素的个数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int my_strlen(char* str)
{
char* start = str;
char* end = str;
while (*end != '\\0')
end++;
return end - start;
}
int main()
{
char arr[] = "bit";
int len = my_strlen(arr);
printf("%d\n", len);
}
  1. 指针的关系运算
1
2
3
4
5
6
7
#define N_VALUES 5
float values[N_VALUES];
float* vp;
for(vp = &values[N_VALUES]; vp > &values[0]; )//选择这个
*--vp = 0;
for(vp = &values[N_VALUES - 1]; vp >= &values[0]; vp--)//避免,标准不保证可行,尽管大多数编译器可以通过
*vp = 0;

标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,
但是不允许与指向第一个元素之前的那个内存位置的指针进行比较

指针和数组

数组名是首元素的地址

1
2
3
4
5
6
printf("%p\n", arr);
printf("%p\n", &arr[0]);//结果相同
printf("%p\n", &arr);//结果相同,但地址是整个数组的地址
printf("%p\n", arr + 1);//加4
printf("%p\n", &arr[0] + 1);//加4
printf("%p\n", &arr + 1);//加4*n

注意:

  1. &数组名 – 数组名不是首元素的地址 – 数组名表示整个数组 – &数组名取出的是整个数组的地址
  2. sizeof(arr) – sizeof(数组名) – sizeof(数组名)计算的是整个数组的大小

其他情况下数组名都表示首元素的地址

二级指针

int a=10;
int* pa=&a;
int** ppa=&pa;//ppa就是二级指针
int*** pppa=&ppa;//三级指针

指针数组

指针数组 - 数组 - 存放指针的数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
int a = 10;
int b = 20;
int c = 30;
//整型数组 - 存放整型
//字符数组 - 存放字符
//指针数组 - 存放指针
int* arr[3] = { &a, &b, &c };//指针数组
for (int i = 0; i < 3; ++i)
{
printf("%p\n", arr[i]);
printf("%d\n", *arr[i]);
}
}

数组指针 - 指针