Thứ Tư, 24 tháng 9, 2014

chương trình c tính tích hai 2 ma trận bất kì


/*chuong trinh c tinh tich hai ma tran bat ki*/
#include<stdio.h>
#include<conio.h>
#define max 100
/*tao ham nhap ma tran*/
void nhap(int mt[max][max],int h,int c)
{
printf("nhap ma tran:\n _____________________________\n");
for (int i = 0; i < h; i++)
{
printf("nhap hang %d:\n",i+1);
for (int j = 0; j < c; j++)
{
scanf_s("%d", &mt[i][j]);
}
printf("\n");
}
}
/*tao ham xuat ma tran*/
void xuat(int mt[max][max], int h, int c)
{
printf("__________________________\n");
for (int i = 0; i < h; i++)
{
for (int j = 0; j < c; j++)
{
printf("%6d", mt[i][j]);
}
printf("\n");
}
}
int mt1[max][max];
int mt2[max][max];
int tich[max][max];
void main()
{
printf("________author: Tran Khanh Toan____________\n___________________________\n");
int h1, h2, c1, c2;
/*nhap ma tran 1*/
printf(">>>ma tran 1\n");
printf("nhap so hang: ");
scanf_s("%d", &h1);
printf("nhap so cot: ");
scanf_s("%d", &c1);
nhap(mt1, h1, c1);
/*nhap ma tran 2*/
printf("\n__________________________________\n >>>ma tran 2\n");
printf("nhap so hang: ");
scanf_s("%d", &h2);
printf("nhap so cot: ");
scanf_s("%d", &c2);
nhap(mt2, h2, c2);
/*kiem tra hai ma colien hop khong
neu khong lien hop thi ket thuc chuong trinh*/
if (c1 != h2)
{
printf("hai ma tran khong lien hop nen khong the tinh tich");
goto kt;
}
/*tinh tich 2 ma tran*/

for (int i = 0; i < h1; i++)
{
for (int j = 0; j < c2; j++)
{
for (int n = 0; n < c1; n++)
{
tich[i][j] += mt1[i][n] * mt2[n][j];
}
}
}
printf("\n ________________________\n tich 2 ma tran do la: \n");
xuat(tich, h1, c2);
kt:;

_getch();
}
/* a(i,1)*b(1,j)+a(i,2)*b(2,j)=c(i,j)    */
file chương trình,>>>>> click to dwnload

Thứ Ba, 23 tháng 9, 2014

chuỗi , xâu ký tự trong c


Trong tất cả các chương trình chúng ta đã thấy cho đến giờ, chúng ta chỉ sử dụng các biến kiểu số, chỉ dùng để biểu diễn các số. Nhưng bên cạnh các biến kiểu số còn có các xâu kí tự, chúng cho phép chúng ta biểu diễn các chuỗi kí tự như là các từ, câu, đoạn văn bản... Cho đến giờ chúng ta mới chỉ dùng chúng dưới dạng hằng chứ chứa quan tâm đến các biến có thể chứa chúng.
Trong C không có kiểu dữ liệu cơ bản để lưu các xâu kí tự. Để có thể thỏa mãn nhu cầu này, người ta sử dụng mảng có kiểu char. Hãy nhớ rằng kiểu dữ liệu này (char) chỉ có thể lưu trữ một kí tự đơn, bởi vậy nó được dùng để tạo ra xâu của các kí tự đơn.
Ví dụ, mảng sau (hay là xâu kí tự):
char ho_ten[20];
có thể lưu một xâu kí tự với độ dài cực đại là 20 kí tự. Bạn có thể tưởng tượng nó như sau:




















Kích thước cực đại này không cần phải luôn luôn dùng đến. ví dụ xâu ho_ten ở trên có thể lưu các từ như "toan" hay "tran khanh toan".. Vì các mảng kí tự có thể lưu các xâu kí tự ngắn hơn độ dài của nó.
chúng ta có thể biểu diễn nó cho dễ hiểu như sau:

T
O
A
N
















T
R
A
N

K
H
A
N
H

T
O
A
N





 1.Khởi tạo các xâu kí tự. 
