listindexoutofbounds was outside the bounds of the array.

Index was outside the bounds of the array是什么错误?怪事
[问题点数:20分,结帖人flashasp]
Index was outside the bounds of the array是什么错误?怪事
[问题点数:20分,结帖人flashasp]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
本帖子已过去太久远了,不再提供回复功能。当前位置: &
求翻译:index was outside the bounds of the array是什么意思?
index was outside the bounds of the array
问题补充:
指数超出了数组界限
数组下标越界了。一编程错误。比如 int[] a=new int[5]; 然后你写a[5]=10;,因为a数组最后一个是a[4],下标超出范围了,就报错
指数超出了数组界限
指数的范围之外是数组
索引是在列阵的区域之外
指数是数组的界限之外
正在翻译,请等待...
我来回答:
参考资料:
* 验证码:
登录后回答可以获得积分奖励,并可以查看和管理所有的回答。 |
我要翻译和提问
请输入您需要翻译的文本!7622人阅读
SilverLight(5)
今天在SL中遇到了Index was outside the bounds of the array.这个错误,对比了不同的类,调试了近2个小时,未发现类的异常。
于是重建dbml文件,测试通过,可能是在dbml文件进行多次修改时,有些类进行了多次创建导致的。
当然,错误源是来自:System.Data.Linq
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:200001次
积分:3633
积分:3633
排名:第5167名
原创:159篇
转载:18篇
评论:41条
(1)(1)(1)(1)(1)(2)(2)(1)(4)(1)(1)(1)(2)(2)(7)(2)(1)(1)(3)(1)(1)(1)(1)(4)(2)(1)(1)(2)(3)(2)(1)(3)(4)(1)(5)(1)(2)(6)(35)(22)(1)(1)(3)(6)(3)(5)(2)(1)(2)(2)(7)(7)(5)(1)How to Program in C++
How to Program in C++
You may copy this file for noncommercial use.
The latest version
is located at
Apr. 14, 2010.
Please report errors to Matt Mahoney at
Seldom-used features have been deliberately omitted.
if, for, while, return, break...
arithmetic, comparison, assignment...
The most important types are
int, char, bool, double, and the containers string, vector,
Summary of common types:
Description
Fastest integer type (16-32 bits), also short, long, unsigned
8-bit character, '\0' to '\xFF' or -128 to 127
64 bit real + or - 1.8e308, 14 significant digits, also float
true or false
Description
Non-modifiable object
, y is an alias for x, which both have type T
T f(...) {...}
Defines f as a
returning T
to T (*p is a T object)
of N elements of T, a[0] to a[N-1]
Place x in data segment
(rare) Hint to optimize for speed
(rare) x may be modified externally
The following standard library types and functions require at the
beginning of the program:
#include &header>
Description
Standard input (cin)
Output (cout, cerr, clog)
Input file
Output file
Sequence of char
Expandable array/stack of T
Array/double ended queue
List/stack/queue of T
map&T1,T2>
Associative mapping of T1 to T2
A map with keys only
pair&T1,T2>
Two objects of type T1 and T2
map or utility
priority_queue&T>
Sorted queue
Array of N bool with logical operations
valarray&T>
Array with arithmetic operations
complex&T>
Complex number
Pointer into a container
(Included with container)
const_iterator
Pointer not allowing element assignment (Included with container)
Hierarchy of exception types
min(), max(), swap(), sort(), copy(), equal()
accumulate(), inner_product()
back_inserter()
equal_to(), less(), bind2nd()
set_new_handler()
atoi(), atof(), abs(), rand(), system(), exit()
isalpha(), isdigit(), tolower(), toupper()
sqrt(), log(), exp(), pow(), sin(), cos(), atan()
clock(), time()
strlen(), memset(), memmove(), memcmp()
printf(), fopen(), getc(), perror()
C++ allows you to create your own types and libraries.
important type is a , allowing object oriented
programming.
A class is an abstract data type with a hidden
representation and a set of public member functions and types.
Classes can be organized into a hierarchy (), and you
can write code that accepts any type in this hierarchy ().
Functions and classes can be parameterized by type (templated).
Defines T as a collection of types, objects, and member functions
template &class T> ... Defines a set of
over all T
Defines type U is a synonym for T
Defines T as an int, and set of int constants
T {...}; Like a class, except default scope of members is public
A struct with object members overlapping in memory
Defines a scope for a collection of types, objects, and functions
(compiling, linking, make)
// Empty statement
of 0 or more statements is a statement
// If t is true then s
// else is optional
// Loop 0 or more times
// s1; while (t) {s; s2;}
// Jump from while, for, do, switch
// Return x to calling function
// Throw exception, abort if not caught, x has any type
catch (T y) {s;}
// if x has type T then y=x, jump to s
catch (...) {s;}
// else jump here (optional)
while (t);
// (uncommon) while (t)
// (uncommon) Start next loop of while, for, do
switch (i) {
// (uncommon) Test int expression i to const C
// if (i==C) go here
// optional, else go here
// (rare) Jump to label within a function
A statement may be a declaration or an expression.
Objects and
types declared in a block are local to that block.
(Functions cannot be defined locally).
It is normal (but not required) to
show statements on separate lines and to indent
statements enclosed in a block.
If braces are optional, we indent anyway.
For instance,
// start of block
int a[10], i=0,
// declaration
// expression
// end of block, a, i, and j are destroyed
declares the array of int a with elements a[0]
through a[9] (whose values are initially undefined),
i with initial value 0, and j
with an undefined initial value.
These names can only be used in scope,
which is from the declaration to the closing brace.
Convert x to type T using defined conversions
(rare) Convert x to equivalent but non-const T
(rare, dangerous) Pretend x has type T
(rare) Convert base pointer or reference to derived if possible
(rare) If x is type T, then typeid(x)==typeid(T) (in &typeinfo>)
3 (right to left)
Contents of pointer p, or p[0].
If p is type T*, *p is T
Address of (pointer to) x.
If x is type T, &x is T*
Negative of numeric a
Not i, true if i is false or 0
Bitwise compliment of i, -1 - i
Convert (cast) object x to type T (by static, const, or reinterpret)
Convert, initializing with 0 or more arguments
Create a T object on heap, return its address as T*
new T(x,y)
Create, initializing with 0 or more arguments
(rare) Initialize T at address p without allocating from heap
new(p) T(x,y)
(rare) Initialize T with 0 or more arguments at p
Create array of i objects of type T, return T* pointing to first element
Destroy object pointed to by p obtained with new T or new T()
delete[] p
Destroy array obtained with new T[]
Add 1 to i, result is the new i
Subtract 1 from i, result is the new i
Size of object x in bytes
Size of objects of type T in bytes
(rare) Object in x pointed to by pointer to member p
(rare) Object in *q pointed to by pointer to member p
Multiply numeric a and b
Divide numeric a and b, round toward 0 if both are integer
Integer remainder i-(i/j)*j
Addition, string concatenation
Subtraction
Integer x shifted y bits to left, or output y to ostream x
Integer x shifted y bits to right, or input y from istream x
Greater than
Less than or equal to
Greater than or equal to
Not equals
Bitwise AND of integers i and j
Bitwise XOR of integers i and j
Bitwise OR of integers i and j
i and then j (evaluate j only if i is true/nonzero)
i or else j (evaluate j only if i is false/zero)
15 (right to left)
Assign y to x, result is new value of x
x=x+y, also -= *= /= %= &= |= ^= &&= >>=
If i is true/nonzero then x else y
Throw exception x (any type)
Evaluate x and y (any types), result is y
Expressions that don't require creating a new object, such as a=b, ++a,
p[i], p->m, x.m, a?b:c, a,b etc. are lvalues, meaning they
may appear on the left side of an assignment.
Other expressions and conversions create temporary objects to hold the
result, which are const (constant).
An expression used as a
statement discards the final result.
// Legal, add a and b, discard the sum
// Legal, assign c to b, then assign the new b to a
(a+=b)+=c;
// Legal, add b to a, then add c to a
// Error, a+b is const
double(a)=b; // Error, double(a) is const
The most important types are int,
bool, char, and double.
Integer types
false (0) or true (1)
signed char
'\x80' to '\x7f' (-128 to 127)
unsigned char
'\x00' to '\XFF' (0 to 255)
Usually signed
-32768 to 32767
unsigned short
0u to 65535U
Usually - to
unsigned int
Usually 0 to U
At least -l to L
unsigned long
0ul to at least LU
Floating point types
-1.7e38f to 1.7E38F, 6 significant digits
-1.8e308 to 1.8E308, 14 significant digits
long double
At least double
There are implicit conversions between all types.
When types are
mixed in an expression, both operands are converted to the type
that has the higher upper bound, but at least to int.
This conversion
only loses representation when mixing signed and unsigned types.
// 1, int division rounds toward 0
// 1.75, implicit double(4) = 4.0
'\x05'+true
// 6, implicit int('\x05') = 5, int(true) = 1
// false, implicit (unsigned int)(-1) = 232-1
Conversion from a floating point type to an integer type drops the
decimal part and rounds toward 0.
If the value is outside the range
of the target, then the result is undefined.
Conversion of one integer type to another is performed modulo the
range of the target.
For a B-bit number (except bool), we add or
subtract 2B to bring the value within range.
of a 2's complement number, we drop the most significant bits and
reinterpret the sign bit without changing any bits).
any nonzero value is true.
(unsigned char)(-1)
// '\xff' (255)
short a=x;
// x5678 hex
// Sum of all elements
v.shift(n)
// Move all v[i] to v[i+n], shift in 0
v.cshift(n)
// Move v[i] to v[(i+n) % v.size()]
v.resize(n)
// Change size to n, but reset all elements to 0
v.resize(n, x)
// Change size to n, set all elements to x
class MyError: public exception {
MyError(const string& msg=""): exception(msg) {}
, iterators should define the following
5 public typedefs:
iterator_category: one of the following (defined in &iterator>):
output_iterator_tag
(if sequential writing is supported)
input_iterator_tag
(if sequential reading is supported)
forward_iterator_tag (if both are supported)
bidirectional_iterator_tag
(if the iterator can be decremented)
random_access_iterator_tag
(if all pointer operations are supported)
value_type: the type of the elements, for example, T
difference_type: the result of iterator subtraction, usually ptrdiff_t (a signed int type)
pointer: the type returned by operator->(), usually T* or const T*
reference: the type returned by operator*(), usually T& or const T&
Operator -> should be overloaded as a unary function returning a
pointer to a class to which -> will be applied, i.e. x->m is
interpreted as x.operator->()->m.
Nested class members
are named Outer::Inner::member.
Outer and inner classes cannot access
each other's private members.
Templated members defined outside the
class need their own template declarations.
template &class T> class Vector {
// Reverse iterator for Vector, i.e. ++p goes to the previous element.
class reverse_iterator {
// Points to current element
// typedefs needed to work with &algorithm> functions
typedef std::random_access_iterator_tag iterator_
// Defined in &iterator>
typedef T value_
// Type of element
typedef ptrdiff_t difference_
// Result of iterator subtraction, usually int
typedef T*
// Type returned by operator ->
typedef T&
// Type returned by operator *
reverse_iterator(T* a=0): p(a) {}
// Implicit conversion from T* and iterator
iterator base() const {}
// Convert to normal iterator
// Forward operators
reverse_iterator& operator++() {--p; return *} // prefix
reverse_iterator
operator++(int);
// postfix, we pretend it's binary
reference operator*() const {return *p;}
pointer operator->() const {}
// We pretend it's unary
bool operator==(Vector&T>::reverse_iterator b) const {return p==b.p;}
bool operator!=(Vector&T>::reverse_iterator b) const {return p!=b.p;}
// Also, bidirectional and random operators
reverse_iterator rbegin() {return end()-1;}
reverse_iterator rend() {return begin()-1;}
// Other members...
// Code for postfix ++
template &class T>
inline Vector&T>::reverse_iterator Vector::reverse_iterator::operator++(int dummy) {
Vector&T>::reverse_iterator result = *
// Print a Vector in reverse order
int main() {
Vector&int> a(10);
for (Vector&int>::reverse_iterator p=a.rbegin(); p!=a.rend(); ++p)
cout && *p &&
vector&T> supplies random
reverse_iterator and const_reverse_iterator
Const iterators would typedef pointer as const T*
and reference as const T&.
A static data member is shared by all instances of a class.
It must be initialized in a separate declaration, not in the class definition
or in the constructor initialization list.
A static member function
cannot refer to this or any
non-static members (and therefore it makes no sense to make them
Static members may be referenced either as
object.member or class::member.
class Counter {
// Number of Counters that currently exist (private)
static int get() {}
Counter() {++}
~Counter() {--}
Counter(const Counter& c) {++}
// Default would be wrong
Counter& operator=(const Counter& c) {return *}
// Default would be OK
int Counter::count = 0;
// Initialize here, OK if private
Counter a, b,
cout && b.get();
cout && Counter::get();
Inheritance
Inheritance is used to write a specialized or enhanced version of
another class.
For example, an ofstream is a type of
class D: public B defines class D as
derived from (subclass of) base class (superclass) B,
meaning that D inherits
all of B's members, except the constructors, destructor, and assignment
The default behavior of these special member functions is to treat
the base class as a data member.
class String: public Vector&char> {
String(const char* s=""): Vector&char>(strlen(s)) {
copy(s, s+strlen(s), begin());
// Inherits Vector&char>::begin()
String a="hello"; // Calls Vector&char>::Vector(5);
// 5, inherits Vector&char>::size()
// "jello", inherits Vector&char>::operator[]
String b=a;
// Default copy constructor uses Vector's copy constructor on base part
// Default = calls Vector's assignment operator on base part
The default destructor String::~String() {} is correct,
since in the process of destroying a String, the base is also
destroyed, calling Vector&char>::~Vector() {delete data[];}.
Since there is no need to write a destructor, there is no need to
redefine copying or assignment either.
Although String inherits Vector&char>::data,
it is private
and inaccessible.
A protected member is accessible to derived
classes but private elsewhere.
protected:
// Declare class B and object b
// Error, x is protected
class D: public B {
void f() {x=1;}
By default, a base class is private, making all inherited members
Private base classes are rare and typically used as
implementations rather than specializations (A string is a vector,
but a stack is not).
class Stack: Vector&int> {
// or class Stack: private Vector&int>
bool empty() const {return size()==0;}
// Error, private
s.empty();
// OK, public
A class may have more than one base class (called multiple
inheritance).
If both bases are in
turn derived from a third base, then we derive from this root class using
virtual to avoid inheriting its members twice further on.
Any indirectly derived class treats the virtual root as a direct base
class in the constructor initialization list.
class ios {...};
// good(), binary, ...
class fstreambase: public virtual ios {...};
// open(), close(), ...
class istream: public virtual ios {...};
// get(), operator>>(), ...
class ifstream: public fstreambase, public istream {
// Only 1 copy of ios
ifstream(): fstreambase(), istream(), ios() {...}
// Normally ios() would be omitted
Polymorphism
Polymorphism is the technique of defining a common interface for a
hierarchy of classes.
To support this, a derived object is allowed
wherever a base object is expected.
For example,
String s="Hello";
Vector&char> v=s;
// Discards derived part of s to convert
Vector&char>* p=&s;
// p points to base part of s
try {} catch(Vector&char> x) {}
// Caught with x set to base part of s
s=Vector&char>(5);
// Error, can't convert base to derived
// Allow output of Vector&char> using normal notation
ostream& operator && (ostream& out, const Vector&char>& v) {
copy(v.begin(), v.end(), ostream_iterator&char>(out, ""));
// Print v to out
// To allow (cout && a) &&
// OK, v refers to base part of s
ofstream f("file.txt");
// OK, ofstream is derived from ostream
A derived class may redefine inherited member functions, overriding any
with the same name, parameters, return type, and const-ness (and hiding
other functions with the same name, thus the overriding function should
not be overloaded).
The function call is resolved at compile time.
This is incorrect in case
of a base pointer or reference to a derived object.
To allow run time
resolution, the base member function should be declared virtual.
the default destructor is not virtual, a virtual destructor should
be added to the base class.
If empty, no copy constructor or assignment
operator is required.
Constructors and = are never virtual.
class Shape {
virtual void draw()
virtual ~Shape() {}
class Circle: public Shape {
void draw()
// Must use same parameters, return type, and const
S s.draw();
// Shape::draw()
C c.draw();
// Circle::draw()
Shape& r=c; r.draw();
// Circle::draw() if virtual
Shape* p=&c; p->draw();
// Circle::draw() if virtual
p=new C p->draw();
// Circle::draw() if virtual
// Circle::~Circle() if virtual
An abstract base class defines an interface for one or
more derived classes, which are allowed to instantiate objects.
Abstractness can be enforced by using protected (not private) constructors
or using pure virtual member functions, which must be overridden in
the derived class or else that class is abstract too.
A pure virtual
member function is declared =0; and has no code defined.
class Shape {
protected:
// Optional, but default would be public
virtual void draw() const = 0; // Pure virtual, no definition
virtual ~Shape() {}
// Circle as before
// Error, protected constructor, no Shape::draw()
Shape& r=c; r.draw();
// OK, Circle::draw()
Shape* p=new Circle();
Run time type identification
C++ provides for run time type identification, although this usually
indicates a poor design.
dynamic_cast&T>(x) checks at run time whether a base pointer
or reference is to a derived object, and if so, does a conversion.
The base class must have at least one virtual function to use run time
type checking.
#include &typeinfo>
// For typeid()
typeid(*p)==typeid(T)
// true if p points to a T
dynamic_cast&T*>(p)
// Convert base pointer to derived T* or 0.
dynamic_cast&T&>(r)
// Convert base reference to derived T& or throw bad_cast()
For example,
class B {public: virtual void f(){}};
class D: public B {public:}
// Bad design, public member in D but not B
B* p=&d; p->x;
// Error, no B::x
D* q=p; q->x;
// Error, can't convert B* to D*
// OK, but reinterpret_cast, no run time check
q=dynamic_cast&D*>(p); if (q) q->x;
Other Types
typedef defines a synonym for a type.
typedef char* S
// Str is a synonym for char*
Str a, b[5], *c;
// char* char* b[5]; char**
char* d=a;
// OK, really the same type
enum defines a type and a set of symbolic
values for it.
There is an implicit conversion to int and explicit
conversion from int to enum.
You can specify the int equivalents of
the symbolic names, or they default to successive values beginning
Enums may be anonymous,
specifying the set of symbols and possibly objects without giving the
type a name.
enum Weekday {MON,TUE=1,WED,THU,FRI};
// Type declaration
enum Weekday today=WED;
// Object declaration, has value 2
// true, implicit int(today)
today=Weekday(3);
// THU, conversion must be explicit
enum {N=10};
// Anonymous enum, only defines N
// OK, N is known at compile time
enum {SAT,SUN} weekend=SAT;
// Object of anonymous type
A struct is a class where the default protection is
public instead of private.
A struct can be initialized like an
struct Complex {double re,};
// Declare type
Complex a, b={1,2}, *p=&b;
// Declare objects
a.re = p->
// Access members
A union is a struct whose fields overlap in memory.
Unions can also be anonymous.
They may be used to implement variant records.
union U {};
// sizeof(U) is larger of int or double
// overwrites u.d
// A variant record
class Token {
enum {INT, DOUBLE}
// which field is in use?
// An anonymous union
void print() const {
if (type==INT) cout && value.i;
else cout && value.d;
An enum, struct, class, or union type and a list of objects may
be declared together in a single statement.
class Complex {public: double re,} a, b={1,2}, *p=&b;
Program Organization
For C++ programs that only use one source code file and the
standard library, the only rule is to declare things before using them:
type declarations before object declarations, and function declarations
or definitions before calling them.
However, implicitly inlined member
may use members not yet declared, and templates may use names as long
as they are declared before instantiation.
class Complex {
double real() const {}
double re,
Global and member functions (unless inlined or templated) and global
or class static objects are separately compilable units, and may appear
in separate source code (.cpp) files.
If they are defined and used
in different files, then a declaration is needed.
To insure that
the declaration and definition are consistent, the declaration should
be in a shared header file.
A shared header conventionally has a
.h extension, and is inserted with a
#include "filename.h", using double quotes to indicate
that the file is in the current directory.
Global variables are
declared with extern without initialization.
// prog1.cpp
// prog2.cpp
#include "prog.h"
#include "prog.h"
int main() {
To compile,
g++ prog1.cpp prog2.cpp -o prog
This produces two object files (prog1.o, prog2.o), and then links
them to produce the executable prog.
g++ also accepts .o
files, which are linked only, saving time if the .cpp
file was not changed.
To compile without linking, use -c.
To optimize (compile slower but run faster), use -O.
The UNIX make command updates the executable as needed based
on the timestamps of source and .o files.
It requires a file
named Makefile containing a set of dependencies of the form:
file: files which should be older than file
(tab) commands to update file
Dependencies may be in any order.
The Makefile is executed repeatedly
until all dependencies are satisfied.
# Makefile comment
prog: prog1.o prog2.o
g++ prog1.o prog2.o -o prog
prog1.o: prog1.cpp prog.h
g++ -c prog1.cpp
prog2.o: prog2.cpp prog.h
g++ -c prog2.cpp
Compiler options for g++.
Other compilers may vary.
g++ file1.cpp
Compile, produce executable a.out in UNIX
g++ file1.cpp file2.o
Compile .cpp and link .o to executable a.out
Turn on all warnings
g++ -c file1.cpp
Compile to file1.o, do not link
g++ -o file1
Rename a.out to file1
Optimize executable for speed
Verbose mode
Equivalent to #define X Y
g++ --help
Show all g++ options
gxx file1.cpp
Compile in Windows MS-DOS box (DJGPP) to A.EXE
Anything which is not a separately compilable unit may appear in
a header file, such as class definitions (but not function code unless
inlined), templated classes (including function code), templated
functions, and other #include statements.
Creating Libraries (namespaces)
Libraries usually come in the form of a header and an object (.o)
To use them, #include "header.h" and link the .o
file using g++.
If the .o was compiled in C rather than C++,
then indicate this with extern "C" {} to turn off name mangling.
C++ encodes or "mangles" overloaded function names to allow them to be linked,
but C does not since it doesn't allow overloading.
extern "C" {
// Turn off name mangling
#include "header.h"
// Written in C
When writing your own library, use a unique namespace name to prevent
conflicts with other libraries.
A namespace may span multiple
Types, objects, and functions declared in a namespace N must
be prefixed with N:: when used outside the namespace, or there must
be a using namespace N; in the current scope.
Also, to guard against possible multiple
inclusions of the header file, #define some symbol and test
for it with #ifndef ... #endif on the first and last lines.
Don't have a using
, since the user may not want std visible.
#ifndef MYLIB_H
// mylib.h, or use #if !defined(MYLIB_H)
#define MYLIB_H
#include &string>
// No using statement
namespace mylib {
std::string f();
// No code
// mylib.cpp, becomes mylib.o
#include &string>
#include "mylib.h"
namespace mylib {
string B::f() {return "hi";}
#define could be used to create constants through text substitution,
but it is better to use const to allow type checking.
#define X Y has the effect of replacing symbol X with
arbitrary text Y before compiling, equivalent to the g++ option -DX=Y.
Each compiler usually defines a different set of symbols, which
can be tested with #if, #ifdef, #ifndef, #elsif, #else,
and #endif.
#ifdef unix
// Defined by most UNIX compilers
Preprocessor statements are one line (no semicolon).
They perform
text substitutions in the source code prior to compiling.
#include &header>
// Standard header
#include "header.h"
// Include header file from current directory
#define X Y
// Replace X with Y in source code
#define f(a,b) a##b
// Replace f(1,2) with 12
#define X \
// Continue a # statement on next line
// True if X is #defined
// False if X is #defined
#if !defined(X)
// Optional after #if...
// Required
History of C++
C++ evolved from C, which in turn evolved from B, written by Ken
Thompson in 1970 as a variant of BCPL.
C was developed in the 1970's
by Brian Kernighan and Dennis Ritchie as a "portable assembly language"
to develop UNIX.
C became widely available when they published "The
C Programming Language" in 1983.
C lacked standard containers (string,
vector, map), iostreams, bool, const, references, classes, exceptions,
namespaces, new/delete, function and operator overloading, and
object-oriented capabilities.
I/O was done using &stdio.h>.
Strings were implemented as
fixed sized char[] arrays requiring functions to assign or compare them
(strcpy(), strcmp()).
Structs could not be assigned, and had to be
copied using memcpy().
Function arguments were not type checked.
Functions could only modify arguments by passing their addresses.
Memory allocation was done using malloc(), which requires the number of
bytes to allocate and returns an untyped pointer or NULL if it fails.
The language allowed unsafe implicit conversions such as int to pointers.
Variables had to be declared before the first statement.
no inline, so macros were often used in place of small functions.
Hardware was slow and optimizers were not very good, so it was common
to declare register variables.
There were no // style comments.
For instance,
/* Copy argv[1] to buf and print it */
#include &stdio.h>
/* No cout, use printf()
#include &string.h>
/* No string type, use char*
#include &stdlib.h>
/* No new/delete, use malloc/free
main(argc, argv)
/* Return type defaults to int */
/* Old style parameter declaration, no type checking */
/* No namespace std
/* All declarations before the first statement
if (argc>1) {
buf=(char*)malloc((strlen(argv[1])+1)*sizeof(char));
/* Cast optional
strcpy(buf, argv[1]);
/* Can't assign, no range check
printf("%s\n", buf);
/* Arguments not type checked
free(buf);
/* No delete */
/* Return value is undefined (unchecked)
The ANSI C standard was finished in 1988.
It added const,
new style function declaration with type checking, struct assignment,
strict type checking of pointer assignments,
and specified the standard C library, which until now was widely used
but with minor, annoying variations.
However, many compilers did not
become ANSI compliant until the early 1990's.
In the 1980's Bjarne Stroustrup at AT&T developed "C with Classes", later C++.
Early implementations were available for UNIX as cfront (cc), a
C++ to C translator around 1990.
It added object oriented programming with
classes, inheritance, and polymorphism, also references, the iostream
library, and minor enhancements such as // style comments and the ability
to declare variables anywhere.
Because there were no namespaces,
the iostream header was named &iostream.h> and no using
statement was required.
Unlike C programs which always have a .c extension,
C++ didn't say, so .cpp, .cc
and .C were all common, and .hpp for headers.
GNU gcc and g++, which compiled C and C++
directly to machine code, were developed in the early 1990's.
were added in 1993.
Exceptions were added in 1994.
The standard
container library (originally called the standard template library
or STL) was developed by researchers at Hewlett-Packard and made
available free as
a separate download in the mid 1990's and ported to several compilers.
ANSI standard C++ compilers became available in 1998.
This added
STL to the standard library, added multiple inheritance, namespaces,
type bool, and run time type checking (dynamic_cast, typeid).
.h extension on headers was dropped.
C++ most likely succeeded where other early object oriented languages
failed (Simula67, Actor, Eiffel, SmallTalk) because it was backwards
compatible with C, allowing old code to be used, and because C programmers
could use it immediately without learning the new features.
However, there
are a few incompatibilities.
Old style function declarations are not allowed.
Conversion from void* (returned by malloc()) requires
There are many new reserved words.
There are also some incompatibilities between old (before 1998)
and new versions of C++.
new was changed to throw type bad_alloc if out
of memory, instead of returning 0.
The scope of a variable declared in a for loop was changed
to be local to the loop and not beyond it (not yet implemented by
Microsoft Visual C++)
g++ does not yet implement all ANSI C++ features.
For instance,
Type ostringstream allowing formatted writing to strings.
Run time bounds checking of vector indexes using v.at(i)
The largest integer type is 32 bits in most implementations, but
as 64 bit machines become common it is possible that type long
could become a 64 bit type (as in Java) in the future.
g++ supports the nonstandard 64-bit integer type long long, e.g.
unsigned long long bigzero=0LLU;
Most implementations of time() return the number of seconds since
Jan. 1, 1970 as a time_t, normally a signed 32-bit long.
Programs that use this implementation will fail on Jan. 19,
2038 at 3:14:08 AM as this value overflows and becomes negative.
Further Reading
Brian W. Kernighan, The C Programming Language, 2nd Ed.,
Prentice Hall, 1988.
Bjarne Stroustrup, The C++ Programming Language, 3rd Ed,,
Addison Wesley, 1997.
Andrew Koenig, Barbara E. Moo, Accelerated C++,
Addison Wesley, 2000.

我要回帖

更多关于 indexoutofbounds 的文章

 

随机推荐