C 理解指针

C 理解指针,c,pointers,C,Pointers,所以我有下面的代码,我试图理解指针的基本知识,所以我想更改first中的值/字符串,同时使用second保留它 问题是,无论输入是什么,函数都将打印0,然后打印1(值i) 然后崩溃。我可以清楚地看到它与循环有关,但我不明白为什么 有谁能向我解释为什么会发生这种情况,以及我如何避免这种情况 #include <stdio.h> #include <string.h> void spells( char **str ){ int i = 0, len = strle

所以我有下面的代码,我试图理解指针的基本知识,所以我想更改
first
中的值/字符串,同时使用
second
保留它

问题是,无论输入是什么,函数都将打印
0
,然后打印
1
(值
i
) 然后崩溃。我可以清楚地看到它与循环有关,但我不明白为什么

有谁能向我解释为什么会发生这种情况,以及我如何避免这种情况

#include <stdio.h>
#include <string.h>

void spells( char **str ){
    int i = 0, len = strlen(*str);
    while( i < len ){
        printf("%d\n",i); //just to check 
        if( ( (int)*str[i] )%3 == 0 ){// if the ascii value is divided by 3
            *str[i] = '#';
        }
        i++;
    } puts("done");
}
int main(){
    char first[20];
    char* second = &first;
    scanf("%s", first);
    spells( &second );
    printf("%s", second);
    printf("\n%s", first);
    return 0;
}
#包括
#包括
虚空法术(字符**str){
int i=0,len=strlen(*str);
而(我
尝试执行以下操作: (这是一个优先级问题。提示:如果您在该函数中执行了
str[1]
,那么它的值应该是什么?)

但您并没有以这种方式保留任何内容,因为您仍然在通过
拼写
函数修改main:
char first[20]
中创建的字符串实例


如果要保留任何内容,请复制字符串并对其进行操作

不要使事情复杂化-这里您是在使事情复杂化(通过访问数组索引超出范围的方式,然后在调用的函数中出现seg错误)

简单的做事方法

 char* second = first;
数组衰减为指向第一个元素的指针。然后用同样的逻辑你做一件事

spells( second );
然后

void spells( char *str ){
    size_t i = 0, len = strlen(str);
    while( i < len ){
        printf("%zu\n",i); //just to check 
        if( str[i] % 3 == 0 ){// if the ascii value is divided by 3
             str[i] = '#';
        }
        i++;
    } 
    puts("done");
}
避免缓冲区溢出,同时检查输入是否成功


要明确的是,我之前的编辑没有解释这个问题。更明确地说,指针有两个方面——它的值和类型。第二个命令指示所有指针算法

这里,当我说递增
str
将超出
80
字节的限制时,只有将相关类型信息传递给函数时,该限制才为真。差不多

spells(&first)

但是在这里,我们没有传递这些信息,而是将
char(*)[20]
的值分配给
char*
(当然是编译器抱怨的),并开始使用
char**

现在当我说

str+i
    
实际上我们搬家了

str+ i*sizeof(str)
更清楚

str+ i*sizeof(char**)
在您的例子中,这个
str
最初包含一个
char*
的任意地址,它与地址没有直接关系。添加后它指向的内存位置与您无关,您无权访问该内存


使用
(*str)
现在可以获得数组基的地址。然后索引到它。这是正确的做法,不会造成任何非法的内存访问。

嗨,你能解释一下他为什么要这样做以及答案背后的逻辑吗?谢谢。你用双指针把事情弄得太复杂了。一个简单的
char*
就足够了。如果要保留原始值,则需要复制整个数组内容,仅添加另一个指向它的指针是不够的。@Matso这不是问题,因为它是&first[0]的别名<代码>字符*second=&first也是错误的,你的编译器没有抱怨吗?!必须是
char*second=first
&first
是指向20个字符数组的指针,而不是指向一个字符的指针。那么哪一个是真的?
&first
是否是
&first[0]
的别名,因为我很困惑?我一直在想它不是…你为什么在这里贴标签?
str+i
    
str+ i*sizeof(str)
str+ i*sizeof(char**)