Vì những xâu kí tự là những mảng bình thường nên chúng cũng như các mảng khác. Ví dụ, nếu chúng ta muốn khởi tạo một xâu kí tự với những giá trị xác định chúng ta có thể làm điều đó tương tự như với các mảng khác: 
char ho_ten[]={'t','o','a','n'};
char ho_ten[]={"toan"};
char ho_ten[]="xau ki tu";
2.các lệnh nhập xuất dữ liệu dùng riêng cho chuỗi, xâu ký tự
  • nhập ký tự vào cho mảng xâu: gets_s(biến kiểu xâu hay tên mảng xâu mà ta đã tạo);
  • xuất ký tự trong mảng xâu ra màn hình: puts(biến kiểu xâu hay tên mảng xâu mà ta đã tạo);
*chú ý: trước khi nhập dữ liệu cho mảng xâu ta nên xóa rác trong bộ nhớ đệm cho đảm bảo an toàn khi viết chương trình, cú pháp như sau: _flushall();
3.ví dụ về khởi tạo, nhập và xuất mảng kiểu xâu ký tự:
#include<stdio.h>
#include<conio.h>
void main()
{
char ho_ten[20];
printf("nhap ho va ten:\n");
_flushall();
gets_s(ho_ten);
puts(ho_ten);
_getch();
}
__________________________________________________

#include<stdio.h>
#include<conio.h>
void main()
{
char ho_ten[] = { "ho va ten" };
puts(ho_ten);
_getch();
}
4.Gán giá trị cho xâu kí tự 
Vì vế trái của một lệnh gán chỉ có thể là một phần tử của mảng chứ không thể là cả mảng, chúng ta có thể gán một xâu kí tự cho một mảng kiểu char sử dụng một phương pháp như sau: 
xau[0]="h";
xau[1]="e";
xau[2]="l";
xau[3]="l";
xau[4]="o";
Nhưng rõ ràng đây không phải là một phương pháp thực tế. Để gán giá trị cho một xâu kí tự, chúng ta có thể sử dụng loạt hàm kiểu strcpy (string copy), hàm này được định nghĩa trong string.h và có thể được gọi như sau: 
strcpy (string1, string2); 
Lệnh này copy nội dung của string2 sang string1. string2 có thể là một mảng, con trỏ hay một hằng xâu kí tự, bởi vậy lệnh sau đây là một cách đúng để gán xâu hằng "Hello" cho mystring: 
strcpy (mystring, "Hello"); 
ví dụ:
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main()
{
char ho_ten[20];
strcpy_s(ho_ten, "tran minh an");
puts(ho_ten);
_getch();
}
Để ý rằng chúng ta phải include file <string.h> để có thể sử dụng hàm strcpy., trong visual 2013 thì lệnh strcpy thay thế bằng strcpy_s(...,...);
 chúng ta luôn có thể viết một hàm đơn giản như ganchuoi  để thay cho lệnh strcpy:
#include<stdio.h>
#include<conio.h>
void copy(char st1[], char st2[])
{
int n = 0;
do
{
st1[n] = st2[n];
n++;
} while (st2[n] != 0);
}
void main()
{
char ho_ten[20];
copy(ho_ten, "tran minh dang");
puts(ho_ten);
_getch();
} 
5.Các hàm để thao tác trên chuỗi 
Thư viện cstring (string.h) không chỉ có hàm strcpy mà còn có nhiều hàm khác để thao tác trên chuỗi. Dưới đây là giới thiệu lướt qua của các hàm thông dụng nhất:
char* strcat (char* dest, const char* src); 
Gắn thêm chuỗi src vào phía cuối của dest. Trả về dest. 
int strcmp (const char* string1, const char* string2); 
So sánh hai xâu string1 và string2. Trả về 0 nếu hai xâu là bằng nhau. 
char* strcpy (char* dest, const char* src);
Copy nội dung của src cho dest. Trả về dest.
 size_t strlen (const char* string); 
Trả về độ dài của string. 
Chú ý: char* hoàn toàn tương đương với char[] 

mảng nhiều chiều, đa chiều trong c


