25/05/2018, 13:17

Truyền giá trị cho hàm theo tham chiếu

Trong C chỉ có một cách truyền dữ liệu cho hàm theo giá trị : + Cấp phát vùng nhớ cho các đối. + Gán giá trị các tham số trong lời gọi hàm cho các đối sau đó hàm làm việc trên vùng nhớ của các đối chứ không liên quan gì đến ...

Trong C chỉ có một cách truyền dữ liệu cho hàm theo giá trị :

+ Cấp phát vùng nhớ cho các đối.

+ Gán giá trị các tham số trong lời gọi hàm cho các đối sau đó hàm làm việc trên vùng nhớ của các đối chứ không liên quan gì đến các tham số.

Như vây chương trình sẽ tạo ra các bản sao (các đối) của các tham số và hàm sẽ thao tác trên các bản sao này, chứ không làm việc trực tiếp với các tham số. Phương pháp này có 2 nhược điểm chính:

Tốn kém về thời gian và bộ nhớ vì phải tạo ra các bản sao. Không thao tác trực tiếp trên các tham số, vì vậy không làm thay đổi được giá trị các tham số.

Trong C++ cung cấp thêm cách truyền dữ liệu cho hàm theo tham chiếu bằng cách dùng đối là biến tham chiếu hoặc đối là hằng tham chiếu. Cách này có ưu điểm:

Không cần tạo ra các bản sao của các tham số, do đó tiết kiệm bộ nhớ và thời gian chạy máy.

Hàm sẽ thao tác trực tiếp trên vùng nhớ của các tham số, do đó dễ dàng thay đổi giá trị các tham số khi cần.

Nếu đối là biến hoặc hằng tham chiếu kiểu K thì tham số (trong lời gọi hàm) phải là biến hoặc phần tử mảng kiểu K. Ví dụ:

+ Đối là biến hoặc hằng tham chiếu kiểu double, thì tham số là biến hoặc phần tử mảng kiểu double

+ Đối là biến hoặc hằng tham chiếu kiểu cấu trúc, thì tham số là biến hoặc phần tử mảng kiểu cấu trúc

/* 
    Chương trình sau được tổ chức thành 3 hàm:
    Nhập dẫy số double
    Hoán vị 2 biến double
    Sắp xếp dẫy số double theo thứ tự tăng dần
    Chương trình sẽ nhập một dẫy số và in dẫy sau khi sắp xếp
    */
    #include <iostream.h>
    #include <conio.h>
    #include <stdio.h>
    void nhapds(double *a, int n)
    {
    for (int i=1; i<= n ; ++i)
    {
    cout << "
Phan tu thu " << i << " : " ;
    cin >> a[i] ;
    }
    }
    void hv(double &x, double &y)
    {
    double tg=x; x=y; y= tg;
    }
    void sapxep(double * a, int n)
    {
    for (int i=1; i <= n-1 ;++i)
    for (int j=i+1 ; j<=n ;++j)
    if (a[i] > a[j])
    hv(a[i],a[j]);
    }
    void main()
    {
    double x[100];
    int i, n;
    cout <<"
 N= ";
    cin >> n;
    nhapds(x,n);
    sapxep(x,n);
    for (i=1;i<=n;++i)
    printf("
%0.1lf",x[i]);
    getch();
    }
    /* 
    Chương trình sau gồm các hàm:
    - Nhập dẫy cấu trúc (mỗi cấu trúc chứa dữ liệu một thí sinh)
    - Hoán vị 2 biến cấu trúc
    - Sắp xếp dẫy thí sinh theo thứ tự giảm của tổng điểm
    - In một cấu trúc (in họ tên và tổng điểm)
    Chương trình sẽ nhập dữ liệu một danh sách thí sinh, nhập điểm chuẩn và in danh sách thí sinh trúng tuyển
    */
    #include <iostream.h>
    #include <iomanip.h>
    #include <conio.h>
    struct TS
    {
    char ht[20];
    float t,l,h,td;
    } ;
    void ints(const TS &ts)
    {
    cout << setiosflags(ios::showpoint) << setprecision(1) ;
    cout << "
Ho ten: " << setw(20) << ts.ht << setw(6) << ts.td ;
    }
    void nhapsl(TS *ts,int n)
    {
    for (int i=1;i<=n;++i)
    {
    cout << "
 Thi sinh " << i ;
    cout << "
 Ho ten: " ;
    cin.ignore(1);
    cin.get(ts[i].ht,25) ;
    cout << "Cac diem toan, ly, hoa: ";
    cin >> ts[i].t >> ts[i].l >> ts[i].h ;
    ts[i].td = ts[i].t + ts[i].l + ts[i].h ;
    }
    }
    void hvts(TS &ts1, TS &ts2)
    {
    TS tg=ts1;
    ts1=ts2;
    ts2=tg;
    }
    void sapxep(TS *ts,int n)
    {
    for (int i=1;i<=n-1;++i)
    for (int j=i+1;j<=n;++j)
    if (ts[i].td < ts[j].td)
    hvts(ts[i],ts[j]);
    }
    void main()
    {
    TS ts[100];
    int n,i;
    clrscr();
    cout << " So thi sinh: " ;
    cin >> n ;
    nhapsl(ts,n);
    sapxep(ts,n) ;
    float dc;
    cout << " Diem chuan: " ;
    cin >> dc;
    cout << "

Danh sach trung tuyen
" ;
    for (i=1;i<=n;++i)
    if (ts[i].td >= dc)
    ints(ts[i]);
    else
    break;
    getch();
    }
    /* 
    Chương trình sau gồm các hàm:
    Nhập một ma trận thực cấp mxn
    In một ma trận thực dưới dạng bảng
    Tìm phần tử lớn nhất và phần tử nhỏ nhất của dẫy số thưc;
    Chương trình sẽ nhập một ma trận, in ma trận vừa nhập và in các phần tử lớn nhất và nhỏ nhất trên mỗi hàng của ma trận
    */
    #include <iostream.h>
    #include <iomanip.h>
    #include <conio.h>
    #include <stdio.h>
    void nhapmt(float a[20][20], int m, int n)
    {
    for (int i=1 ; i<= m ; ++i)
    for (int j=1; j<= n ; ++j)
    {
    cout << "
a[" << i << "," << j << "]= " ;
    cin >> a[i][j] ;
    }
    }
    void inmt(float a[20][20], int m, int n)
    {
    cout << setiosflags(ios::showpoint) << setprecision(1);
    for (int i=1 ; i<= m ; ++i)
    for (int j=1; j<= n ; ++j)
    {
    if (j==1) cout << "
" ;
    cout << setw(6) << a[i][j] ;
     }
    }
    void maxminds(float *x, int n,int &vtmax, int &vtmin)
    {
    vtmax = vtmin = 1 ;
    for (int i=2; i<=n ; ++i)
    {
    if (x[i] > x[vtmax]) vtmax = i;
    if (x[i] < x[vtmin]) vtmin = i;
    }
    }
    void main()
    {
    float a[20][20];
    int m, n;
    cout <<"
 So hamg va so cot ma tran: ";
    cin >> m >> n;
    nhapmt(a,m,n);
    clrscr();
    inmt(a,m,n);
    float *p = (float*)a;
    int vtmax, vtmin;
    for (int i=1;i<=m;++i)
    {
    p = ((float*)a) + i*20 ;
    maxminds(p , n, vtmax, vtmin) ;
    printf("
Hang %d Phan tu max= %6.1f tai cot 
    %d",i,p[vtmax],vtmax);
    printf("
 Phan tu min= %6.1f tai cot %d", p[vtmin],vtmin);
    }
    getch();
    }
    
0