如何更改指针变量的值并将更改保留在函数之外而无需通过引用传递?

Posted

技术标签:

【中文标题】如何更改指针变量的值并将更改保留在函数之外而无需通过引用传递?【英文标题】:How do I change a pointer variable's value and keep the changes outside of a function without pass-by-reference? 【发布时间】:2019-02-11 08:21:40 【问题描述】:

我正在为一个编写 C 字符串编辑函数的类做一个项目。我必须编写的函数中有 3/5 改变了我必须使用的 char 数组的大小,并且它们是通过 ifstream 输入读取的。这是程序:

#include <iostream>
#include <fstream>

using namespace std;

void stringCopy(char *A, char *B);
bool stringCompare(char *A, char *B);
void stringConcatenation(char *A, char *B);    //added const to make sure b is never changed
int stringPosition(char *A, char B);
int stringLength(char *A);
//-------------------MY-FUNCTIONS----------------------
int cStringLen(const char*);  //finds string length, but doesn't account for null char
void reSize(char*&, int len, int newLen);
void input(char*& A, istream& is);
void printMessage(const char* word1, const char* word2, const char* message);

int main()

    ifstream ifs"input.txt";
    ofstream ofs"output.txt";
    char* word1 = "";
    char* word2 = "";

    input(word1, ifs);
    input(word2, ifs);
    printMessage(word1, word2, "stringCopy()");
    stringCopy(word1, word2);
    printMessage(word1, word2, "after stringCopy()");
    cout << endl;

    input(word1, ifs);
    input(word2, ifs);
    printMessage(word1, word2, "stringCompare()");
    if(stringCompare(word1, word2))
    
        cout << "They match!" << endl;
    
    else
    
        cout << "They don't match!" << endl;
    
    stringCopy(word1, word2);
    printMessage(word1, word2, "comparing after stringCopy()");
    if(stringCompare(word1, word2))
    
        cout << "They match!" << endl;
    
    else
    
        cout << "They don't match!" << endl;
    
    cout << endl;

    input(word1, ifs);
    input(word2, ifs);
    printMessage(word1, word2, "stringConcatenation()");
    stringConcatenation(word1, word2);
    printMessage(word1, word2, "after stringConcatenation()");
    cout << endl;

    input(word1, ifs);
    input(word2, ifs);
    printMessage(word1, word2, "stringPosition()");
    cout << "Searching for 'm' in word1..." << endl << "position returned is: " << stringPosition(word1, 'm') << endl;
    cout << "Searching for 'n' in word2..." << endl << "position returned is: " << stringPosition(word2, 'n') << endl;
    cout << endl;

    input(word1, ifs);
    cout << "stringLength()" << endl;
    cout << "word1: " << word1 << endl;
    cout << "The length of word1 is: " << stringLength(word1) << endl;
    cout << "after stringLength()" << endl;
    cout << "word1: " << word1 << endl;

    return 0;


void stringCopy(char *A, char *B)

    ///GETTING THE SIZES OF BOTH ARRAYS
    int counterA = cStringLen(A) + 1;
    int counterB = cStringLen(B) + 1;
    ///MAKES SURE BOTH ARE THE SAME SIZE BEFORE COPYING
    if(counterA < counterB)
    
        reSize(A, counterA, counterB);
    
    else
    
        reSize(A, counterB, counterA);
    
    ///THE COPY
    for(int i = 0; i < counterB; i++) *(A + i) = *(B + i);  //each character is copied to A from B


bool stringCompare(char *A, char *B)

    ///getting length of one string
    int counter = cStringLen(A);
    ///will move through string until diff char found
    for(int i = 0; i < counter + 1; i++)
    
        if(*(A + i) != *(B + i))
        
            return false;
        
    
    return true;


void stringConcatenation(char *A, char *B)    //added const to make sure b is never changed

    ///getting length of both strings
    int counterA = cStringLen(A)+1;
    int counterB = cStringLen(B)+1;
    ///putting the length of both together for new string
    const int COUNTERS = counterA + counterB - 1;
    ///making A the size of both strings - 1
    reSize(A, counterA, COUNTERS);
    ///copying b to the parts of a past the original
    for(int i = 0; i < counterB; i++)
    
        *(A + (counterA - 1) + i) = *(B + i);   //will override the '/0' char of A
    


