1.c++初始化

在我们学习c语言的时候初始化都是

int a=10;
int ar[10]={1,2,3,4,5,6,7,8,9,10};
struct Student
{
	char s_id[20];
	char s_name[20];
	char s_sex[20];
	char s_age[20];
};
struct Student s1={"2024001","zl","man",12 };

c++中我们通常用{}进行初始化

int b(10);
int c{ 10 };//对所有的方式进行初始化
int d = int(10);
int e = int{ 10 };
int ar[10] = { 1,2,3,4,5,6 };//未初始化是的后面是0
 //			   0 1 2 3 4 5 6 7 8 9
int br[10]{ 1,2,3,4,5,6 };
struct Student
{
	char s_id[20];
	char s_name[20];
	char s_sex[20];
	char s_age[20];
};
struct Student s1{"2024001","zl","man",12 };
int* p{ NULL };

NULL和nullptr的区别?

特性 NULL nullptr
本质 宏定义(通常是整数 0 或 (void*) 0) C++11+ 关键字(专门的空指针标识)
类型 无独立类型(int 或 void*) std::nullptr_t(独立类型)
类型安全 弱(可转整数 / 指针,易歧义) 强(仅可转指针,不可转整数)
函数重载歧义 有(可能匹配整数版本) 无(仅匹配指针版本)
语义清晰度 低(本质是 0,需人工联想空指针) 高(直接表示空指针,无歧义)
适用标准 C++ 所有版本、C 语言 C++11 及以上
模板编程适配 差(推导类型可能错误) 好(类型明确,推导准确)

2.输入输出

int main()
{
	const int Strlen = 32;
	char stra[Strlen] = {};
	char strb[Strlen] {};
	//scanf("%s", stra);//' '\n
	//scanf_s("%s", stra, sizeof(stra));
	//两个区别
	//fgets(stra, Strlen, stdin);//\n
	cin >> stra;
	cout << stra;
	cin.getline(stra, Strlen);//31  \0   \n字符串的结束
	cin.getline(stra, Strlen, '#');//以#作为字符串结束的标志
}
int main()
{
	int a = 0;
	char ch = '\0';
	cin >> a >> ch;

	cout << a <<" " << ch <<endl;
	return 0;
}

3.const关键字

1.const在C语言和c++中的区别?

const int LEN = 10;
int ar[LEN];   //错误   c++可以

在C语言中,const是以变量为主,定义时必须对其初始化

2.指针与const的两种结合方式

 const在*左侧:修饰指针指向的内容(内容不可被修改)

int a = 10;
const int* p = &a;  // const 在*左侧,限制“指向的内容”

// 验证规则:
p = &b;    // 合法!指针本身可改(可以换指向的地址)
*p = 20;   // 编译错误!指向的内容不可改(不能通过指针改a的值)

const在*右侧:修饰指针变量本身(指针指向不可修改)

int a = 10;
int* const p = &a;  // const 在*右侧,限制“指针本身”,必须初始化

// 验证规则:
*p = 20;   // 合法!指向的内容可改(a的值会变成20)
p = &b;    // 编译错误!指针本身不可改(不能换指向其他地址)

结合讲解:

int main() {
    const int a = 10;  // 常变量a,值不可改

    // 1. int *p1 = &a; 
    // 错误(error):p1是“普通int变量”,&a是“const int*指针”,类型不匹配,不能把指针赋值给普通变量。

    // 2. const int *p2 = &a;
    // 合法(ok):p2是“指向常变量的指针”(const在*左侧,限制内容),可以指向常变量a(符合“保护常变量”的规则)。

    // 3. int *const p3 = &a;
    // 错误(error):p3是“指针常量”(const在*右侧,限制指针本身),但它是“普通指针(无const内容限制)”,不能指向常变量a(否则可能通过p3修改a的值,违反常变量定义)。

    // 4. const int *const p4 = &a;
    // 合法(ok):p4是“指向常变量的指针常量”(*左右都有const),既限制指针指向,又限制内容修改,可安全指向常变量a。

    // 5. int *p5 = (int*)&a;
    // 编译能过(ok),但不安全:通过“强制类型转换”把“const int*”转成“int*”,绕过了编译器的类型检查。
    // 风险:后续若通过p5修改*p5,会直接修改常变量a的值,违反const语义(C++标准未定义这种行为,可能导致程序崩溃)。

    
int main() {
    int a = 10, b = 20;
    int *p = &a;  // 普通指针p(无任何const限制)

    // 1. int *s1 = p;
    // 合法(ok):s1和p都是“普通指针”,类型完全一致,直接赋值。

    // 2. const int *s2 = p;
    // 合法(ok):s2是“指向常变量的指针”(能力比p收缩:p能改内容,s2不能改),符合“能力强→能力收缩”的规则。
    // 本质:给指针“加限制”(从“能改内容”变成“不能改”),是安全的。

    // 3. int *const s3 = p;
    // 合法(ok):s3是“指针常量”(能力比p收缩:p能改指向,s3不能改),符合“能力强→能力收缩”的规则。
    // 本质:给指针“加限制”(从“能改指向”变成“不能改”),是安全的。

    // 4. const int *const s4 = p;
    // 合法(ok):s4是“指向常变量的指针常量”(能力比p收缩:p能改内容+指向,s4都不能改),符合“能力强→能力收缩”的规则。
    // 本质:给指针“加双重限制”,是最安全的赋值。
}

4.引用

引用的定义:类型&引用变量名称=变量名称;

特点:

	int a = 10;
	int& ra = a;//1.定义引用必须初始化
	//int& rb = NULL;//not  2.空引用   3.没有引用的引用
	double dx = 12.23;
	double& rx = dx;

引用作为形参代替指针:

void Swap(int* ra, int* rb)
{
	assert(ra != NULL && rb != NULL);
	int temp = *ra;
	*ra = *rb;
	*rb = temp;
}
void Swap(int& ra, int& rb)
{
	int temp = ra;
	ra = rb;
	rb = temp;
}
int main()
{
	int ar[10] = { 1,2,3,4,5,6 };
	int(&rar)[10] = ar;
    int a=10;
    int *p=&a;
    int *&rp=p;//对指针加引用
	int(*p)[10] = &ar;//数组引用
}

使用引用代替指针的好处就是不存在NULL引用,不需要判空,比指针安全。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