C++ 基础学习 — 可参照C语言学习文章列表

4389199-22b838f84f8b2b83.png
20190130112534.png

C++ 程序结构

让我们看一段简单的代码,可以输出单词 Hello World

文中代码github地址

#include <iostream>
//this is entrance
int main() {
    std::cout << "Hello, World!" << std::endl;//print Hello, World!
    return 0;
}
  • C++ 语言定义了一些头文件,这些头文件包含了程序中必需的或有用的信息。上面这段程序中,包含了头文件 <iostream>
  • 下一行 // this is entrance 是一个单行注释。单行注释以 // 开头,在行末结束。
  • 下一行 int main() 是主函数,程序从这里开始执行。
  • 下一行 cout << "Hello World"; 会在屏幕上显示消息 "Hello World"。
  • 下一行 return 0; 终止 main( )函数,并向调用进程返回值 0。

C++ 关键字

下表列出了 C++ 中的保留字。这些保留字不能作为常量名、变量名或其他标识符名称。

asm else new this
auto enum operator throw
bool explicit private true
break export protected try
case extern public typedef
catch false register typeid
char float reinterpret_cast typename
class for return union
const friend short unsigned
const_cast goto signed using
continue if sizeof virtual
default inline static void
delete int static_cast volatile
do long struct wchar_t
double mutable switch while
dynamic_cast namespace template

C 语言 int main() 和 int main(void) 的区别?

int main(void) 指的是此函数的参数为空,不能传入参数,如果你传入参数,就会出错。

int main() 表示可以传入参数。

// 这样是正确的
int main()
{
  if (0) {main(69)};
}

// 这样会出错
int main(void)
{
  if (0) {main(54)};
}

在 C++ 中 int main() 和 int main(void) 是等效的,但在 C 中让括号空着代表编译器对是否接受参数保持沉默。在 C 语言中 main() 省略返回类型也就相当说明返回类型为 int 型,不过这种用法在 C++ 中逐渐被淘汰。虽然 void main()在很多系统都适用,但他毕竟不是标准的,所以应该避免这种用法, 应该使用这种 int main(void) 的写法比较妥当。

C++ 数据类型

使用编程语言进行编程时,需要用到各种变量来存储各种信息。变量保留的是它所存储的值的内存位置。这意味着,当您创建一个变量时,就会在内存中保留一些空间。

您可能需要存储各种数据类型(比如字符型、宽字符型、整型、浮点型、双浮点型、布尔型等)的信息,操作系统会根据变量的数据类型,来分配内存和决定在保留内存中存储什么。

基本的内置类型

C++ 为程序员提供了种类丰富的内置数据类型和用户自定义的数据类型。下表列出了七种基本的 C++ 数据类型:

类型 关键字
布尔型 bool
字符型 char
整型 int
浮点型 float
双浮点型 double
无类型 void
宽字符型 wchar_t

其实 wchar_t 是这样来的:

typedef wchar_t short int;

所以 wchar_t 实际上的空间是和 short int 一样。

扫描二维码关注公众号,回复: 5184755 查看本文章

一些基本类型可以使用一个或多个类型修饰符进行修饰:

  • signed
  • unsigned
  • short
  • long

下表显示了各种变量类型在内存中存储值时需要占用的内存,以及该类型的变量所能存储的最大值和最小值。

注意:不同系统会有所差异。

类型 范围
char 1 个字节 -128 到 127 或者 0 到 255
unsigned char 1 个字节 0 到 255
signed char 1 个字节 -128 到 127
int 4 个字节 -2147483648 到 2147483647
unsigned int 4 个字节 0 到 4294967295
signed int 4 个字节 -2147483648 到 2147483647
short int 2 个字节 -32768 到 32767
unsigned short int 2 个字节 0 到 65,535
signed short int 2 个字节 -32768 到 32767
long int 8 个字节 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
signed long int 8 个字节 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807
unsigned long int 8 个字节 0 to 18,446,744,073,709,551,615
float 4 个字节 +/- 3.4e +/- 38 (~7 个数字)
double 8 个字节 +/- 1.7e +/- 308 (~15 个数字)
long double 16 个字节 +/- 1.7e +/- 308 (~15 个数字)
wchar_t 2 或 4 个字节 1 个宽字符

从上表可得知,变量的大小会根据编译器和所使用的电脑而有所不同。

如程序所示:

//
// Created by Lenovo on 2019/1/30.
//

#include "cppblogcode.h"
#include<iostream>
#include<string>
#include <limits>
using namespace std;

