printf and scanf. In any
event, they are clearly functions, and you should be able to
understand them as such, though we don't yet know what those
functions do. Programs will look much the same, compiling is
similar (though you use a C compiler, like gcc, instead of a C++
compiler, like g++), and running a compiled program is no
different at all.
| ex0.c | ex0.cpp |
~$ gcc -o ex0 ex0.c -lm ~$ ./ex0 Enter name, height and weight: chris 73 190 A 10' tall chris would weigh 843.973400 pounds. |
~$ g++ -o ex0 ex0.cpp ~$ ./ex0 Enter name, height and weight: chris 73 190 A 10' tall chris would weigh 843.973400 pounds. |
new and delete operatorsistreams and
ostreams for input and output.
bool foo(int k) { return k*k > 5; }
double foo(double z) { return 1.5 + sqrt(z); }
... can exist in the same program. Because, for example, if you
make a call
like foo(3*i+1), where i is
an int, the compiler will deduce that 3*i+1
is an int and know to call the first function.
As (1) states, C tends not base its behavior on deducing types
and, indeed, function overloading is illegal in C - there may
not be two functions with the same name.
| C | C++ | ![]() |
void swap(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
} |
void swap(int& a, int& b)
{
int t = a;
a = b;
b = t;
} |
|
. . . if (x > y) swap(&x,&y); |
. . . if (x > y) swap(x,y); |
string datatypechars,
with one special caveat: One of the elements of the array has
to be the special char '\0', known as the "null
character". The actual sequence of characters represented
consists of all the char's from the beginning of the array up
to, but not including, that '\0'.
So, for example, the string "hello" is represented by the array:
In fact, even in C++ string literals are actually C-style
strings like this, so "hello" is exactly the array
of chars you see above. This means you could write a function
to compute the length of a C-style string like this:
int strlen(char* s)
{
int i = 0;
while(s[i] != '\0')
i++;
return i;
}
Fortunately, this function and a number of other useful
functions for manipulating strings are defined in the standard C
library string.h
#include "string.h"
int main()
{
char* s = "hello";
int n = strlen(s); /* sets n to 5 */
return 0;
}
Challenge: can you write a function that takes a C-style
string and determines whether it is a palindrome?
Important: String literals like
"foobar" are C-style strings, even in C++!
That's why "foo" + "bar" doesn't do concatenation
even through s + t does (where s
and t are variables of type string).
cin >> var;in C++. Which characters are actually read in from the input stream as a result of this depends completely on the type of
var. Same with output.
cout << int(42) and
cout << char(42) cause different output based
purely on the type of the right-hand side.
As described above, C doesn't operate
this way. So I/O is handled in a fundamentally different way.
There is a function printf to print output,
and scanf to read input.
printf("Hello World\n");
This first argument may include "format specifiers", which are
not literally printed, but rather refer to a subsequent
argument to printf, whose value is printed rather than the
format string itself. These start with a %, followed by one
or more characters indicating the type of argument object it
is referring to, and possibly also how that object should be
formatted. For example, to print integer x in decimal you
might use printf like this:
printf("x = %d\n",x);
If x were 42, this would output
x = 42
| A few common format specificiers |
%d Integer Format Specifier%c Character Format Specifier%s String Format Specifier%lf Double Format Specifier
|
scanf("%d",&x);
Scanf gets a pointer to x, which it can use to
modify the actual variable x in the calling
function, for example like this: *p = 42;
To reiterate, this is necessary because C does not have
pass-by-reference.
To tell the caller whether the read was successful, scanf
returns the number of items successfully read in.
In the example above, there was only the one item to read
in (the %d), so scanf will return 1 if
successful, and 0 if not.
With these pieces in place, we can look at the
classic problem of reading in numbers and outputting the
average, which compares in C vs. C++ like this:
| ex1.c | ex1.cpp |
dist (42,7.5)... you could use the call
scanf("dist (%lf,%lf)",&x,&y);,
and the "dist (" would literally have to appear in the input,
followed by a floating point value, and so on.
One gotcha is that while whitespace in front of the input
matching %lf is skipped, whitespace in front of the
literal text, like "dist (" is not.
However, a literal space in the format string matches any number
of spaces, including 0. So by putting a space before "dist",
we skip over any leading whitespace, including newlines.
It also means that the space between "dist" and "(" is optional
in the input: there can be no spaces in between, one space, or
many spaces.
| ex1.c | compile & run |
$ clang -o ex4 ex4.c -lm $ ./ex4 command: dist (2,3) 3.605551 command: dist (-3,9.2) 9.676776 command: dist ( 1, 1.2) 1.562050 command: dist(2.2,9.8) 10.043904 command: x bye. |
struct Foo {
int k;
char c;
};
void print(struct Foo f) {
printf("%d:%c\n",f.k,f.c);
}
int main() {
struct Foo joe;
joe.k = 42;
joe.c = 'f';
print(joe);
...