Mảng nhiều chiều có thể được coi như mảng của mảng, ví dụ, một mảng hai chiều có thể được tưởng tược như là một bảng hai chiều gồm các phần tử có kiểu dữ liệu cụ thể và giống nhau
0 1 2 3 4
0 1 2 3
4
Mảng nhiều chiều không bị giới hạn bởi hai chỉ số (hai chiều), Chúng có thể chứa bao nhiều chỉ số tùy thích mặc dù ít khí cần phải dùng đến mảng lớn hơn 3 chiều. Hãy thử xem xét lượng bộ nhớ mà một mảng có nhiều chỉ số cần đến.
char century [100][365][24][60][60]; 
Mảng nhiều chiều thực ra là một khái niệm trừu tượng vì chúng ta có thể có kết quả tương tự với mảng một chiều bằng một thao tác đơn giản giữa các chỉ số của nó: 
int jimmy [3][5];   tương đương với int jimmy [15];   (3 * 5 = 15)
ví dụ sau đây khai báo, nhập giá trị vào mảng và in ra màn hình mảng vừa nhập;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include<stdio.h>
#include<conio.h>
int mang[5][5];
void main()
{

int i, j;
for (i = 0; i <= 4; i++)
for (j = 0; j <= 4; j++)
{
printf("mang[%d][%d]=", i, j);
scanf_s("%d", &mang[i][j]);
printf("\n");
}
printf("mang ban da nhap la:\n");
for (i = 0; i <= 4; i++)
{
for (j = 0; j <= 4; j++)
{
printf("%4d", mang[i][j]);
}
printf("\n");
}
_getch();
}
*dùng mảng làm tham số
Vào một lúc nào đó có thể chúng ta cần phải truyền một mảng tới một hàm như là một tham số. Trong C, việc truyền theo tham số giá trị một khối nhớ là không hợp lệ, ngay cả khi nó được tổ chức thành một mảng. Tuy nhiên chúng ta lại được phép truyền địa chỉ của nó, việc này cũng tạo ra kết quả thực tế giống thao tác ở trên nhưng lại nhanh hơn nhiều và hiệu quả hơn
Để có thể nhận mảng là tham số thì điều duy nhất chúng ta phải làm khi khai báo hàm là chỉ định trong phần tham số kiểu dữ liệu cơ bản của mảng, tên mảng và cặp ngoặc vuông trống. Ví dụ, hàm sau
void procedure (int arg[]) 
nhận vào một tham số có kiểu "mảng của char" và có tên arg. Để truyền tham số cho hàm này một mảng được khai báo
int myarray [40]; 
chỉ cần gọi hàm như sau: 
procedure (myarray); 
Dưới đây là một ví dụ cụ thể 
#include<stdio.h>
#include<conio.h>
void in_mang(int arg[])
{
for (int n = 0; n <= 4; n++)
{
printf("%3d", arg[n]);
}
}
int mang[5];
void main()
{
int i;
for (i = 0; i <= 4; i++)
{
printf("mang[%d]=",i);
scanf_s("%d", &mang[i]);
printf("\n");
}
in_mang(mang);
_getch();
}
Như bạn có thể thấy, tham số đầu tiên (int arg[]) chấp nhận mọi mảng có kiểu cơ bản là int
Trong phần khai báo hàm chúng ta cũng có thể dùng tham số là các mảng nhiều chiều
ví dụ, một hàm với tham số là mảng nhiều chiều có thể như sau:
void procedure (int myarray[][3][4]) 
chú ý rằng cặp ngoặc vuông đầu tiên để trống nhưng các cặp ngoặc sau thì không. Bạn luôn luôn phải làm vậy vì trình biên dịch C phải có khả năng xác định độ lớn của các chiều thêm vào của mảng.
Dưới đây là một ví dụ cụ thể
#include<stdio.h>
#include<conio.h>
void in_mang(int a[][5],int h)
{
for (int i = 0; i <= h-1; i++)
{
for (int j = 0; j <= 4;j++)
{
printf("%4d", a[i][j]);
}
printf("\n");
}
}
int mang1[3][5];
int mang2[4][5];
void main()
{
for (int i = 0; i <= 3; i++)
{
for (int j = 0; j <= 4; j++)
{
printf("mang1[%d][%d]=", i, j);
scanf_s("%d", &mang1[i][j]);
printf("\n");
}
}
for (int a = 0; a <= 3; a++)
{
for (int b = 0; b <= 4; b++)
{
printf("mang2[%d][%d]=", a, b);
scanf_s("%d", &mang2[a][b]);
printf("\n");
}
}
printf("mang 1 la:\n");
in_mang(mang1, 3);
printf("mang 2 la:\n");
in_mang(mang2, 4);
_getch();

}

