函(xiao)数(bai)声明:一个刚接触c不久的大一小白
c中赋值语句就是将右值赋给左值
也就是说假如a=3,b=4
然后a = b;
那么a=4,而b保持不变
#include<stdio.h>
int main()
{
int a=3,b=4;
a=b;
printf("a=%d b=%d",a,b);
}
于是我一直认为将右值赋给左值是不会改变右值的
赋值改变右值,听上去也很奇怪
但是...
当我某天不小心写错了一段代码后,我发现了这件很邪恶的事情...
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
void fun(int *s,int n,int *s3)
{
//--ksstart(注释不能删除)—
//考生代码从此开始编写
int i,j,t;
for (i=0;i<n-1;i++)
for (j=0;j<n-1-i;j++)
if (s[j]<s[j+1])
{
t=s[j];
s[j]=s[j+1];
s[j+1]=t;
}
if (n>2)
for (i=n-3;i<=n-1;i++)
s3[i]=s[i];
else
for (i=0;i<n;i++)
s3[i]=s[i];
//--ksend---
}
main()
{
int s[]={1,2,3,4,5,6},s3[3]={0,0,0},i;
int n=sizeof(s)/sizeof(int);
fun(s,n,s3);
printf("后三个数是:%d ,%d ,%d \n",s3[0],s3[1],s3[2]);
for (i=0;i<n;i++)
printf("%d ",s[i]);
}
我在第20行的地方将
s3[i-n+3]=s[i];
写成了
s3[i]=s[i];
然后就gg了
这代码显然不对,没能得到想要的s3数组的正确的3个值
但我意外地发现原来的数组s的元素也不对了
于是我大吃一斤
开始化身暴躁老哥,想要知道到底是哪导致了s数组元素的改变
在我马上就要变身德国boy怒砸键盘之时
突然灵光一闪!
于是我走上了验证之路...
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},b[3]={1,2,3},i=4;
for (i=0;i<sizeof(a)/sizeof(int);i++)
printf("%d ",a[i]);
printf("\n");
b[i]=a[i];
for (i=0;i<sizeof(a)/sizeof(int);i++)
printf("%d ",a[i]);
}
在执行上述代码后,我们发现
作为右值的a数组元素的值被改变了 ,但我们并没有对a元素做过任何改变值的操作(至少就代码表面而言)
我陷入了深深的沉思之中...
突然,我觉得a数组元素值的改变应该是更深层次的东西
也就是涉及计算机内部
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},b[3]={1,2,3},i=4;
for (i=0;i<sizeof(a)/sizeof(int);i++)
printf("%d ",a[i]);
printf("&a=0x%p",a);
printf("\n");
for (i=0;i<sizeof(b)/sizeof(int);i++)
printf("%d ",b[i]);
printf("&a=0x%p",b);
}
然后,我想到了数组内存地址!
我们知道同一个数组内的变量a[0] a[1]等等的地址是连续的!
那么,两个数组间的地址呢?
运行上述代码后:
!!!
a的地址是62fe30
而b的地址是62fe20
相差十六进制的10也就是十进制的16
而int的size是4
通过简单的几何学计算可以得知
b[2]的地址是62fe28
和a[0]的地址十分接近!
那么,当b数组溢出时,是不是就到了a数组里?!
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},m,b[3]={1,2,3},i=4;
printf("a=0x%p\nb=0x%p\nb[2]=0x%p\nb[3]=0x%p\nb[4]=0x%p\ni=0x%p\n",a,b,&b[2],&b[3],&b[4],&i);
printf("%d\n",b[4]);
for (i=0;i<sizeof(a)/sizeof(int);i++)
printf("%d ",a[i]);
printf("\n");
b[4]=a[4];
for (i=0;i<sizeof(a)/sizeof(int);i++)
printf("%d ",a[i]);
}
结果显示,此时的b[4]和a[0] 的地址是一样的!
而进行了b[4]=a[4]的操作后
a[0]变成了5(也就是a[4])
数组名就是指针,这就使得结果很明显了
当a指针与b指针同时指向了一个内存空间(a[0])时
我们对b指针所指值做了修改
自然也使得a所指值发生了变化
而这,也使得我上述所谓的赋值时右值改变的情况出现
总而言之
算了,懒得写了,反正又是一次乌龙
计算机真是个令人头秃的东西
不过...
我还发现了一个更邪恶的事情...
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},m,b[3]={1,2,3},i=4;
printf("a=0x%p\nb=0x%p\nb[2]=0x%p\nb[3]=0x%p\nm=0x%p\n",a,b,&b[2],&b[3],&m);
printf("%d %d",m,b[3]);
}
变量m和b[3]的值一样!地址一样!
好吧,大惊小怪就是我了
有缘再见(应该是无缘了)
祝大家元旦快乐~