1

我正在处理的函数需要两个字符串作为输入(以及一些其他参数),并在输出时返回两个不同的字符串。我认为最合乎逻辑的方法是int为错误返回一个并有两个​​指向 C 字符串的指针作为参数。我就是这样做的:

int annealc(const char *sequence1, const char *sequence2, float startTemp, float endTemp, float tempStep, int cycles, char *retVal1, char *retVal2, int *score)
{
    ...
    retVal1 = malloc(MAX(len1, len2));
    retVal2 = malloc(MAX(len1, len2));
    ...
    strcpy(retVal1, sequence1);
    strcpy(retVal2, sequence2);
    ...
    //Somewhere along the line retVal is exchanged for another string
    free(retVal1);
    free(retVal2);
    retVal1 = currentSeq1;
    retVal2 = currentSeq2;
    ...
    *score = bestScore;

    return 0;
}

//Intended use:
int error = annealc(content1, content2,
                    30, 5, 1, 5,
                    alignment1, alignment2, &score);

我认为我没有正确使用指针的语法,因为当函数返回时,alignment1or中都没有值alignment2。那么,我做错了什么?

谢谢你的帮助!

4

1 回答 1

3

你是对的,你没有使用正确的参数类型。您希望您在函数中设置的指针并期望在返回后具有值作为指向指针的指针。

就像是。

int annealc
(
    const char *sequence1, 
    const char *sequence2, 
    float startTemp, 
    float endTemp, 
    float tempStep, 
    int cycles, 
    char **retVal1,
    char **retVal2, 
    int *score
)
{
    ...
    *retVal1 = malloc(MAX(len1, len2));
    *retVal2 = malloc(MAX(len1, len2));
    ...
    strcpy(*retVal1, sequence1);
    strcpy(*retVal2, sequence2);
    ...
    //Somewhere along the line retVal is exchanged for another string
    free(*retVal1);
    free(*retVal2);
    *retVal1 = currentSeq1;
    *retVal2 = currentSeq2;
    ...
    *score = bestScore;

    return 0;
}

//Intended use:
int error = annealc(content1, content2,
                    30, 5, 1, 5,
                    &alignment1, &alignment2, &score);

原因是在您的版本中,参数 retVal1 和 retVal2 仅作为 char 指针键入。这意味着这些变量只保存一个地址值,可以通过使用 *retVal1 或 *retVal2 检查或修改该地址处的字符来取消引用该值。

现在,当您将它们键入为指向指针的指针时,它们会引用对某个其他指针的地址的引用。取消引用指向指针的指针允许您检查或修改其他指针引用的地址。

下面的例子最好地说明了这一点:

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

void sample1(char *inner) 
{
    printf("IN SAMPLE1 BEFORE MALLOC: Address of inner is %p\n", &inner);
    printf("IN SAMPLE1 BEFORE MALLOC: Address held by inner is %p\n", inner);
    printf("IN SAMPLE1 BEFORE MALLOC: The char referenced by inner is %c\n", *inner);

    inner = (char *)malloc(4);
    strcpy(inner, "WXYZ");

    printf("IN SAMPLE1 AFTER MALLOC: Address of inner is %p\n", &inner);
    printf("IN SAMPLE1 AFTER MALLOC: Address held by inner is %p\n", inner);
    printf("IN SAMPLE1 AFTER MALLOC: The char referenced by inner is %c\n\n", *inner);
}

void sample2(char **inner) 
{
    printf("IN SAMPLE2 BEFORE MALLOC: Address of inner is %p\n", &inner);
    printf("IN SAMPLE2 BEFORE MALLOC: Address of the pointer held by inner is %p\n", inner);
    printf("IN SAMPLE2 BEFORE MALLOC: Address of the char referenced by the address held by inner is %p\n", *inner);
    printf("IN SAMPLE2 BEFORE MALLOC: The char referenced by the address held by inner is %c\n\n", **inner);

    *inner = (char *)malloc(sizeof(char));
    **inner = 'W';

    printf("IN SAMPLE2 AFTER MALLOC: Address of inner is %p\n", &inner);
    printf("IN SAMPLE2 AFTER MALLOC: Address of the pointer held by inner is %p\n", inner);
    printf("IN SAMPLE2 AFTER MALLOC: Address of the char referenced by the address held by inner is %p\n", *inner);
    printf("IN SAMPLE2 AFTER MALLOC: The char referenced by the address held by inner is %c\n\n", **inner);
}