mảng một 1 chiều trong lập trình


Mảng là một dãy các phần tử có cùng kiểu được đặt liên tiếp trong bộ nhớ và có thể truy xuất đến từng phần tử bằng cách thêm một chỉ số vào sau tên của mảngĐiều này có nghĩa là, ví dụ, chúng ta có thể lưu 5 giá trị kiểu int mà không cần phải khai báo 5 biến khác nhau.Ví dụ, một mảng chứa 5 giá trị nguyên kiểu int có tên là A kiểu int
0 1 2 3 4
trong đó mỗi một ô trống biểu diễn một phần tử của mảng, trong trường hợp này là các giá trị nguyên kiểu int. Chúng được đánh số từ 0 đến 4 vì phần tử đầu tiên của mảng luôn là 0 bất kể độ dài của nó là bao nhiêu
Như bất kì biến nào khác, một mảng phải được khai báo trước khi có thể sử dụng. Một khai báo điển hình cho một mảng trong C như sau: 
type name [elements];
trong đó type là một kiểu dữ liệu hợp lệ (int, float...), name là một tên biến hợp lệ và trường elements chỉ định mảng đó sẽ chứa bao nhiêu phần tử  
Vì vậy, để khai báo A như đã trình bày ở trên chúng ta chỉ cần một dòng đơn giản như sau
int A[5];
Chú ý: Trường elements  bên trong cặp ngoặc [] phải là một giá trị hằng khi khai báo một mảng, vì mảng là một khối nhớ tĩnh có kích cỡ xác định và trình biên dịch phải có khả năng xác định xem cần bao nhiêu bộ nhớ để cấp phát cho mảng trước khi các lệnh có thể được thực hiện
1.Khởi tạo một mảng
Khi khai báo một mảng với tầm hoạt động địa phương (trong một hàm), theo mặc định nó sẽ không được khởi tạo, vì vậy nội dung của nó là không xác định cho đến khi chúng ra lưu các giá trị lên đó. 
Nếu chúng ta khai báo một mảng toàn cục (bên ngoài tất cả các hàm) nó sẽ được khởi tạo và tất cả các phần tử được đặt bằng 0
Nhưng thêm vào đó, khi chúng ta khai báo một mảng, chúng ta có thể gán các giá trị khởi tạo cho từng phần tử của nó.  Ví dụ: 
int A [5] = { 16, 2, 77, 40, 12071 };
lệnh trên sẽ khai báo một mảng như sau
16
2
77
40
12071
Số phần tử trong mảng mà chúng ta khởi tạo với cặp ngoặc nhọn { } phải bằng số phần tử của mảng đã được khai báo với cặp ngoặc vuông [ ]. Bởi vì điều này có thể được coi là một sự lặp lại không cần thiết nên C cho phép để trống giữa cặp ngoặc vuông, kích thước của mảng được xác định bằng số giá trị giữa cặp ngoặc nhọn. 
2.Truy xuất đến các phần tử của mảng
Ở bất kì điểm nào của chương trình trong tầm hoạt động của mảng, chúng ta có thể truy xuất từng phần tử của mảng để đọc hay chỉnh sửa như là đối với một biến bình thường. 
Ví dụ, để lưu giá trị 75 vào phần tử thứ ba của billy ta viết như sau:
billy[2] = 75; 
và, ví dụ, để gán giá trị của phần tử thứ 3 của billy cho biến a, chúng ta viết
a = billy[2]; 
Vì vậy, xét về mọi phương diện, biểu thức billy[2] giống như bất kì một biến kiểu int.  
Chú ý rằng phần tử thứ ba của billy là billy[2], vì mảng bắt đầu từ chỉ số 0. Vì vậy, phần tử cuối cùng sẽ là billy[4]. Vì vậy nếu chúng ta viết billy[5], chúng ta sẽ truy xuất đến phần tử thứ 6 của mảng và vượt quá giới hạn của mảngTrong C, việc vượt quá giới hạn chỉ số của mảng là hoàn toàn hợp lệ, tuy nhiên nó có thể gây ra những vấn đề thực sự khó phát hiện bởi vì chúng không tạo ra những lỗi trong quá trình dịch nhưng chúng có thể tạo ra những kết quả không mong muốn trong quá trình thực hiện. Nguyên nhân của việc này sẽ được nói đến kĩ hơn khi chúng ta bắt đầu sử dụng con trỏ.  
Cần phải nhấn mạnh rằng chúng ta sử dụng cặp ngoặc vuông cho hai tác vụ: đầu tiên là đặt kích thước cho mảng khi khai báo chúng và thứ hai, để chỉ định chỉ số cho một phần tử cụ thể của mảng khi xem xét đến nó
int billy[5];         // khai báo một mảng mới. 
billy[2] = 75;        // truy xuất đến một phần tử của mảng.
ví dụ về mảng đơn giản như sau:
#include<stdio.h>
#include<conio.h>
int mang[5];
void main()
{
int i;
for (i = 0; i <= 4; i++)
{
printf("nhap phan tu mang[%d]=", i);
scanf_s("%d", &mang[i]);
printf("\n");
}
printf("mang ban da nhap la:\n");
for (i = 0; i <= 4; i++)
{
printf(" %d ", mang[i]);
}

}