int stringPosition(char *A, char B)

    int counter = cStringLen(A) + 1;
    ///searching through string for char
    for(int i = 0; i < counter; i++)
    
        if(*(A + i) == B)
        
            return i;   //found!
        
    
    ///checking if b == '\0' and a '\0' isn't found somewhere before last spot of A
    if(B == '\0')
    
        return counter;
    
    return -1;  //not found


int stringLength(char *A)

    int counter = cStringLen(A) + 1;
    char* car = new char[counter + 1];
    for(int i = 0; i < counter; i++)
    
        *(car + 1 + i) = *(A + i);
    
    *(car + 0) = counter;
    delete[] A;
    A = car;
    /**
    * Will take string as param.

    * Shifts all characters to the right by one and store the length of the string in position 0.
        - Length doesn't include position 0.
    */
    return counter;   //temp


//-----------------------------------------MY FUNCTIONS---------------------------------------------------------------------------
int cStringLen(const char* A) //finds string length, but doesn't account for null char

    int counter = 0;
    while(*(A + counter) != '\0')
    
        counter++;
    
    return counter;


void reSize(char*& A, int len, int newLen)

    char* car = new char[newLen];
    for(int i = 0; i < newLen; i++)
    
        if(i < len)
        
            *(car + i) = *(A + i);
        
        else if(i >= len && i < newLen)
        
            *(car + i) = '\0';
        
    
    delete[] A;
    A = car;


void input(char*& A, istream& is)

    int wordSize = 0;
    int arrSize = 1;
    char c = 'o';   //checking char
    char* car = new char[arrSize];
    while((!(is.eof())) && (c != ' ' && c != '\t' && c != '\n'))
    
        is.unsetf(ios_base::skipws);
        is >> c;

        if(is.eof())
        
            delete[] A;
            A = car;
            return;
        
        if(c != ' ' && c != '\t' && c != '\n')
        
            if(wordSize == arrSize)
            
                reSize(car, arrSize, arrSize * 2);
            
            *(car + wordSize) = c;
        
        wordSize++;
    
    is.setf(ios_base::skipws);
    delete[] A;
    A = car;


void printMessage(const char* word1, const char* word2, const char* message)

    cout << message << endl;
    cout << "word1: " << word1 << endl << "word2: " << word2 << endl;

我以为我把这一切都做好了。请记住,我已经在每个指针参数之后添加了“&”运算符。这是他们以前的样子:

void stringCopy(char *&A, char *B);
bool stringCompare(char *A, char *B);
void stringConcatenation(char *&A, char *B);    //added const to make sure b 
is never changed
int stringPosition(char *A, char B);
int stringLength(char *&A);

但是,当我上课时,我的老师说我们不允许以任何方式更改函数头。所以,我被困在通过价值传递分配。问题是我现在无法在编辑功能之外更改 c 字符串。我对他们所做的任何更改都留在里面。

一切都编译得很好,而且,如果我让指针通过引用传递,程序可以完美运行。我只是想知道如何在编辑功能之外更改 c 字符串的值。这项任务开始变得很痛苦(这么多他妈的限制)。

【问题讨论】:

【参考方案1】:

我认为你的老师希望你做的是改变字符指针的值而不是创建一个新的字符串。

因此,尝试将参数A 重新分配给新的char*,而是更改A 在内存中指向的值。这样,调用您的函数的方法仍然指向相同的内存,并且当他们访问该位置时,将获取您在函数中更改的值。

【讨论】:

以上是关于如何更改指针变量的值并将更改保留在函数之外而无需通过引用传递?的主要内容,如果未能解决你的问题,请参考以下文章

如何理解函数中的指针

相同的变量名,但在两个单独的“ def”函数中具有不同的值。他们不能以某种方式更改代码吗?

如何在 ms access 中更改表字段的数据类型,而无需创建新表单来更新表?

为啥你可以在函数中使用另一种方法而不是赋值运算符来更改 Ruby 中局部变量的值?

根据一维数组中的值更改二维numpy数组中的某些值而无需for循环

static和const变量有什么区别?