目录
1、C++同一初始化
在C语言中,我们常使用 “ int a = 10 ”,这类等号赋值的方式,对变量进行初始化,但在C++中有多种变量初始化方式。
int a = 10; //a初始化为10
int b(10); //b初始化为10
int c{ 20 }; //c初始化为20
int d = int(10);//d初始化为10
int e = int{ 10 };//e初始化为10
如上,以 int 变量初始化为例,有5种可用的正确的初始化方式。但在日常使用时,如果一次用一种,下次用另一种,就让人眼花缭乱。虽然都是正确的,但不好。所以,统一使用“ int c{ 20 } ”型初始化方式。
对于其他类型数据,这种方法也适用。
struct Student {
char id[10];
char name[10];
int age;
};
int main()
{
double f{ 20.23 };
int nums[]{ 1,2,3,4,5,6 };
struct Student stua{ "123456","zhangsan",15 };
}
2、输入输出
2.1、C语言
在C语言中,通常使用 scanf 与 printf 进行输入、输出。如:
int main(){
int a;
double b;
scanf("%d %lf", &a, &b);
printf(" a = %d, b = %lf", a, b);
return 0;
}
这种方式比较复杂,必须要写成 scanf 与 printf 指定语句格式,还要根据变量类型确定正确的输入格式与输出格式(int 对应 %d,double 对应 %lf ,等等)。
scanf在输入字符串时,存在的问题:
1、不检查输入边界,不安全:若输入字符串长度 >= 字符数组长度,则会产生访问越界。
所以,C语言还提供了scanf_s("%s", buff, len)。len为buff的长度,若输入字符串长度小于len,则输入成功;否则,输入失败,buff内容仍为空。
2、碰见 ' '(空格)就结束输入,不能将空格作为字符串中的一部分。
2.2、C++
C++提供了一种更简便的输入输出方式:cin 与 cout。需调用 <iostream> 库文件,并使用标准命名空间:using namespace std。使用方法如下:
#include<iostream>
using namespace std;
int main() {
int a, b;
cin >> a >> b;
cout << "a=" << a <<",b=" << b <<endl;
}
cin :输入流对象,键盘
>> :提取符
cout :输出流对象,屏幕
<< :插入符
endl :相当于 '\n' ,换行
cin 从键盘(stdin)接收数据 ,提取到">>"指向的变量中。一个 ">>" 跟一个变量,有多个变量时,后续依次添加 ">> 变量名" ,进行变量赋值。
cout 将变量值插入到屏幕(stdout)中,实现打印,并且一个 "<<" 也只跟一个变量。若在cout时,想要进行输出完换行,则在结尾添加 "endl" ,相当于换行符。
此时,cin 相当于 scanf,只是更简便,但在进行字符串输入时,仍未进行长度检查:
但cin 提供 getline(buff, len) 方法进行安全检查,只获取长度 len -1 个数据,并且只以 '\n' 为输入结束标志, 空格 可以作为字符串中的一员输入。
若想要以其他字符替换 '\n' 作字符串输入结束标志,则可以使用 cin.getline(buff, len, char) 的方法,以 char 替换 '\n' 。
3、const
C++中const在指针方面的应用与 const在C语言指针上应用 的大致相同,主要区别在对于常变量的定义上。
3.1、同类型的能力强的指针可赋值给能力弱的指针
例1:
int a = 10, b = 20;
int* p = &a;
const int* s = p;
此时,p为常规 int* 型指针,指向变量a。
而对于s,它首先向右结合 * ,s是一个指针,再被 const 修饰,变成一个常量指针 ,就不可以通过 "*s = x;" 去修改其指向变量的值。所以,此时 s的能力 < p的能力,所以 "const int* s = p;" 正确。
若将顺序调换,用能力小的指针s去初始化赋值能力大的指针p时,程序就会报错。
例2:
int a = 10,b = 20;
int* const p = &a;
int* s = p;
const int* t = p;
此时,p先向左结合 const,p是一个常量,再向左结合 int* ,p是一个指针常量(指针类型的常量),也就是 p 不能进行 "p = &b;" 修改它的指向,但仍可以通过 " *p = 100; " 来将a的值修改为100。
s是一个常规 int* 型指针。
虽然看起来指针p的能力 < 指针s的能力,"int* s = p;" 可能错误,但这样对 s 进行赋值后,s进行" s = &b;" 修改自身指向,并不影响p(p还是指向变量a),所以 "int* s = p;" 是正确的。从两指针解引用能力来看,两指针s、p都可以进行合理范围内的任意解引用访问、修改指向变量的值,二者能力是等大的;只是p只能指向变量a,不可修改指向,如 "p = &b;"。
对于t,t的能力 < p的能力,赋值成功。
3.2、常变量在C与C++中的区别
在C语言中,const修饰的变量以变量为主,只具有常量不可被修改的性质,实质仍是变量。此时,该变量不能用作初始化数组的大小。
在C++中,const修饰的变量以常量为主,拥有常量在编译时被替换与不可修改的性质,但系统仍会给其开辟变量空间,可以像变量般使用(如取地址等)。
C++中const修饰的变量,其常量性质体现的例子:
const int n = 10;//n为常变量
int* p = (int*)&n;//n被强转为普通int型变量,值可被改变
*p = 20; //*p修改n的值
int b = n; //以n的值初始化b
printf("*p = %d,b = %d\n", *p, b);
若在C语言中,此时,n的值为20,*p的值为20,b的值也是20。但在C++中实际结果却是 *p = 20,b = 10。
因为n为常变量,在C++中,在编译时就将有一般情况使用的n的值宏替换为10;虽然 "int *p = (int*)&n;"发生强转,使n的值可以被解引用修改,但这发生在编译、运行之后。
所以,此时实际执行的代码为: