关于数组存在偏移量的地址和指针的地址

圣诞节写的一道题,发现一个之前没注意过的知识点,有关在向函数传指针同时在函数体里面把指针当初数组用发现的地址不相同的一个问题。

6-2【拓展函数题】 删除字符 (20分)

本题要求实现一个删除字符串中的指定字符的简单函数。

函数接口定义:

void delchar( char *str, char c ); 其中char
*str是传入的字符串,c是待删除的字符。函数delchar的功能是将字符串str中出现的所有c字符删除。

裁判测试程序样例:

#include <stdio.h>
#define MAXN 20

void delchar( char *str, char c );
void ReadString( char s[] ); /* 由裁判实现,略去不表 */

int main()
{
    char str[MAXN], c;

    scanf("%c\n", &c);
    ReadString(str);
    delchar(str, c);
    printf("%s\n", str);

    return 0;
}

输入样例: a happy new year
输出样例: hppy new yer

(以下是一个丑丑的代码)

#include <stdio.h>
#define MAXN 20
#include<string.h>
void delchar(char* str, char c)
{
    char p[200];
    int i = 0;
    char* str2 = str;
    printf("str=%p\n", str);
    while (*str2!='\0')
    {
        if (*str2 != c) p[i++] = *str2;
        str2++;
    }
    p[i] = '\0';
    int n = strlen(p);
    int j;
    for (j = 0; j < n; j++)
    {
        *str = p[j];
        str++;
    }
    printf("str[0]=%p\n", &str[0]);
    printf("*str=%p\n", str);
 
    printf("str[n]=%p\n", &str[n]);//和str[j]一样
    
    printf("*(str-1)=%p\n", (str - 1));
    printf("str[j-1]=%p\n", &str[j - 1]);
    *str = '\0';
    //最开始这里写的是str[n]='\0'然后输出就变成了
    //hppy new yerar(多了两个)
    //现在知道str[n]指向的地址与str(变换后)的并不一样
    // 所以在这里加'\0'并不能截至住传入的字符串*str

}
int main()
{
    char str[MAXN], c;

    scanf("%c\n", &c);
    gets_s(str);
    delchar(str, c);
    printf("%s\n", str);

    return 0;
}

这个是有关地址部分的输出:
str=0135FBC4 //str的地址和下面的str还有str[n]的地址竟然也不一样

  1. 主函数运行函数体后str的地址是一样的
    2.在函数题里面str++和str2++再输出字符串%s首字母会相应后移 但这并不表示主函数str的地址变了。
    3.函数题str和str2的地址一一相等

str[0]=0135FBD0
*str=0135FBD0

str[n]=str[j]=0135FBDC//这个和上面那个地址也不一样

str[j-1]=0052FAAF
*(str-1)=0052FAA3//这两个地址竟然不一样

str是首地址,&str[n]是有偏移量的地址
偏移量的了解1
数组地址偏移量了解2

*str等价于str[0]
str[i]中括号的意思是
让这个指针加上里面的下标 i 乘以元素字节数字 sizeof
然后访问那个地方的元素

——————————————————————

下面这个忽略 是一段调试的代码

#include <stdio.h>
#define MAXN 20
#include<string.h>
void delchar(char* str, char c)
{
    char p[200];
    int i = 0;
    char* str2 = str;
    printf("*str=%p\n", str);
    printf("*str2=%p\n\n", str2);
    while (*str2!='\0')
    {
        if (*str2 != c) p[i++] = *str2;
        str2++;
       /* printf("*str=%p\n", str);
        printf("*str2=%p\n", str2);
        printf("%s\n", str);
        printf("%s\n\n", str2);*/
    }
    p[i] = '\0';
    int n = strlen(p);
    int j;
    for (j = 0; j < n; j++)
    {
       // printf("*str=%p\n", str);
        *str = p[j];
        str++;
        printf("%s\n", str);
        printf("*str=%p\n", str);
        printf("*str2=%p\n", str2);
    }
    //printf("str[0]=%p\n", &str[0]);
    //printf("*str=%p\n", str);

    //printf("str[n]=%p\n", &str[n]);//和str[j]一样

    //printf("*(str-1)=%p\n", (str - 1));
    //printf("str[j-1]=%p\n", &str[j - 1]);
    *str = '\0';
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值