int main(int argc, char *argv[])
{
    char myChar = 'A';
    char *outer = &myChar;

    printf("Addres of myChar is %p\n\n", &myChar);

    printf("BEFORE sample1: Address of outer is %p\t\t\t\t\t\tThis is where the variable 'outer' resides in memory.\n", &outer);
    printf("BEFORE sample1: Address of the char held by outer is %p\t\t\t\tThis matches the address of 'myChar' because that is what we set 'outer' to.\n", outer);
    printf("BEFORE sample1: The char referenced by the address held by outer is %c\t\t\tThis is the same as the value held by 'myChar'.\n\n", *outer);

    sample1(outer);

    printf("AFTER sample1: Address of outer is %p\t\t\t\t\t\tThe variable 'outer' is unaffected by the call to sample1.\n", &outer);
    printf("AFTER sample1: Address of the char held by outer is %p\n", outer);
    printf("AFTER sample1: The char referenced by outer is %c\n\n\n", *outer);

    printf("BEFORE sample2: Address of outer is %p\t\t\t\t\t\tThis is all the same as before sample1 since 'outer' was not affected.\n", &outer);
    printf("BEFORE sample2: Address of the char held by outer is %p\n", outer);
    printf("BEFORE sample2: The char referenced by the address held by outer is %c.\n\n", *outer);

    printf("BEFORE sample2: Address of outer is %p\n", &outer);
    printf("BEFORE sample2: Address referenced by outer is %p\n", outer);
    printf("BEFORE sample2: The char referenced by the address held by outer is %c\n\n", *outer);

    sample2(&outer);

    printf("AFTER sample2: Address of outer is %p\t\t\t\t\t\tThe variable 'outer' still resides in the same place in memory; this didn't change.\n", &outer);
    printf("AFTER sample2: Address referenced by outer is %p\t\t\t\t\tThe address held by 'outer' now matches what was assigned inside the call to sample2.\n", outer);
    printf("AFTER sample2: The char referenced by the address held by outer is %c\t\t\t...as well as now references the character 'W' which was stored in the memory allocated inside the call to sample2.\n", *outer);

    return 0;
}

/*
Example Output:

Addres of myChar is 002EFD33

BEFORE sample1: Address of outer is 002EFD24                                            This is where the variable 'outer' resides in memory.
BEFORE sample1: Address of the char held by outer is 002EFD33                           This matches the address of 'myChar' because that is what we set 'outer' to.
BEFORE sample1: The char referenced by the address held by outer is A                   This is the same as the value held by 'myChar'.

IN SAMPLE1 BEFORE MALLOC: Address of inner is 002EFC50
IN SAMPLE1 BEFORE MALLOC: Address held by inner is 002EFD33
IN SAMPLE1 BEFORE MALLOC: The char referenced by inner is A
IN SAMPLE1 AFTER MALLOC: Address of inner is 002EFC50
IN SAMPLE1 AFTER MALLOC: Address held by inner is 0075B0F8
IN SAMPLE1 AFTER MALLOC: The char referenced by inner is W

AFTER sample1: Address of outer is 002EFD24                                             The variable 'outer' is unaffected by the call to sample1.
AFTER sample1: Address of the char held by outer is 002EFD33
AFTER sample1: The char referenced by outer is A


BEFORE sample2: Address of outer is 002EFD24                                            This is all the same as before sample1 since 'outer' was not affected.
BEFORE sample2: Address of the char held by outer is 002EFD33
BEFORE sample2: The char referenced by the address held by outer is A.

BEFORE sample2: Address of outer is 002EFD24
BEFORE sample2: Address referenced by outer is 002EFD33
BEFORE sample2: The char referenced by the address held by outer is A

IN SAMPLE2 BEFORE MALLOC: Address of inner is 002EFC50
IN SAMPLE2 BEFORE MALLOC: Address of the pointer held by inner is 002EFD24
IN SAMPLE2 BEFORE MALLOC: Address of the char referenced by the address held by inner is 002EFD33
IN SAMPLE2 BEFORE MALLOC: The char referenced by the address held by inner is A

IN SAMPLE2 AFTER MALLOC: Address of inner is 002EFC50
IN SAMPLE2 AFTER MALLOC: Address of the pointer held by inner is 002EFD24
IN SAMPLE2 AFTER MALLOC: Address of the char referenced by the address held by inner is 0075B128
IN SAMPLE2 AFTER MALLOC: The char referenced by the address held by inner is W

AFTER sample2: Address of outer is 002EFD24                                             The variable 'outer' still resides in the same place in memory; this didn't change.
AFTER sample2: Address referenced by outer is 0075B128                                  The address held by 'outer' now matches what was assigned inside the call to sample2.
AFTER sample2: The char referenced by the address held by outer is W                    ...as well as now references the character 'W' which was stored in the memory allocated inside the call to sample2.

*/
于 2013-09-28T04:39:33.140 回答