hàm trong ngôn ngữ lập trình c (part 2)


1.Truyền tham số theo tham số giá trị hay tham số biến
Cho đến nay, trong tất cả các hàm chúng ta đã biết, tất cả các tham số truyền cho hàm đều được truyền theo giá trị. Điều này có nghĩa là khi chúng ta gọi hàm với các tham số, những gì chúng ta truyền cho hàm là các giá trị chứ không phải bản thân các biến. Ví dụ, giả sử chúng ta gọi hàm tich như sau:
int x=5, y=3, z; 
z=tich(x,y);
Trong trường hợp này khi chúng ta gọi hàm addition thì các giá trị 5 and 3 được truyền cho hàm, không phải là bản thân các biến.
#include<stdio.h>
#include<conio.h>
void nhandoi(int&a, int&b)
{
a *= 2;
b *= 2;
}
void main()
{
int x, y;
printf("nhap vao a,b:\n");
scanf_s("%d%d", &x, &y);
nhandoi(x, y);
printf(" %d  %d ", x, y);
_getch();
}
Điều đầu tiên làm bạn chú ý là trong khai báo của duplicate theo sau tên kiểu của mỗi tham số đều là dấu và (&), để báo hiệu rằng các tham số này được truyền theo tham số biến chứ không phải tham số giá trị.

Khi truyền tham số dưới dạng tham số biến chúng ta đang truyền bản thân biến đó và bất kì sự thay đổi nào mà chúng ta thực hiện với tham số đó bên trong hàm sẽ ảnh hưởng trực tiếp đến biến đó.
Truyền tham số dưới dạng tham số biến cho phép một hàm trả về nhiều hơn một giá trị. Ví dụ, đây là một hàm trả về số liền trước và liền sau của tham số đầu tiên
#include<stdio.h>
#include<conio.h>
void tinh(int x, int&next, int&prev)
{
next = x + 1;
prev = x - 1;
}
void main()
{
int x,y,z;
printf("nhap vao 1 so");
scanf_s("%d", &x);
tinh(x, y, z);
printf("%d %d %d", z,x,y);
_getch();
}
2.Giá trị mặc định của tham số
Khi định nghĩa một hàm chúng ta có thể chỉ định những giá trị mặc định sẽ được truyền cho các đối số trong trường hợp chúng bị bỏ qua khi hàm được gọi. Để làm việc này đơn giản chỉ cần gán một giá trị cho đối số khi khai báo hàm. Nếu giá trị của tham số đó vẫn được chỉ định khi gọi hàm thì giá trị mặc định sẽ bị bỏ qua. Ví dụ
#include<stdio.h>
#include<conio.h>
int tinh(int x,int y=2)
{
int chia;
chia = x / y;
return(chia);
}
void main()
{
printf("thieu 1 tham so =%d \n", tinh(12));
printf("du tham so=%d\n", tinh(20, 4));
_getch();
}
có hai tham số, bởi vậy giá trị mặc định sẽ được bỏ qua. Kết quả của hàm sẽ là 5 (20/4)
3.Quá tải các hàm
Hai hàm có thể có cũng tên nếu khai báo tham số của chúng khác nhau, điều này có nghĩa là bạn có thể đặt cùng một tên cho nhiều hàm nếu chúng có số tham số khác nhau hay kiểu dữ liệu của các tham số khác nhau (hay thậm chí là kiểu dữ liệu trả về khác nhau).
4.đệ quy
Các hàm có thể gọi chính nó. Điều này có thể có ích với một số tác vụ như là một số phương pháp sắp xếp hay tính giai thừa của một số. Ví dụ, để tính giai thừa của một số (n), công thức toán học của nó như sau:
n! = n * (n-1) * (n-2) * (n-3) ... * 1 
và một hàm đệ qui để tính toán sẽ như sau:
#include<stdio.h>
#include<conio.h>
unsigned long giaithua(unsigned long x)
{
if (x>1) return(x*giaithua(x-1));
else return(1);

}

