int temp;
今天初次接触了指针,这是我学习做的一点笔记,欢迎各位前来观看有错误请帮忙改正。谢谢
指针
指针:指向一个变量的地址。
指针变量:存放另外一个变量地址的变量。
通常我们所说的指针是指指针变量。
指针变量的定义: 基类型 *指针变量名
其中基类型是指针变量所指向变量的类型。
必须指定基类型的原因:
指针的移动和指针的运算(不同的类型字节数不同)
虽然基类型不同 但是他们所指向的地址值都是整型的。所有的指针型变量都占四个字节,因为地址值为int型。
eg:
int main()
{
int *p;
char *q;
printf("%d,%d\n",sizeof(p),sizeof(q));
return 0;
}
运行结果为: 4,4
通过这个例子来理解指针是如何将值提取出来的。
int main()
{
int a=6;
int b=8;
int *p=&a;
int *q=&b;
printf("%d %d %d %d %d%d",*&a,*&p,&*p,p,&a,a);
return 0;
}
运行结果为:6 1376060 1376060 1376060 1376060 6
再通过两个例子来区分值传递的问题:
int main()
{
int a=6;
int b=8;
int *p=&a;
int *q=&b;
int *t=NULL;
int temp;
t=p;
p=q;
q=t;
printf("%d,%d\n",a,b);
printf("%d,%d\n",*p,*q);
return 0;
}
运行结果为:6,8
8,6
eg:
int main()
{
int a=6;
int b=8;
int *p=&a;
int *q=&b;
temp = *p;
*p = *q;
*q = temp;
printf("%d,%d\n",a,b);
printf("%d,%d\n",*p,*q);
return 0;
}
运行结果为:
8,6
8,6
这就是传递指针和单传的不同。
野指针:没有指向地址的指针变量。也就是指向了垃圾内存的指针。
eg: int *p=NULL;
为了防止野地址的出现,先定义为0.这样就可以防止出现地址错误。
指针变量作为函数参数:
void swap(int *a,int *b)
{
int t ;
t = *a;
*a = *b;
*b = t;
}
int main()
{
int a = 6,b = 8;//9
swap(&a,&b);
printf("%d,%d\n",a,b);
return 0;
}
运行结果:
8,6
因为采用的是地址传递的方式,所以在函数调用之后,本身的值也发生了改变。
eg:
int main()
{
int *p=(int*)0x2000;
int *q=(int*)0x2014;
printf("%x\n",(char*)p+5);
printf("%x\n",(double*)p+5);
printf("%x\n",(short*)p+5);
printf("%x\n",(long*)p+5);
printf("%d\n",p-q);
return 0;
}
运行结果为:
2005
2028
200a
2014
-5
从这道题目可以看出来,指针的运算就是相减和相加都是其对应的单元数。
魔数: 在代码中,应该避免无缘无故的数出现,如果出现了这样就是魔数。
eg: 几种不同的方式输出数组中的数据。
int main()
{
int *p = NULL;
int a[N] = {1,2,3,4,5,6,7,8,9,0};
//int b[3][4];
int i = 0;
//int *const a;
// sizeof(a)
p = &a[0];//a,&a[0] p = a
// printf("%d\n",*p);
for(i = 0;i<N//如果将N换为10就是魔数;i++)
printf("%d ",a[i]);
printf("\n");
for(i = 0;i<N;i++)
printf("%d",*(a+i));
printf("\n");
for(p= a,i = 0;i<N;i++)
printf("%d ",p[i]);
printf("\n");
for(i = 0;i<N;i++)
printf("%d",*(p+i));
printf("\n");
for(p=a;p<a+N;p++) //for(p =a;p <p+N;p++);
printf("%d ",*p);
printf("\n");
return 0;
}
eg: 在计算机的存储中 都是以二进制的方式存储的。
#if 1
// 0000 0001 0000 0001 0000 0001 0000 0001
int main()
{
char a[]={1,1,1,1,1};
int *p=(int*)a;
//char b='1';
//char c=1;注意两者的区别。
printf("%d\n",*p);
return 0;
}
#endif
eg:
int main()
{
int a[5] = {1,3,5,7,9};
int *p = (int*)(&a+1);
printf("%d\n",*(p-1));
return 0;
}
运行结果为:
9
说明:*p是从所指的地址开始,从p的基类型所占的字节数为偏移量,取当前内存的内容。而数组名可以做指针使用,但不是指针。
用指针的方法将数组里面的元素逆序输出:
eg:
int main()
{
int a[] = {1,3,2,6,5,4,0,9,8,7};
int n = sizeof(a)/sizeof(a[0]);
int *p = a,*q = a + n-1;
int t;
while(p < q)
{
t = *p;
*p = *q;
*q = t;
++p;
--q;
}
for(p = a;p<a+n;p++)
printf("%d ",*p);
return 0;
}
运行结果为:
7 8 9 0 4 5 6 2 3 1
用指针的方法做冒泡法排序
eg:
int main()
{
int a[] = {3,2,1,4,5,0,9,8,7,6};
int n = sizeof(a)/sizeof(a[0]);
int *p = a,*q = a,*m = a + n,t;
for(p = a;p<a+n;p++)
{
for(q = a;q < m-1;q++)
{
if(*q > *(q+1))
{
t = *q;
*q = *(q+1);
*(q+1) = t;
}
}
--m;
}
for(p = a;p < a + n;p++)
printf("%d ",*p);
printf("\n");
return 0;
}
运行结果为:
0 1 2 3 4 5 6 7 8 9
eg:const是一个只读变量,它的值不能改变
int main()
{
int a = 6;
int *const p1 = &a;
int const *p2= &a;
const int *p3 = &a;
const int *const p4 = &a;
return 0;
}
第一个:p1为const类型。
第二个:(*p2)是const类型。
第三个:(*p3)是const类型。
第四个:p4和(*p4)都是const类型。