本文共 6894 字,大约阅读时间需要 22 分钟。
指针对变量使对指向变量的指针&运算符产生,对指针使用*运算符则可以返回到原始变量
只要p指向i,那么*p就是i的别名*p不仅仅拥有和i同样的值,而且对*p的改变i的值*p左值,对它赋值合法*p = 90;p 对象 的内存地址*p 是指向对象的别名 p 存储的是指针p = &i;i = 1;不把间接寻址运算符用于未初始化的指针变量;int *p;printf("%d",*p); /* prints garbage */给*p赋值甚至更糟,p可以指向内存中的任何地方,赋值改变了某些未知的内存单元int *p;*p = 1 /* Wrong */上述赋值改变的内存单元可能属于程序(可能导致不规律的行为)或者属于操作系统--可能导致系统崩溃;指针赋值C语言允许使用赋值运算符进行指针复制,两个指针具有相同的类型指针赋值允许使用赋值运算符进行指针赋值,两个指针具有相同的类型int i,j,*p,*q;p = &i;p 存储的是变量在内存中的地址把q指向了和p指向相同的地方;q = p 指的是内存地址空间的值*q = *p 指的 是所指向的内存地址空间存储的值相等!p = &i;q = &j;i = 1;*q = *p;赋值语句*q = *p是把p指向的值(i的值)赋值到q指向的内存单元(变量j)中;C语言用值进用变量作为实际参数行参数传递,所以在函数调用中用变量作为实际参数会阻止对变量的改变需要函数改变变量C这种特性指针提供了此问题的解决方法不再传递变量X作为函数的实际参数而是&x不再传递变量X作为函数的实际参数,而是采用&x 指向X指针的申明相应的形式参数p是指针p &x*p 是x的别名函数体内*的每次出现都是对X的间接引用*p 每次出现都将是对X的间接引用,而且允许函数既可以读取X也可以修改函数体内*p的每次出现都是对X的间接引用,而且允许函数既可以读取X也可以修改Xdecomposevoid decompose(float x,int *int_part,float *frac_part);指针会告诉scanf函数读取的值所放置的位置没有&运算符,scanf函数将虽然需要scanf函数的实际参数是指针但是不是每个实际参数总是需要&运算符scanf函数传递了指针变量;int i,*p;p = &i;scanf("%d",p);f(&x); // 地址希望改变参数的值可以使用单词const 不会改变传递给函数的指针所指向的 对象为了允许检查传递的指针指向的实际参数.void f/(const int *p){ *p = 0;}const的使用说明p是指向 整型常量指针int *max(int *a,int *b) //返回指向最大数的指针---变量数的内存地址位置 *a *b 是{ if (*a > *b){ return a; //a 存储的是a指针变量所指向的变量的内存的地址,*a 取指向变量内存地址elsereturn b;值}}变量的别名 a,b 存储的是变量的内存地址;调用max函数,传递指向两个int型变量的指针,结果存储在指针变量中;int *p,x,y;p = max(*x,*y);永远不会指向自动永远不会返回指向自动局部变量的指针int *f(void){ int i;return &i;}void f(const int *p) //常量指针,p存储的 内存地址 到底盘是不给修改p 内存地址还是不给修改 *p p 所指向的变量内存地址的变量数据;void f(const int *p);const int *p 常量指针变量阻所指向的止修改的是指针 变量的值可以修改p 保存的 内存别的地址!void f(const int *p){ int j;p = &j;}void f(const int *p){ //}指的是不允许修改p 所指向的内存位置的值,为不是不允许修改p 指针变量的值,指针变量可以指向别的内存地址申明指针类型的形式参数,void f(int * const p)const 可以保护p 指向的对象 ,在的类型后面放置const可以保护p本身void f(const int *p) //保护*p 指不允许修改*p的值,但是可以把指针变量重新指向别的内存地址void f(int * const p); //保护的是指针变量不能重新赋值别的内存地址 但是*p 却是可以修改指针变量p的前面放置const可以保护p指向的对象在p的类型后面放置const保护p本身;p的类型前面放置const可以保护p指向的对象,p的类型后面放置const 可以保护p本身void f(int * const p){ int j;*p = 0; //legalp = &j; //Wrong,p指针变量此时被保护;}p很一个少是另一个指针的副本,既要保护p又要保护*p对象,可以通过p类型的前后都放置constvoid f(const int * const p){ int j;*p = 0; //Wrongp = &j; //Wrong}数组指向数组元素,C允许算术运算引出了对数组进行处理的替换可以是指针对指针进行算术 指针指向数组元素,允许对指针进行可以使指针代替数组下标进行操作数组和指针关系当指针指向数组元素 允许对指针进行算术运算指针代替数组下标指针代替数组下标指针指向数组元素指针和数组之间的关系指针处理数组的主要原因是效率指针的算术运算如何使用关系运算符合判等运算符进行指针的比较如何能用指针处理数组元素数组名字作为指向数据中元素的第一个数组名指向数组中第一个元素的指针把指针p指向数组a的元素、通过在p执行指针算术运算 地址运算 可以访问到数组a的其他元算术素地址运算 指针运算 访问到数组的其他元素C支持3中格式的指针指针加上整数指针减去整数两个指针相减 指针算术运算--地址算术运算 可以访问到数组a的其他元素C支持3种格式的指针算术运算指针加上整数指针减去整数两个指针相减int a[10],*p,*q,i;指针 减法运算 减去整数;p指向数组元素a[i],p - j 指向a[i - j]指针加上整数指针减去整数两个指针相减指针相减 结果为指针之间的距离计算数组中元素个数指针相减,结果为指针之间的距离 计算数组中元素 的个数p指向a[i] q指向a[j] q - q 等于 i -j;只算术数组元素,指针有p指向p上的 意义结果只有两个指针指向同一个数组,指针相意义;减才有指针比较用关系运算符< <= > >= 和判等运算符== !=只有用关系两个指针指向同一个数组 运算符进指针比较菜有意义 比较的结果行的 依赖数组中两个元素 的相对位置指针用于数值处理指针的算术运算允许通过对指针变量进行重复自增来数组的元素访问指针用于数组处理指针的算术运算允许通过对指针变量进行重复自增来访问数组的元素指针的算术运算允许通过对指针变量进行重复自增来访问数组的元素指针的算术允许通过对指针变量进行重复自增来访问数组的元素程序对数组元素进行求和;指针变量p初始化指向a[0]每次被执行循环,p a[0];p进行自增结果p 指向a[1] p 执行到数组a的最后一个元素后循环终止;#define N 10 宏名称 typedef int newTypeName;int a[N],sum,*p;//sum = 0;for (p = &a[0];p < &a[N];p++){ sum += *p;}关系运算符 判等运算符== != 两个指针指向同一数组 比较的结果依赖数组中两个元素的相对位置指针相减两个指针相减两个指针相减,结果为指针之间的距离 指针之间的距离 指针 加整数 指针减整数指针相减结果为指针之间的距离 计算数组中元素的个数指针相减指针间接的距离 计算数组中元素的个数p指向a[i] 且q指向a[j];指针相减结果为指针之间的距离 -- 计算数组中元素的个数 p指向a[i] q指向a[j] p - q 等于i - j;指针减去整数p指向数组元素a[i] 那么p - j 指针与整数相加减 的作为就是移动指针指向的数据元素的内存地址p = &a[8];q = p - 3;p -= 6;指整数针减 作为是将指针现在指向的数组元素的内存地址位置向左移动整数个p = &a[8];q = p - 3 但此的值是指针变量,存储的是内存的 地址;p -= 6;p = p -6 p 指针当前的位置 向左边移动6个元素量;#define N 10int a[N],sum,*p;sum = 0;for (p = &a[0];p < &a[N];p++){ sum += *p;}a[] 10个元素数组,sum 整型变量 ,*p整形指针变量sum = 0;for (p = &a[0]//整型指针变量指向a数组的第一个元素;p < &a[N];p++) p = p + 1 指针变量与整数相减价 的 作用就移动指针所指向的数组的元素;p < &a[N] 小于指针指向的数组元素的最后一个元素;p++ 数据的元素移动;p < &a[N] 元素不存在数组a的下标从0 到N - 1对它取地址运算符合法 p = &a[N] 循环终止*间接引用 运算符 取的是指针指向的内存地址空间的值 ++ 运算符数组存入数据元素中数值存入到数组元素中;推进到下一个元素 利用数组下标可以写成a[i++] = j;如果p指向数组元素,相应的语句将会是*p++ = j;*p = *p + 1 //Wrong*p++ = *(p++) *(p = p + 1)计算用的都是指针变量*p 当使用间接引用的时候,计算的就是 改变间接引用指针所指向的内存地址的变量的值;把值存入到数组元素中,然后推进到下一个元素i = i + 1;利用数组下标;p指向数组元素*p++ = j;*p 指的是 间接取值 p 代表的是变量内存地址的指针变量;++在* 间接引用前使用 是指针变量的值--其它变量的内存地址 的 位置向后推进*(p++) = j; 后缀 只有表达式计算出后才自增*(p++)的值将是*p; p 指向当前对象(*p)++ 表达式返回p指向的对象值 然后对象进行自增返回指向对象的 p 本身是不变化 的 p 指向变量 的 内存地址;*p++ *(p++)自增前表达式的值是 自增前表达式*p(++)*p++ 指针变量的值在变化 增加 向下一数组元素推进个 *p++ *(p++);自增的指针变量的值,达到的效果就是指针所指向的内存地址的指向位置推进到数组元素的下一个(*p)++ `*p`使用间接引用取出指针变量所指向的内存的地址,然后此值进行自增;*(p++)自增前表达式的值*p++ 计算的是p++*p(*p)++自增前表达式值,然后自增的是什么?*++p 先自增p 自增后表达式的值是*p++ *p 先自增*p++ *(p++) 推进到指针所指向的数组元素的下一个for (p = &a[0]; p < &a[]N;p++)指针指向数组的第一个元素,指针p的值小于指针指向的数组元素的最后的值sum += *p;p = &a[0];while (p < &a[N]) sum += *p++;*p++ *++p ++运算符的优先级别高于 *的 首先计算的是 指针变量的值;原始版本的栈依赖名为top的整型变量跟踪contents数组栈顶的位置top整型变量跟踪contents数组栈顶的位置 FILO first input last output用指针变量替换top指针变量初始指向contents数组的第0个元素;指针变量替换top 指针变量初始指向contents数组的第0个元素指针int *top_ptr = &contents[0];指针变量 指针变量初始指向contents数组的第0个元素int *top_ptr = &contents[0];void push(int i){ if (is_full()){ stack_overflow();}else{ *top_ptr++ = i;}}int pop(void){ if (is_empty()){ stack_underflow();}elsereturn *--top_ptr;}数组名作为指针指针的算数字和指针之间术运算是 相互关联的一种方法,但不是 用数组的名字作为指向数组第一个元素的指针数组的数组第一个名字作为指向数组的名字指向数组第一个元素的指针 数组的名字 关系简化了指针的算术运算 是数组和指针都更加通用数组名作为指针用数组名作为指针指针的算术运算是数组和指针之间相互关联的一种方法 下面是另一种关系;*a 数组的名字作为指向数组第一个元素的指针这种关系简化了指针的算术运算,使得数组和指针都更加通用;int a[10];用a作为指向数组第一个元素的指针int a[10];正新数组 int a[10];a作为指向数组第一个元素的指针, a作为指向数组第一个元素的指针,修改a[0];数组名作为指针int a[10];a 数组名称 就是整个数组的地址,也是数组元素的第一个元素的地址;*a = 7;//*(a + 1) = 12;数组名作为指针指针的算术运算 数组的名字 作为指向数组第一个元素指针 关系简化了指针的算术运算 如下形式声明aint a[10];a作为指向数组第一个元素指针,修改a[0];指向数组元素的第一个元素的指针 数组名称 作为指向数组第一个元素的a 存储的是 数组的地址 也是数组第一个元素的地址*a = 7; a[0] 都表示数组的第一个元素;a存储的是数组内存地址 整个数组在内存地址,数组第一个元素在内存地址;* *(a + 1) = 12 取地址运算&a[0] = 存储和 取出 的 是变量的内存地址;a + i &a[i] 指向数组a中i元素的指针*(a + i) 取值间接引用;数组的第n个元素;把数指针算术运算的组的下标看成是格式;数组名可以用作指针的事实 数组 编写从头数组的循环更加容易到尾单步操作for (p = &a[0];p < &a[N];p++)p 指针变量指向数组的&a[0]第一个元素的指针,p < &a[N] p指针的变量小于数组最后一个元素内存地址后的一个不存在的数组元素的 到此处时 For 语句已经终止;a 数组名代替 代表数组的第一个元素,整个数组在内存的第一个a &a[0]a + N &a[N] 这个 是为什么呢? a 表示数组的第一个元素, a + N 表示数组元素的地址向下 推进, &a[N]表示数组的第N个元素的内存地址a + N === &a[N]!!!;p < a + N p = a 指针的变量 指针 指向 数组元素的第一个 后面a + N p++ 指针变量;sum += *p;数组 用作指针虽然可以把数组名 数组名赋新的值;试图错误使数组名指向其他地方while (*a != 0)*a 间接 a 地址a++ a 是内存地址 自增 改变的 效果是 推进 数组 元素位置la++ 数组名 使 数组名用作指针 但不能给数组名赋予新的值,试图使数组指错误向其他试图使其它地方错误a++使数组名指向其他 地方 是错误数组名不能赋予新值;可以始终 把a复制给指针变量 然后 改变 指针变量p = a while (*p != 0)p++ p 指针 数列反向数列反向 reverse.c 读进10 反序写出这些数 存入数组程序利用下标访问数组元素利用下标数组的算术运算代替指针的原来程序中 scanf函数要求的参数;p 指向数组的元素,满足scanf函数要求的参数 p指向数组元素 内存地址,满足scanf函数要求参数 &p 指向另一个指针的指针数组型实际参数传递给函数,数组名始终作为指针数组型实际参数,数组名始终作为指针数组型实际参数,传递函数,数组名始终作为指针,函数返回整型数组中最大元素转载地址:http://vvsvx.baihongyu.com/