C++中变量声明顺序的不同导致不同的运行效果嘛?

输入移动位数n,然后接受用户输入的四个字符,每个字符向后移动n位实现凯撒密码加密。

例如,输入n为3,再输入abcd,输出defg。只考虑小写字母的情况下,部分代码如下:

    int n;
    char c[4];
   
    cin>>n;
    cin>>c;
    
    for(int i=0;i<4;i++)
    {
      printf("%c",(c[i]+n-97)%26+97);
    }

当代码运行后发现输入:

3
abcd

输出的内容依然是:

abcd

更好玩的事情是,当把源代码中声明变量的顺序调整一下,情况就发生了变化:

char c[4];    
int n;
    
cin>>n;
cin>>c;
for(int i=0;i<4;i++)
{
   printf("%c",(c[i]+n-97)%26+97);
}

运行程序,输入:

3
abcd

输出的内容就变为:

defg

这个代码在不同的机器上应该有不同的运行效果,但是在我的机器上确实发生了这个好玩的情况。存在即合理,到底发生了什么呢?

其实打印一下变量n和c的地址就知道事情的真相了:

int n;
char c[4];

cout<<&n<<endl;
cout<<&numbers<<endl;

cin>>n;
cin>>c;

n和c的地址分别是:

0x28fef8
0x28fef4

可以看见恰好数组c和变量n的内存地址居然是挨在一起的。

当执行到cin>>n的时候,输入3,在0x26fef8中存入数字3。

回车后执行cin>>c,输入abcd。因为c是数组的名称,所以cin会认为输入的abcd是一个字符串,于是编译器会自动在abcd后面补上一个NULL符,NULL符的ASCII码值为0,一般写作'\0'。所以接下来发生的事情就是:

C++把0当做写入输入在第五个元素即c[4],所以它的写入位置就是数组首地址(即a[0]的地址)偏移4位,这个地址恰好是变量n的地址,所以0被写入到了变量n中。

后续在做字符变化的时候,所有的字符都是与0在做加法运算,因此字符没有产生任何变化。

当交换了变量的声明顺序后,数组c和变量n的地址发生了变化:

char c[4];
int n;

cout<<&n<<endl;
cout<<&c<<endl;

cin>>n;
cin>>c;

此时n和c的地址如下:

0x28fef4
0x28fef8

于是再输入n和abcd的时候内存变为了如下形式:

此时从内存上看,程序中需要的变量n和c[0]c[1]c[2]c[3]都有需要的值,因此程序产生了效果。但是要注意数组依然影响了“无辜的”内存地址0x28fefc。 

所以,如果以字符串的形式进行字符数组内容的初始化,必须要让数组的长度至少比字符串字面内容多1位,用来存储编译器添加的NULL结束字符,防止影响到“无辜的”内存空间,造成意想不到的错误。

int n;
char c[5];

//cout<<&n<<endl;
//cout<<&c<<endl;

cin>>n;
cin>>c;
for(int i=0;i<4;i++)
{
    printf("%c",(c[i]+n-97)%26+97);
}

 

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值