void main()
{
unsigned long a;
printf("nhap vao so can tinh giai thua\n");
scanf_s("%lu", &a);
printf("%lu! = %lu", a, giaithua(a));
_getch();
}
5.Khai báo mẫu cho hàm
Cho đến giờ chúng ta hoàn toàn phải định nghĩa hàm trước lệnh gọi đầu tiên đến nó, mà thường là trong main, vì vậy hàm main luôn phải nằm cuối chương trình. Nếu bạn thử lặp lại một vài ví dụ về hàm trước đây nhưng thử đặt hàm main trước bất kì một hàm được gọi từ nó, bạn gần như chắc chắn sẽ nhận được thông báo lỗi. Nguyên nhân là một hàm phải được khai báo trước khi nó được gọi như nhưnggx gì chúng ta đã làm trng tất cả các ví dụ
Nhưng có một cách khác để tránh phải viết tất cả mã chương trình trước khi chúng có thể được dùng trong main hay bất kì một hàm nào khác. Đó chính là khai báo mẫu cho hàm. Cách này bao gồm việc khai báo hàm một cách ngắn gọn nhưng đủ để cho trình dịch có thể biết các tham số và kiểu dữ liệu trả về của hàm.
Dạng của nó như sau:
type name ( argument_type1, argument_type2, ...); 
Đây chính là phần đầu của định nghĩa hàm, ngoại trừ:
  • Nó không có bất kì lệnh nào cho hàm. Điều này có nghĩa là nó không bao gồm thân hàm với tất cả các lệnh thường được bọc trong cặp ngoặc nhọn { }
  • Nó kết thúc bằng dấu chấm phẩy (;). 
  • Trong phần liệt kê các tham số chỉ cần viết kiểu của chúng là đủ. Việc viết tên của các tham số trong phần khai báo mẫu là không bắt buộc
Ví dụ:
#include<stdio.h>
#include<conio.h>
unsigned long giaithua(unsigned long);
void main()
{
unsigned long a;
printf("nhap vao so can tinh giai thua\n");
scanf_s("%lu", &a);
printf("%lu! = %lu", a, giaithua(a));
_getch();
}
unsigned long giaithua(unsigned long x)
{
if (x>1) return(x*giaithua(x - 1));
else return(1);

}

Ví dụ này rõ ràng không phải là một ví dụ về sự hiệu quả. Tôi chắc chắn rằng các bạn có thể nhận được kết quả như trên chỉ với một nửa số dòng lệnh. Tuy nhiên nó giúp cho chúng ta thấy được việc khai báo mẫu các hàm là như thế nào
Rất nhiều lập trình viên kinh nghiệm khuyên rằng tất cả các hàm nên được khai báo mẫu. Đó cũng là lời khuyên của tôi, nhất là trong trường hợp có nhiều hàm hoặc chúng rất dài, khi đó việc khai báo tất cả các hàm ở cùng một chỗ cho phép chúng ta biết phải gọi các hàm như thế nào, vì vậy tiết kiệm được thời gian

hàm trong ngôn ngữ lập trình c (part 1)