void print_basic_data_types(){
    cout << "type: \t\t" << "************size**************"<< endl;
    cout << "bool: \t\t" << "Number of bytes occupied" << sizeof(bool);
    cout << "\tmax" << (numeric_limits<bool>::max)();
    cout << "\t\tmin" << (numeric_limits<bool>::min)() << endl;
    cout << "char: \t\t" << "Number of bytes occupied" << sizeof(char);
    cout << "\tmax" << (numeric_limits<char>::max)();
    cout << "\t\tmin" << (numeric_limits<char>::min)() << endl;
    cout << "signed char: \t" << "Number of bytes occupied" << sizeof(signed char);
    cout << "\tmax" << (numeric_limits<signed char>::max)();
    cout << "\t\tmin" << (numeric_limits<signed char>::min)() << endl;
    cout << "unsigned char: \t" << "Number of bytes occupied" << sizeof(unsigned char);
    cout << "\tmax" << (numeric_limits<unsigned char>::max)();
    cout << "\t\tmin" << (numeric_limits<unsigned char>::min)() << endl;
    cout << "wchar_t: \t" << "Number of bytes occupied" << sizeof(wchar_t);
    cout << "\tmax" << (numeric_limits<wchar_t>::max)();
    cout << "\t\tmin" << (numeric_limits<wchar_t>::min)() << endl;
    cout << "short: \t\t" << "Number of bytes occupied" << sizeof(short);
    cout << "\tmax" << (numeric_limits<short>::max)();
    cout << "\t\tmin" << (numeric_limits<short>::min)() << endl;
    cout << "int: \t\t" << "Number of bytes occupied" << sizeof(int);
    cout << "\tmax" << (numeric_limits<int>::max)();
    cout << "\tmin" << (numeric_limits<int>::min)() << endl;
    cout << "unsigned: \t" << "Number of bytes occupied" << sizeof(unsigned);
    cout << "\tmax" << (numeric_limits<unsigned>::max)();
    cout << "\tmin" << (numeric_limits<unsigned>::min)() << endl;
    cout << "long: \t\t" << "Number of bytes occupied" << sizeof(long);
    cout << "\tmax" << (numeric_limits<long>::max)();
    cout << "\tmin" << (numeric_limits<long>::min)() << endl;
    cout << "unsigned long: \t" << "Number of bytes occupied" << sizeof(unsigned long);
    cout << "\tmax" << (numeric_limits<unsigned long>::max)();
    cout << "\tmin" << (numeric_limits<unsigned long>::min)() << endl;
    cout << "double: \t" << "Number of bytes occupied" << sizeof(double);
    cout << "\tmax" << (numeric_limits<double>::max)();
    cout << "\tmin" << (numeric_limits<double>::min)() << endl;
    cout << "long double: \t" << "Number of bytes occupied" << sizeof(long double);
    cout << "\tmax" << (numeric_limits<long double>::max)();
    cout << "\tmin" << (numeric_limits<long double>::min)() << endl;
    cout << "float: \t\t" << "Number of bytes occupied" << sizeof(float);
    cout << "\tmax" << (numeric_limits<float>::max)();
    cout << "\tmin" << (numeric_limits<float>::min)() << endl;
    cout << "size_t: \t" << "Number of bytes occupied" << sizeof(size_t);
    cout << "\tmax" << (numeric_limits<size_t>::max)();
    cout << "\tmin" << (numeric_limits<size_t>::min)() << endl;
    cout << "string: \t" << "Number of bytes occupied" << sizeof(string) << endl;
    // << "\tmax" << (numeric_limits<string>::max)() << "\tmin" << (numeric_limits<string>::min)() << endl;
    cout << "type: \t\t" << "************size**************"<< endl;

};

打印结果如下:

type:           ************size**************
bool:           Number of bytes occupied1       max1            min0
char:           Number of bytes occupied1       max�            min€
signed char:    Number of bytes occupied1       max�            min€
unsigned char:  Number of bytes occupied1       max           min
wchar_t:        Number of bytes occupied2       max65535                min0
short:          Number of bytes occupied2       max32767                min-32768
int:            Number of bytes occupied4       max2147483647   min-2147483648
unsigned:       Number of bytes occupied4       max4294967295   min0
long:           Number of bytes occupied4       max2147483647   min-2147483648
unsigned long:  Number of bytes occupied4       max4294967295   min0
double:         Number of bytes occupied8       max1.79769e+308 min2.22507e-308
long double:    Number of bytes occupied16      max1.18973e+4932        min3.3621e-4932
float:          Number of bytes occupied4       max3.40282e+38  min1.17549e-38
size_t:         Number of bytes occupied8       max18446744073709551615 min0
string:         Number of bytes occupied32
type:           ************size**************

typedef 声明

您可以使用 typedef 为一个已有的类型取一个新的名字。下面是使用 typedef 定义一个新类型的语法:

typedef type newname; 

例如,下面的语句会告诉编译器,feet 是 int 的另一个名称:

typedef int feet;

现在,下面的声明是完全合法的,它创建了一个整型变量 distance:

feet distance;

枚举类型

枚举类型(enumeration)是C++中的一种派生数据类型,它是由用户定义的若干枚举常量的集合。

如果一个变量只有几种可能的值,可以定义为枚举(enumeration)类型。所谓"枚举"是指将变量的值一一列举出来,变量的值只能在列举出来的值的范围内。

创建枚举,需要使用关键字 enum。枚举类型的一般形式为:

enum 枚举名{ 
     标识符[=整型常数], 
     标识符[=整型常数], 
... 
    标识符[=整型常数]
} 枚举变量;
    

