1.*p=*p+1、++*p、(*p)++与*p++的区别:
*p=*p+1、++*p、(*p)++这三种都是对指针对应变量值进行加一,地址并不改变,变量值加一。
#include<stdio.h>
int main(void)
{
int x=2;
int *p;
p=&x;
printf("%d\n",p);
++*p;
printf("%d %d %d",*p,p,x);
}
对于y=*p++这种赋值语句,先把p所指向的变量x值赋给变量y,再将指针值加1个数据类型对应字节,此时指向的不是x,(一开始指向x=2,现在变成1703896)。而对于不是赋值语句,printf("%d",*p++);输出的结果就是指针修改后对应的值(1703896)。
#include<stdio.h>
int main(void)
{
int x=2,y;
int *p;
p=&x;
printf("%d\n",p);
y=*p++;
printf("%d\n",y);
printf("%d %d %d",*p,p,*p++);
}
2.调用函数中含有指针,能够对主函数的变量进行更改,因为指针是从地址对应的变量进行更改,因此会影响到主函数变量的数值。进行对比:第一个swap1不会改变主函数的 a,b值,因为主函数的实参传递到调用函数的形参中,调用函数只是对形参进行改变。(如果定义全局变量,是阔以改变的)。
#include<stdio.h>
void swap1(int x,int y),swap2(int *px1,int *py1);
int main(void)
{
int a=1,b=2;
int *px=&a,*py=&b;
swap1(a,b);
printf("a=%d,b=%d\n",a,b);
swap2(px,py);
printf("a=%d,b=%d\n",a,b);
}
void swap1(int x,int y)
{
int i;
i=x;
x=y;
y=i;
}
void swap2(int *px1,int *py1)
{
int i;
i=*px1;
*px1=*py1;
*py1=i;
}
3.指针,数组与地址的应用:对于定义时,可以有int *p=&a;(带int 时候,对指针所指对象进行说明,虽然有*,但这个时候指的是地址,因此用&a)。对于int a[10],*p; 把数组中a[0]地址给指针:①p=a;②p=&a[0];两种。同样的有p=a+i; p=&a[i] (*(a+i),a[i],*(p+i)p[i]等价) 。
4.对于指针加或减,并不是指针值进行加一或者减一,而是加上或者减去该指针指向的变量数据类型长度。例如指针值q=p+1,是对p对应地址加上一个整型数据的长度(4字节)。
#include<stdio.h>
int main(void)
{
int a[2],*p,*q;
p=a;
q=p+1;
printf("%d\n",q-p);
printf("%d %d\n",int(p),int(q));
printf("%d\n",int(q)-int(p));
return 0;
}
5.二分法。对排序过数组(要是没排序,先用冒泡法排序),输入x值,找数组中与其值相同元素,输出下标,算法关键在于中间值的选取,然后一步一步缩小,分三种情况进行。用while循环时,条件就是最小值<=最大值。
#include<stdio.h>
int two(int *p,int n,int x);
int main(void)
{
int a[10]={0,1,2,3,4,5,6,7,8,9};
int j,n,x;
n=10;
printf("输入整数x:");
scanf("%d",&x);
j=two(a,n,x);
if(j!=-1)
{
printf("%d",j);
}
else printf("NOT FOUND");
return 0;
}
int two(int *p,int n,int x)
{
int min,max,mid;
min=0;max=n-1;
while(min<=max)
{
mid=(min+max)/2;
if(x==*(p+mid))
{
break;
}
else if(x>p[mid])
{
min=mid+1;
}
else
max=mid-1;
}
if(min>max)
{
return -1;
}
else return mid;
}
6.字符串输入输出时,char a[10]; scanf("%s",&a); printf("%s",a);不能用printf("%s",a[10]);首先用a[10]本来就是错误,因为数组的长度为10,但是表示的最后面的元素为a[9],其次a[i]代表的是数组中的一个元素,因此不能在%s输入输出字符串时使用。