86 lines
2.2 KiB
C
86 lines
2.2 KiB
C
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include <time.h>
|
||
#include <math.h>
|
||
#include <stdbool.h>
|
||
|
||
// !指针运算
|
||
/*
|
||
1.指针p+1,
|
||
指针p的值会自动增加一个存储单元的大小(sizeof(数据类型)),即指向下一个元素的存储单元
|
||
给一个指针加1表示要让指针指向下一个变量
|
||
int a[10];
|
||
int *p = a;
|
||
*(p+1)—>a[1]
|
||
如果指针不是指向一片连续分配的空间,如数组,则这种运算没有意义
|
||
即*(p+n)<——>ac[n]
|
||
2.*p++
|
||
取出p所指的那个数据来,完事之后顺便把p移到下一个位置去
|
||
*的优先级虽然高,但是没有++高
|
||
常用于数组类的连续空间操作
|
||
在某些CPU上,这可以直接被翻译成一条汇编指令
|
||
3.指针比较
|
||
<,<=, ==,>,>=,!=都可以对指针做
|
||
比较它们在内存中的地址
|
||
数组中的单元的地址肯定是线性递增的
|
||
4.0地址
|
||
当然你的内存中有0地址,但是0地址通常是不能随便碰的地址,所以你的指针不应该具有0值
|
||
因此可以用0地址来表示特殊的事情: 返回的指针是无效的,指针没有被真正初始化(先初始化为0)
|
||
NULL是一个预定定义的符号,表示0地址
|
||
有的编译器不愿意你用0来表示0地址
|
||
5.指针的类型
|
||
无论指向什么类型,所有的指针的大小都是一样的,因为都是地址
|
||
但是指向不同类型的指针是不能直接互相
|
||
赋值的 这是为了避免用错指针
|
||
6.指针的类型转换
|
||
void*表示不知道指向什么东西的指针
|
||
计算时与char*相同(但不相通)
|
||
指针也可以转换类型
|
||
int *p = &i;void*q = (void*)p;
|
||
这并没有改变p所指的变量的类型,而是让后人用不同的眼光通过p看它所指的变量
|
||
我不再当你是int啦,我认为你就是个void!
|
||
7.用指针来做什么
|
||
需要传入较大的数据时用作参数
|
||
传入数组后对数组做操作
|
||
函数返回不止一个结果
|
||
需要用函数来修改不止一个变量
|
||
*/
|
||
|
||
int main(void)
|
||
{
|
||
/* 1.指针p+1 */
|
||
char ac[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||
char *p = ac; // 指向数组首元素的指针,相当于char *p = &ac[0]
|
||
char *p1 = &ac[5];
|
||
printf("p = %p\n", p); // %p是以16进制输出地址
|
||
printf("p+1 = %p\n", p + 1);
|
||
printf("p1-p = %d\n", p1 - p);
|
||
|
||
int ad[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||
int *q = ad;
|
||
int *q1 = &ad[6];
|
||
printf("q = %p\n", q); // %p是以16进制输出地址
|
||
printf("q+1 = %p\n", q + 1);
|
||
printf("q1-q = %d\n", q1 - q);
|
||
|
||
/* 2.*p++ */
|
||
char ae[] = {0,1,2,3,4,5,6,7,8,9,-1};
|
||
char *p2 = ae;
|
||
int i = 0;
|
||
for (i = 0; i < sizeof(ae) / sizeof(ae[0]); i++)
|
||
{
|
||
printf("%d\n", ae[i]);
|
||
}
|
||
for (p2 = ae;*p2!=-1;p2++) // *p2++先取值,再指向下一个元素
|
||
{
|
||
printf("%d\n", *p2);
|
||
}
|
||
|
||
/* 4.0地址 */
|
||
char ai[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||
char *q3 = ai;
|
||
q3=p; //
|
||
|
||
return 0;
|
||
}
|