如果枚举没有初始化, 即省掉"=整型常数"时, 则从第一个标识符开始。

例如,下面的代码定义了一个颜色枚举,变量 c 的类型为 color。最后,c 被赋值为 "blue"。

enum color { red, green, blue } c;
c = blue;

默认情况下,第一个名称的值为 0,第二个名称的值为 1,第三个名称的值为 2,以此类推。但是,您也可以给名称赋予一个特殊的值,只需要添加一个初始值即可。例如,在下面的枚举中,green 的值为 5。

enum color { red, green=5, blue };

在这里,blue 的值为 6,因为默认情况下,每个名称都会比它前面一个名称大 1,但 red 的值依然为 0。

size_t 在 C 语言中就有了。

它是一种 整型 类型,里面保存的是一个整数,就像 int, long 那样。这种整数用来记录一个大小(size)。size_t 的全称应该是 size type,就是说 一种用来记录大小的数据类型。

通常我们用 sizeof(XXX) 操作,这个操作所得到的结果就是 size_t 类型。

因为 size_t 类型的数据其实是保存了一个整数,所以它也可以做加减乘除,也可以转化为 int 并赋值给 int 类型的变量。

类似的还有 wchar_t, ptrdiff_t

wchar_t 就是 wide char type, 一种用来记录一个宽字符的数据类型 。

ptrdiff_t 就是 pointer difference type, 一种用来记录两个指针之间的距离的数据类型 。

通常,size_t 和 ptrdiff_t 都是用 typedef 来实现的。你可能在某个头文件里面找到类似的语句:

typedef unsigned int size_t;

而 wchar_t 则稍有不同。在一些旧的编译器中,wchar_t 也可能是用 typedef 来实现,但是新的标准中 wchar_t 已经是 C/C++ 语言的关键字,wchar_t 类型的地位已经和 char, int 的地位等同了。

在标准 C/C++ 的语法中,只有

int float char bool

等基本的数据类型,至于 size_t, 或 size_type 都是以后的编程人员为了方便记忆所定义的一些便于理解的由基本数据类型的变体类型。

例如:typedef int size_t; 定义了 size_t 为整型。

int i;                   // 定义一个 int 类型的变量 i
size_t size=sizeof(i);   // 用 sizeof 操作得到变量i的类型的大小
// 这是一个size_t类型的值
// 可以用来对一个size_t类型的变量做初始化

i=(int)size;             // size_t 类型的值可以转化为 int 类型的值
char c='a';              // c 保存了字符 a,占一个字节
wchar_t wc=L'a';         // wc 保存了宽字符 a,占两个字节
// 注意 'a' 表示字符 a,L'a' 表示宽字符 a

int arr[]={1,2,3,4,5};   // 定义一个数组
int *p1=&arr[0];         // 取得数组中元素的地址,赋值给指针
int *p2=&arr[3];
ptrdiff_t diff=p2-p1;    // 指针的减法可以计算两个指针之间相隔的元素个数
// 所得结果是一个 ptrdiff_t 类型

i=(int)diff;             // ptrdiff_t 类型的值可以转化为 int 类型的值

C++ 变量类型

C++ 变量类型与C几乎相同

文中不在讲解,地址C语言学习二 — 变量常量存储类运算符

C++ 变量作用域

可参照此文C语言学习四 — 函数与作用域规则

C++ 全局变量、局部变量、静态全局变量、静态局部变量的区别

C++ 变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为 6 种:全局作用域局部作用域语句作用域类作用域命名空间作用域和文件作用域

1,从作用域看:

全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。

静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。

局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。

静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。

2,从分配内存空间看:

全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。

全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。

  • 1)、静态变量会被放在程序的静态数据存储区(数据段)(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
  • 2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。

从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。

Tips:

  • A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
  • B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
  • C、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;
  • D、如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带“内部存储器”功能的的函数)
  • E、函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

-----------------------------------------------------------------------------------------------------------

static 全局变量:改变作用范围,不改变存储位置

static 局部变量:改变存储位置,不改变作用范围

静态函数 :在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。

如果在一个源文件中定义的函数,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用,这种函数也称为内部函数。定义一个内部函数,只需在函数类型前再加一个“static”关键字即可。

基础知识请看这个系列C语言学习六 — 函数指针,回调函数,字符串与结构体

onst char*, char const*的区别

Bjarne 在他的 The C++ Programming Language 里面给出过一个助记的方法: 把一个声明从右向左读

char  * const cp; ( * 读成 pointer to ) 
cp is a const pointer to char 

const char * p; 
p is a pointer to const char; 

char const * p;

同上因为 C++ 里面没有 const* 的运算符,所以 const 只能属于前面的类型。

C++ 存储类与运算符

C语言学习二 — 变量常量存储类运算符

C++ 循环,判断,函数等

参照C语言学习三 至 十一 ,下方文章列表即可学习。

猜你喜欢

转载自blog.csdn.net/weixin_33897722/article/details/87350437