1

皆さん、

私はポインターとポインティーについていくつか読んでいて、興味を持ち始めました。私が理解していない唯一のことは、ポインターが関数でどのように動作するかです。したがって、次のコードです。

#include <stdio.h>

int pointeeChanger(char* writeLocation) {

    writeLocation = "something";
    return 0;
}

int main(void)
{

    char crypted[] = "nothing";
    char* cryptedPointer = crypted;

    pointeeChanger(cryptedPointer);

    printf("The new value is: %s", cryptedPointer);

    return 0;
}

私の意図は、関数に与えられたポインターを介して、「暗号化された」var を調整することです。唯一のことは、それが機能していないということです。私の思考過程で何がうまくいかないのか説明していただけませんか。私は C にかなり慣れていないので、エラーはかなり基本的なものになる可能性があります。

前もって感謝します!

ご挨拶、

キプト・スクリディ

4

4 に答える 4

4

C 文字列は へのポインターとして実装されているため、ポインターを学習するのに最適な素材ではありませんcharint代わりに使用しましょう:

#include <stdio.h>

void pointeeChanger(int* writeLocation) {
    // Using dereference operator "*"
    *writeLocation = 42; // something
}

int main(void) {
    int crypted = 0; // Nothing
    pointeeChanger(&cryptedPointer); // Taking an address with "&"
    printf("The new value is: %d", crypted);
    return 0;
}

これは期待どおりに機能します。

メモリ管理の問題に対処しなければならないため、文字列をその場で変更するのは非常に困難です。具体的には、コピー先の文字列には、新しい文字列が収まる十分なスペースが割り当てられている必要があります。これは、"nothing" と "something" では機能しません。これは、置換が 2 文字長くなるためです。

于 2013-02-12T01:45:11.687 に答える
3

簡単な答え:writeLocationはローカル変数であり、のコピーですcryptedPointer。を変更してもwriteLocationcryptedPointerは変更されません。

を変更したい場合はcryptedPointer、次のようにポインターを渡す必要があります。

#include <stdio.h>

int pointeeChanger(char** writeLocation) {            /* Note: char** */

    *writeLocation = "something";                     /* Note: *writeLocation */
    return 0;
}

int main(void)
{

    char crypted[] = "nothing";
    char* cryptedPointer = crypted;

    pointeeChanger(&cryptedPointer);                  /* Note: &cryptedPointer */

    printf("The new value is: %s", cryptedPointer);

    return 0;
}

ただし、このコードには他にも問題があります。への呼び出し後、pointeeChanger()cryptedPointerもはやcrypted配列を指しません。あなたは実際にその配列の内容を変更したかったのではないかと思います。このコードではそれができません。

あなたの値を変更するには、または(できれば)crypted[]を使用する必要があります。また、配列のサイズを監視する必要があります-はより長く、大きくしない限りバッファ オーバーフローが発生します。strcpy()strncpy()crypted[]"something""nothing"crypted[]

このコードは、元のcrypted[]配列を変更します。

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

#define MAX_STR_LEN 64

/*
 * Only char* required because we are not modifying the
 * original pointer passed in - we are modifying what it
 * points to.
 */
int pointeeChanger(char* writeLocation)
{
    /*
     * In C, you need to use a function like strcpy or strncpy to overwrite a
     * string with another string. Prefer strncpy because it allows you to
     * specify a maximum size to copy, which helps to prevent buffer overruns.
     */
    strncpy(writeLocation, "something", MAX_STR_LEN);

    /* strncpy doesn't automatically add a \0 */
    writeLocation[MAX_STR_LEN] = '\0';

    return 0;
}


int main(void)
{
    /*
     * The +1 is because an extra character is required for the 
     * null terminator ('\0')
     */
    char crypted[MAX_STR_LEN + 1] = "nothing";

    pointeeChanger(crypted);

    printf("The new value is: %s", crypted);

    return 0;

}
于 2013-02-12T01:39:39.087 に答える
2

実際に何をしたいかによって少し異なります。

指している対象を変更しますかcryptedPointer、それとも指しているコンテンツを変更cryptedPointerしますか?

2番目は次の方法で実行できます。

  strcpy(writeLocation, "something"); 

somethingが元の文字列のサイズよりも長い場合、バッファがオーバーフローすることに注意してください。これは悪いことです。したがって、これを修正するにはchar crypted[10] = "nothing";、文字列「something」用のスペースを確保するために が必要です。

次のようなことも明らかにできます。

 writeLocation[2] = 'f';
 writeLocation[3] = 'f';

printfそして、 「ノフィング」という印刷物を持っています

ただし、最初のバリアントを実行する場合は、ポインターにポインターを渡す必要があります。

int pointeeChanger(char** writeLocation) {

    *writeLocation = "something";
    return 0;
}

そして、次のように呼び出します。

pointeeChanger(&cryptedPointer); 

これが戻ったとき、cruptedPointer変更できない定数文字列を指していることに注意してください。ここで、元の文字列を変更cryptedできます。

于 2013-02-12T01:45:06.623 に答える