Return hai giá trị trong một hàm C/C++

Chào mọi người mình đang làm một chương trình C++
Trong đó mình viết cho nó một cái hàm sẽ trả về hai giá trị
Nhưng mà trong C++ nó lại không dễ trả về hai giá trị bạn nào biết làm không chỉ mình với
Mình có tìm trên mạng thấy nó có ghi là dùng thư viện tuple nhưng mà mình lại ko biết dùng

Chào bạn, về vấn đề của bạn thì mình nghĩ kiểu dữ liệu struct là phù hợp nhất
Về cơ bản Struct là một kiểu dữ liệu bao gồm nhiều thành phần có thể thuộc nhiều kiểu dữ liệu khác nhau. Các thành phần được truy nhập thông qua một tên.
Lúc return bạn chỉ cần return tên của struct
Để tìm hiểu rõ hơn bạn có thể đọc qua ở đây:
https://www.stdio.vn/articles/read/166/struct-va-union

1 Like

Mình nghĩ nên truyền gửi vào 2 parameters, xong rồi gán giá trị cho 2 parameters đó là được. Gọi là truyền tham chiếu ấy :smiley: hope it help :3

dùng đơn giản thôi, #include <tuple> rồi xài, nhớ bật std=c++14

#include <iostream>
#include <tuple>
#include <string>

auto func()
{
    std::string s = "hi";
    int n = 10;
    float f = 10.9;
    return std::make_tuple(s, n, f);
}

int main()
{
    std::string s;
    int n;
    float f;
    
    std::tie(s, n, f) = func();
    
    std::cout << s << " " << n << " " << f << "\n";
}
  • trong hàm func() để kiểu trả về là auto (C++14) hoặc std::tuple<std::string, int, float> (C++11). Để auto cho khỏe.
  • xài std::make_tuple(...) để “đóng gói” các giá trị lại thành 1 tuple.
  • xài std::tie(...) để lấy từng giá trị trong tuple ra.

C++17 hứa hẹn cho viết dễ hơn nữa: xài auto[...] để lấy giá trị, và chẳng cần nhớ nó trả về kiểu giá trị gì. (vd ở đây chẳng cần nhớ s, n, f kiểu giá trị là gì)

#include <iostream>
#include <tuple>

auto func()
{
    std::string s = "hi";
    int n = 10;
    float f = 10.9;
    return std::make_tuple(s, n, f);
}

int main()
{
    auto[s, n, f] = func();
    std::cout << s << " " << n << " " << f << "\n";
}

trước C++11 thì phải tạo định nghĩa 1 kiểu struct rồi trả về struct này. Hoặc có thể truyền tham chiếu vào hàm cần trả về nhiều giá trị.

5 Likes

Yeah mình cũng thử dùng đến struct và cuối cùng nó cũng hoạt động được cám ơn bạn

3 Likes

cho em hỏi bật std=c++14 ở đâu ạ

Option đó của g++. Bạn dùng VS?

Thực ra hai trị thì dùng std::pair được rồi, std::tuple đến C++11 mới có và nó là trường hợp tổng quát. Không nên dùng makeshift struct mà chỉ nên viết thẳng vào prototype.

1 Like

tùy vào bạn đang dùng compiler gì, gu gồ tìm cách bật C++14 cho compiler đó là lẹ nhất :joy:

1 Like

À tại em tưởng đâu dùng dòng lệnh luôn ạ :v nếu em xài bên g++ thì làm sao ạ?

1 Like

Bạn thêm tham số -std=c++14 vào sau cách gọi g++ bt của bạn.

  • Từ 4.8 mới hỗ trợ đầy đủ chuẩn C++11.
  • Từ 5.x trở đi hỗ trợ “sơ sơ” một phần chuẩn C++14. (tham số -std=c++1x)
  • Từ 5.2 trở đi hỗ trợ C++14 qua tham số -std=c++14.
1 Like

Mình ngày trc code C++ thỉnh thoảng cũng muốn trả về hơn 2 giá trị mà k biết làm thế nào …
Thế là nghĩ ra việc dùng mảng với con trỏ …
Bằng cách gán các giá trị cần trả vào 1 mảng nào đó .Sau khi kết thúc hàm thì trả về cái mảng ấy(Dùng con trỏ ) ! Rồi sau đó sử dụng ở main !
Giờ mình mới biết đến tuple .Căn bản sách dạy C++ của mềnh k có nên cũng k biết :joy:

1 Like

Sao mọi người nghĩ phức tạp vậy nhỉ. Trả về 1 array, object hoặc 1 string cũng được mà.

@Kulteam viết như vậy không bảo trì được.
@^: như trên.

1 Like

Bạn có thể chỉ ra cái khó ở đây không :slight_smile:

1 Like

vd trả về 3 kiểu khác nhau thì sao? Trả về {string, int, float} thì đâu có xài mảng được. Trả về string rồi phải parse string này thành {string,int,float} thì bó tay.com :joy: Trả về object chứa string, int, float thì ok, nhưng mất công viết 1 cái class/struct mà có thể chỉ xài 1 lần để trả về {string,int,float} ở cái hàm này.

trong Python có cho trả về nhiều kiểu rất là khỏe:

def func():
    return "hi", 20, 90.8 # trả về tuple

msg, n, avg = func() # khỏe re

C++ cũng bắt chước với std::tuple, nhưng phải viết dài dòng hơn: std::make_tuple(...) và khi lấy ra phải viết std::tie(...) và khai báo từng kiểu trả về trước đó. C++17 cho viết theo kiểu auto[...] mà ko cần khai báo kiểu trước đó nữa thì quá sướng :joy:

#include <tuple>

auto func()
{
  return std::make_tuple(std::string("hi"), 20, 90.8f);
}

int main()
{
  auto [msg, n, avg] = func();
}

compile thử với C++17: https://godbolt.org/g/PFYYZl

ko khác Python là bao :joy:

edit: nếu viết kiểu trả về ra rõ ràng thì có thể viết gọn hơn, xài initializer_list thay cho std::make_tuple:

std::tuple<std::string, int, float> func()
{
  return {"hi", 20, 90.8f};
}
4 Likes

Cho mình hỏi sao không dùng tham chiếu mà lại cố gắng trả về nhiều giá trị? Liệu trả về nhiều giá trị sẽ có thể dễ phát triển, bảo trì hơn?

Theo nguyên tắc self-documenting code (self-descriptive thì đúng hơn) thì nên dùng tham chiếu hay struct do ko thể đặt tên cho thành phần trong std::tuple.

Nhưng dùng struct sẽ dẫn đến những tên struct “bá đạo” (phải đặt là outputFunc + tên hàm hay đại loại vậy).

Điều này cho thấy trả về một std::tuple chỉ nên xài ở C++1z mode (chưa có 17).

2 Likes

return về một arraylà cách hay nhất.

1 Like
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?