Académique Documents
Professionnel Documents
Culture Documents
1 Fundamentos de C / C++
www.del.ufrj.br/~villas
villas@del.ufrj.br
Hello World
// hello.cpp
build
#include <stdio.h>
void main() {
printf("Hello World\n");
}
compilao
ligao
(link)
hello.exe
Legenda:
c:\>hello?
Hello World
c:\>
arquivo texto
arquivo binrio
console
Projetos em C/C++
? Um
comp.
f1.obj
f1_1
f1_2
f1_3
// f2.c
void f2_1() { /* ... */ }
void f2_2() { /* ... */ }
void f2_3() { /* ... */ }
comp.
f2.obj
f2_1
f2_2
// fn.c
comp.
f2_3
...
fn.obj
fn_m
biblioteca
padro
Projetos em C/C++)2 (
Projetos em C/C++)2 (
Projetos em C/C++)2 (
f1.obj
f1_1
f1_2
f1_3
f2.obj
f2_1
f2_2
f2_3
...
fn.obj
fn_m
NomeDoProjeto.exe
funes da
biblioteca padro
biblioteca
(standard library)
padro
ligao
(link)
f1_1
f1_2
f1_3
f2_1
f2_2
f2_3
main
other
fn_m
preciso que
haja a funo
main no
executvel
final
Compilao (1)
? Cada
Compilao (2)
? Ao
?O
// t1.cpp
#include <stdio.h>
// declara e define
// a funo f1
// (o identificador f1)
void f1() {
// chama a funo printf
printf("Hello");
}
void main() {
f1(); // chama a funo f1
/* a chamada da funo f1
compatvel com a declarao
do identificador f1. */
}
Exemplode compilao
(1)
Exemplode compilao
(1)
Exemplode compilao
(1)
// t2.cpp
#include <stdio.h>
/* Declara a funo f1
(o identificador f1)
prottipo da funo f1.
Essa linha no gera cdigo,
mas faz o compilador aprender
o sifnificado do identificador
f1 */
void f1();
void main() {
f1(); // chama a funo f1
}
/* define a funo f1, sendo
que essa definio compatvel
com o significado do mesmo
identificador previamente
declarado */
void f1() {
// chama a funo printf
printf("Hello");
}
// t1.cpp
#include <stdio.h>
void f1() {
printf("hello\n");
}
biblioteca
padro
(standard
library)
t1.obj
f1
comp.
main
void main() {
f1();
}
link
projeto.exe
printf
c:\>projeto?
hello
c:\>
f1
Construindo executvel
o
Construindo executvel
o
Construindo executvel
o
main
// t2.cpp
#include <stdio.h>
void f1();
biblioteca
padro
(standard
library)
t2.obj
f1
void main() {
f1();
}
comp.
main
void f1() {
printf("hello\n");
}
link
// t2a.cpp
#include <stdio.h>
void main() {
f1(); // No compila.
// O que significa f1 ?
}
projeto.exe
printf
main
Exemplode compilao
(2)
Exemplode compilao
(2)
Exemplode compilao
(2)
void f1() {
printf("hello\n");
}
f1
// t3.cpp
void f1();
void main() {
f1();
}
// t4.cpp
#include <stdio.h>
void f1() {
printf("Hello");
}
t3.obj
comp.
main
biblioteca
padro
(standard
library)
t4.obj
comp.
f1
Exemplode compilao
(3)
Exemplode compilao
(3)
Exemplode compilao
(3)
link
projeto.exe
printf
main
f1
Erro de Link !
myFun
f2.obj
myFun
ligao
(link)
Tentativa de gerar um
executvel com 2 funes
globais com mesmo
identificador
...
printf
f1
f1
main
main
f1
printf
printf
main
main
f1
Equivalentes !
// t5.cpp
#include <stdio.h>
void f1() {
printf("Hello");
}
void main() {
f1();
}
void ninguemMeChama() {
printf("Nada");
}
printf
comp.
ligao
(link)
f1
main
ninguemMeChama
? Variveis
(locais, globais)
Stack Pointer
void f3() {
}
f2
void f2(int k) {
f3();
}
if1
stack pointer
f1
void f1() {
int if1 = 1;
f2(if1);
}
void main() {
f1();
}
Chamadas de funo
main();
f1();
f2();
f1();
f2();
f3();
f3();
10
11
12
biblioteca
padro
// mymath.cpp
#include<math.h>
double sin2(double x) {
double ret = sin(x);
ret *= ret;
return ret;
}
// mymath_header.h
double sin2(double x);
// sin2_main.cpp
#include"mymath_header.h"
void main(){
double f = sin2(0.4);
}
ligao
(link)
mymath.obj
comp.
No gera-se
mymath_header.obj
sin2_main.obj
projeto.exe
Arquivosdecabealho(header
() )2
Arquivosdecabealho(header
() )2
Arquivosdecabealho(header
() )2
comp.
13
Bibliotecas (1)
?
14
// f1.cpp
...
// f2.cpp
...
comp.
comp.
f1.obj
f1_1
f1_2
f1_3
ferramenta de criao
de bibliotecas
Bibliotecas( )2
Bibliotecas( )2
Bibliotecas( )2
mylib.lib
mylib.a
f2.obj
f2_1
f2_2
f1_1
f1_2
f1_3
f2_1
f2_2
f2_3
f3_1
f3_2
f3_3
f2_3
// f3.cpp
...
comp.
f3.obj
f3_1
f3_2
f3_3
// usemylib.cpp
#include "mylib.h"
void main () {
f1_2();
f1_3();
}
usemylib.obj
comp.
main
ligao
(link)
Bibliotecas( )3
Bibliotecas( )3
Bibliotecas( )3
biblioteca
padro
f1_1
f1_2
f1_3
f2_1
f2_2
f2_3
f3_1
f3_2
f3_3
projeto.exe
main
f1_1
f1_2
f1_3
15
(loops)
while
do .. while
for
#include<iostream.h>
void main () {
int i=0;
while (i < 5) {
cout << "i=" << i << endl;
i++; // i = i + 1;
}
}
i=0
i=1
i=2
i=3
i=4
(loops)
while
do .. while
for
#include<iostream.h>
void main () {
int i=0;
do {
cout << "i=" << i << endl;
i++; // i = i + 1;
} while (i < 5);
}
i=0
i=1
i=2
i=3
i=4
16
(loops)
while
do .. while
for
#include<iostream.h>
void main () {
for (int i=0; i<5 ; i++)
cout << "i=" << i << endl;
}
for (<1> ; <2> ; <3>)
<4>;
{
i=0
i=1
i=2
i=3
i=4
<1>;
while (<2>) {
<4>;
<3>;
}
}
17
rvalue e lvalue
#include <iostream.h>
void main () {
float f = 1.1;
float & lvalue _f = f;
lvalue_f = 2.2;
cout << "f=" << f << endl;
cout << " lvalue_f=" << lvalue _f << endl;
cout << &f << " - " << & lvalue_f << endl;
}
f=2.2
lvalue_f=2.2
0x0012FF7C - 0x0012FF7C
Array
#include <iostream.h>
void main() {
float f[5];
for (int i=0 ; i < 5 ; i++) {
f[i] = 1 + i / 10.0;
cout << f[i] << endl;
}
}
#include <iostream.h>
#define N 5
void main() {
float f[N];
for (int i=0 ; i < N ; i++) {
f[i] = 1 + i / 10.0;
cout << f[i] << endl;
}
}
left
valu
e
a=b;
ue
val
t
h
rig
void main () {
int i;
i = 5; // OK
5 = i; // error:
// '=' : left operand
// must be l-value
}
f
lvalue_f
<float>
<float &>
M programao
2 constantes
relacionadas em
trechos diferentes
do programa.
1
1.1
1.2
1.3
1.4
f <float*>
f[0]
f[1]
f[2]
f[3]
f[4]
<float>
<float>
<float>
<float>
<float>
18
Ponteiros (1)
na
nd
nc
CPU
mem
endereos (address)
dados
controle
outro
perifrico
Ponteiros (2)
?O
19
Ponteiros (3)
&f
f
pf
<float>
<float*>
#include<iostream.h>
void main () {
float f = 1.1;
float *pf;
pf = &f;
*pf = 2.2;
cout << "f=" << f << endl;
cout << "pf=" << pf << endl;
}
f=2.2
pf=0x0066FDF4
&f
f
&pf
pf
&ppf
ppf
pppf
<float>
<float*>
<float**>
<float***>
2.2
3.3
4.4
20
f <float*>
f[0]
f[1]
f[2]
f[3]
f[4]
Arrays e ponteiros
<float>
<float>
<float>
<float>
<float>
? *(p+i)
equivalente a p[i]
? Na soma de um ponteiro com um inteiro,
automaticamente multiplica-se o inteiro pelo
tamanho do tipo
p+i*sizeof(TYPE)
?O
a=10.1
a=10.1
a=2.2
a=3.3
21
f1
<float> 1.1
<float> 10.1
f2
&a
<float> 10.1
endl;
f3
endl;
<float> 10.1
endl;
endl;
fp
x
<double (*)(double)>
<double>
sin2=0.151647
cos2=0.848353
22
sin2=0.151647
cos2=0.848353
sin2=0.151647
cos2=0.848353
23
24
Vazamento de memria
(memory leak)
1
0
10010
10
1001010011
10010100
#include<iostream.h>
void main () {
double *pd = new double;
// delete pd;
}
new
delete
Gerente
de memria
alocada
25
void do_all () {
double *pd = new double;
}
check
void main () {
VBMemCheck a;
do_all();
a.check ();
}
mark
26
1 101 201
11 111 211
21 121 221
m1
m1[0]
m1[1]
m1[2]
m1[0][0]
m1[0][1]
m1[0][2]
m1[1][0]
m1[1][1]
m1[1][2]
m1[2][0]
m1[2][1]
m1[2][2]
<double**>
<double*>
<double*>
<double*>
<double>
<double>
<double>
<double>
<double>
<double>
<double>
<double>
<double>
27
rea de ponteiros
rea de dados
m1
m1[0]
m1[1]
m1[2]
m1[0][0]
m1[0][1]
m1[0][2]
m1[1][0]
m1[1][1]
m1[1][2]
m1[2][0]
m1[2][1]
m1[2][2]
<double**>
<double*>
<double*>
<double*>
<double>
<double>
<double>
<double>
<double>
<double>
<double>
<double>
<double>
m1
m1[0]
m1[1]
m1[2]
m1[0][0]
m1[0][1]
m1[0][2]
m1[1][0]
m1[1][1]
m1[1][2]
m1[2][0]
m1[2][1]
m1[2][2]
<double**>
<double*>
<double*>
<double*>
<double>
<double>
<double>
<double>
<double>
<double>
<double>
<double>
<double>
28
Diretivas de compilao
#define
// diretiva para o pr processador de texto
#include <iostream.h>
#define N 3
#define MY_FUN(x) ((x)*(x))
void main () {
for ( int i=0; i < N ; i++)
cout << "i=" << i << endl;
double d = MY_FUN(3.3+1.1);
cout << "d=" << d << endl;
}
no usar
; (ponto e vrgula)
i=0
i=1
i=2
d=19.36
Diretivas de compilao
# (para string)
#include <iostream.h>
#define PATH(logid,cmd) "/ usr/" # logid "/bin/" #cmd
void main () {
char *mytool = PATH(francisco ,readmail );
// expandido para: char *mytool = "/usr/" "francisco " "/bin /" "readmail ";
// equivalente a: char *mytool = "/usr/francisco /bin/readmail";
cout << mytool << endl;
}
/usr/francisco/bin/readmail
29
Diretivas de compilao ##
concatenao de identificadores
#include <iostream.h>
#define TIPO(a) FUT ## a
#define FUTSAL "futebol de salo"
#define FUTBOL "tradicional futebol de campo"
void main () {
cout << TIPO(SAL) << endl;
cout << TIPO(BOL) << endl;
}
futebol de salo
tradicional futebol de campo
Compilao condicional
#include <iostream.h>
#include <math.h> // sin
#define DEBUG
void show(double z) {
#if 0
/* commented out
double q;
// this function is a test
q = 1.1;
cout << q << endl;
*/
cout << z << endl;
#endif
}
a=0.389418
void main () {
double a,b,c,d;
a = sin(0.4);
#ifdef DEBUG
cout << "a=" << a << endl;
#endif
show(a);
}
30
A biblioteca padro C
?
31
Strings em C/C++(1)
? Em
strcpy(p,szMyStr); // BUG
// para onde est copiando ?
}
&buffer[0]
= buffer
'a'
'b'
'c'
zero
buffer[0]
buffer[1]
buffer[9]
strcat
#include <iostream.h>
#include <string.h>
int main() {
char *szMyStr = "abc";
char *p;
char buffer[10];
strcpy(buffer,szMyStr); // OK
strcat(buffer,"def"); // OK
cout << buffer << endl;
"abc"
strcpy
'a'
'b'
'c'
zero 'd'
'e'
'f'
zero
!
abcdef
32
buffer[0]
buffer[1]
buffer[299]
void main() {
char *completePath = htmlPath("fred");
cout << completePath << endl;
}
c:\>program?
<algum tipo de erro>
c:\>
33
34
#include <iostream.h>
#include "vblib.h"
Soluo recommendada
para strings (2)
void main() {
VBString a;
a = "12345 ";
VBString b("OI");
VBString c(b);
VBString d = a + b;
cout << "VBLib version: " << VBLIB_VERSION << endl;
cout << "d=" << d << endl;
c
c
c
a
equal to b
greater or equal to b
less than or equal to b
not equal b
Strings em C/C++
Retorno de string com VBString
#include <iostream.h>
#include "vblib.h"
/home/usr/fred/public_html
buffer[0]
buffer[1]
buffer[299]
35
VBString (1)
a=123
a=123123
a=123123456
a=1231234567.89
a=abc12
a=abc12.12
a=abc12
a=abc12
entre com algo :abc
a=abc
#include <iostream.h>
#include "vblib.h"
void main() {
VBString a;
a = "123";
cout << "a=" << a << endl;
a = "123" + a;
cout << "a=" << a << endl;
a = a + 456; // int
cout << "a=" << a << endl;
a = a + 7.89111; // double
cout << "a=" << a << endl;
a = "abc";
a += 12;
cout << "a=" << a << endl;
a = "abc";
a += 12.12;
cout << "a=" << a << endl;
a = "abc";
a += "12";
cout << "a=" << a << endl;
a = "abc";
a += VBString("12");
cout << "a=" << a << endl;
cout << "entre com algo:";
cin >> a;
cout << "a=" << a << endl;
}
#include <iostream.h>
#include "vblib.h"
VBString (2)
void main() {
VBString a,b;
a = "123456789";
cout << a << endl;
b = a.beforeFind("56"); // b = "1234";
cout << b << endl;
b = a.afterFind("xx"); // b = ""; // string not found
cout << b << endl;
char *find = "67";
char *replace = "def"; // "12345def89"
36
Converso automtica de
VBString para char*
#include <iostream.h>
#include <string.h>
#include "vblib.h"
void myFun(const char *str) {
cout << "Str:" << str << endl;
}
void myFun2(char *str) {
cout << "Str2:" << str << endl;
}
Str:abc
Str2:abc
Str2:abc
abc
void main() {
VBString a = "abc";
char *p = a.getStr(); // get the char* inside VBString
myFun(a); // automatic conversion of VBString
// myFun2(a); // error. Can't convert
myFun2(p);
myFun2(a.getStr());
char buffer[300];
strcpy(buffer,a); // automatic conversion of VBString
cout << buffer << endl;
}
37
ints
endl; // resultado errado
// type cast garante diviso de floats
endl; // resultado certo
f = 0
f = 0.4
38