Hàm là một khối lệnh được thực hiện khi nó được gọi từ một điểm khác của chương trình. Dạng thức của nó như sau:
type name ( argument1, argument2, ...) statement 
trong đó: type là kiểu dữ liệu được trả về của hàm name là tên gọi của hàm. arguments là các tham số (có nhiều bao nhiêu cũng được tuỳ theo nhu cầu). Một tham số bao gồm tên kiểu dữ liệu sau đó là tên của tham số giống như khi khai báo biến (ví dụ int x) và đóng vai trò bên trong hàm như bất kì biến nào khác. Chúng dùng để truyền tham số cho hàm khi nó được gọi. Các tham số khác nhau được ngăn cách bởi các dấu phẩy. statement là thân của hàm. Nó có thể là một lệnh đơn hay một khối lệnh.

Dưới đây là ví dụ đầu tiên về hàm:
#include<stdio.h>
#include<conio.h>
int tich(int a, int b)
{
int t;
t = a*b;
return(t);
}
void main()
{
int a, b,s;
printf("nhap vao 2 so muon tinh tich\n");
scanf_s("%d%d", &a, &b);
s = tich(a, b);
printf("tich =%d", s);
_getch();
}
Để có thể hiểu được đoạn mã này, trước hết hãy nhớ lại những điều đã nói ở bài đầu tiên: một chương trình C luôn bắt đầu thực hiện từ hàm main. Vì vậy chúng ta bắt đầu từ đây.
Chúng ta có thể thấy hàm main bắt đầu bằng việc khai báo biến,nhập dữ liệu,  sau đó là một lời gọi tới hàm .  Nếu để ý chúng ta sẽ thấy sự tương tự giữa cấu trúc của lời gọi hàm với khai báo của hàm. lệnh return (t) chính là giá trị được trả về của hàm.
Bạn cần nhớ rằng phạm vi hoạt động của các biến khai báo trong một hàm hay bất kì một khối lệnh nào khác chỉ là hàm đó hay khối lệnh đó và không thể sử dụng bên ngoài chúng. Ví dụ, trong chương trình ví dụ trên, bạn không thể sử dụng trực tiếp các biến a, b vì chúng là các biến cục bộ của hàm 
Tuy nhiên bạn có thể khai báo các biến toàn cục để có thể sử dụng chúng ở bất kì đâu, bên trong hay bên ngoài bất kì hàm nào. Để làm việc này bạn cần khai báo chúng bên ngoài mọi hàm hay các khối lệnh, có nghĩa là ngay trong thân chương trình. 
#include<stdio.h>
#include<conio.h>
int a, b, t, s;
int tich(int a,int b)
{

t = a*b;

return(t);
}
void main()
{
printf("nhap vao 2 so muon tinh tich\n");
scanf_s("%d%d", &a, &b);
s = tich(a, b);
printf("tich =%d", s);
_getch();

}


 các cách khác nhau mà một hàm có thể được gọi. 
1. tich(a,b);   với a,b là biến đã có giá trị
2.tich(12,7);  ta thay trực tiếp giá trị và hàm.
hàm có thể đươc gọi ra ngay trong lệnh xuất của ngôn ngữ c++. hay trong các phép tính toán như là 1 số bình thường.
  • các hàm không kiểu, cách sử dụng void:
Nếu bạn còn nhớ cú pháp của một lời khai báo hàm:  
type name ( argument1, argument2 ...) statement 
bạn sẽ thấy rõ ràng rằng nó bắt đầu với một tên kiểu, đó là kiểu dữ liệu sẽ được hàm trả về bởi lệnh return. Nhưng nếu chúng ta không muốn trả về giá trị nào thì sao ? 
Hãy tưởng tượng rằng chúng ta muốn tạo ra một hàm chỉ để hiển thị một thông báo lên màn hình. Nó không cần trả về một giá trị nào cả, hơn nữa cũng không cần nhận tham số nào hết. Vì vậy người ta đã nghĩ ra kiểu dữ liệu void trong ngôn ngữ C. Hãy xem xét chương trình sau:
#include<stdio.h>
#include<conio.h>
void in(void)
{
printf("in ra man hinh");
}
void main()
{
in();
_getch();
}
Từ khoá void trong phần danh sách tham số có nghĩa là hàm này không nhận một tham số nào. Tuy nhiên trong C không cần thiết phải sử dụng void để làm điều này. Bạn chỉ đơn giản sử dụng cặp ngoặc đơn ( ) là xong


Bài đăng phổ biến