一.指针和内存,地址的关系:
在正式了解指针之前,先了解内存编码,地址,指针三者的关系,内存编号地址指针,内存编号就是以十六进制表现的地址(没错他俩确确实实就是一个东西),而指针的产生就是为了快速寻找所想找的内存,所以牢记内存编号地址指针。
再稍微了解何为变量,变量就是在单元内存中申请内存,新开辟一块空间,所以当我们需要找到这块空间时就需要取其地址,所以&(取地址符)诞生,而指向这块被取地址的指针又如何调用?最终用 *(解引用)诞生了,所以指针的基本格式:
int i=0;
int *p=&i;//通过指针p来寻找i的地址
二.指针的构成
1.涉及符号:
*:解引用操作符
&:取地址操作符
2.部分表示意义:
了解了指针的基本组成及其相关符号,通过举例子来分别认识一下指针中每个部分都具有何种含义
int a=0;
int * p=&a;
p的类型是int*(p是int * 型的指针)
int则是指*p指向对象的类型是int
*p=a;
p是地址
*p是指向的对象,一定要清楚到底拿的是什么。
3.代码实现:
#include<stdio.h>
int main()
{
int a = 0;
int* p = &a;
printf("%d", *p);
return 0;
}
4.const:
1.4.1意义:修饰指针/变量,防止指针/变量被修改。
1.4.2代码表示以及const可修饰的指针:
const可放置的位置有两种,两种不同的拜访方式有不同的效果
- const放在*的左边:
int a=10;
const int *p=&a;//第一种const放在左边的表达形式
int const *p=&a;//第二种const放在左边的表达形式
const放在左边时被锁定就是*p所指向的空间而并没有锁住p。
注:是以 * 来划分,并非以类型为划分,所以const放在int的哪边并不重要
- const放在*的右边:
int a=0;
int * const p=&a;
是指p本身不可被修改。
3. const不同的作用效果的体现:
#include<stdio.h>
int main()
{
int a=10;
const int *p=&a;
int p=20;
*p=20;//此时报错的将是这一行,因为const被放到*左边时,被锁的是*p这个指针所指向的内容,但p仍然可以被修改
return 0;
}
#include<stdio.h>
int main()
{
int a=10;
int * const p=&a;
int p=20;//此时报错的将是这一行,因为const被放到*右边时,被锁的是p这个指针本身,但*p所指向的空间仍然可以被修改
*p=20;
return 0;
}
(这两个码可以分别在编译器中实现,分别感受有何不同)
1.4.3const可修饰的整数:
const既可以修改指针,同样的也可以修改变量,防止变量被改变。格式如下:
const int a=10;
三.指针大小(4/8)
1.求指针大小:
#include<stdio.h>
int main()
{
printf("%d", sizeof(char *));
printf("%d", sizeof(int *));
return 0;
}
//以上两个不同类型的指针的运行结果在×64的环境下结果为8
//在×86的环境下结果为4,未因类型的改变而改变数字大小
所以指针是有固定大小的,在×64的环境下结果为8,×86的环境下结果为4,与类型无关,而前面谈到内存编号地址指针,也可知内存编号,地址的大小也为4或8.
四.指针类型的作用:
既然不论何种类型的指针,其指针本身的大小都不变那指针的类型又有什么作用呢?答案是:查找,通过指针可以快速确定变量地址,而对于数组来讲,在取得首元素地址后,便可以通过指针推算出整个数组。
这正式了解指针类型作用时先了解指针与数组的关系
1.指针和数组:
注:数组元素在内存中的排序是连续的,只需知道首元素地址,其他地址即可依次得出
1.通过指针访问数组下标,代码列子:
#include<stdio.h>
int main()
{
int i = 0;
int arr[] = { 1,2,3,4,5 };
int* p = &arr[0];
int z = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < z; i++)
{
printf("%d",*( p+i));//在的到数组首元素地址后通过对指针进行相关操作而达到查找的目地
}
return 0;
}
//输出结果为1 2 3 4 5
在上述程序中指针的类型是int *,那么如果指针的类型和数组类型都改为char呢?结果会有何改变?
#include<stdio.h>
int main()
{
int i = 0;
char arr[] = { 1,2,3,4,5 };
char * p = &arr[0];
int z = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < z; i++)
{
printf("%d",*( p+i));
}
return 0;
}
输出结果依然是1 2 3 4 5,既然指针大小都为4或8,那么为什么在,char的类型下,依然不影响输出结果,这就是因为不同的指针类型再被+1时所跳过的字节数不同。
2.指针拥有类型后的用处:
虽然指针的大小固定不变,但指针的类型决定了指针在+/-时,所跳过的字节长度。
五.指针的运算:
1.三种指针常见运算:
6.1.1.指针和整数:
在通过指针访问数组下标的地方所运用的就是指针与整数之间的运算。
6.1.2.指针和指针:
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4 };
int* p = &arr[0];
int* c = &arr[3];
printf("%d\n", p-c);
return 0;
}
//输出结果为-3
在指针与指针之间的运算之中所得出结果的绝对值是两个指针之间相隔的元素个数。
注:两个相加减的指针需要时指向同一片空间(不能是两个数组中的指针进行运算 )。
原因:两个数组之间隔了多少是未知的
6.1.3.指针的关系运算:
指针间的关系运算,就是指针间大小的比较,也是地址间大小的比较。
#include<stdio.h>
int main()
{
int arr[] = { 1,2,3,4 };
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;
while (p < arr + sz)//指针在进行大小比较
{
printf("%d ", *p);
p++;
}
return 0;
}