初识的美好唯美句子,初识 接下来是什么
写在前面这个应该是c基础知识的最后一部分了,我们前面说了这么多,为后面的类和对象做铺垫。今天主要看两个基础知识。
auto这个关键词是我们在C语言的时候和大家分享的。在C语言中,我们都忽略了这个关键字,但是在C中,这个关键字被赋予了新的特性。
Auto在早期C/C中的作用是指用auto修饰的变量是一个有自动记忆的局部变量,可惜一直没有。
人们使用它。在C 11中,标准委赋予了auto新的含义:**auto **不再是存储类型指示器,而是一种新的类型。
指示编译器auto声明的变量必须在编译时由编译器派生的指示器。
人们说auto可以根据我们给的数据自动推断出应该是什么类型。这一点非常重要。
#包括iostream
使用命名空间std
int main()
{
auto x=1;
auto ch= c
返回0;
}
int TestAuto()
{
返回10;
}
int main()
{
int a=10
汽车b=a;
auto c= a
auto d=TestAuto();
//typeid可以测试变量的类型。
cout typeid(b)。name()endl;
cout typeid(c)。name()endl;
cout typeid(d)。name()endl;
返回0;
}
好了,至此,auto最基本的一点已经讲完了。你可能会困惑。我们可以清楚地定义数据的类型。我们为什么需要汽车?这不是多此一举吗?
为什么会有auto,这是个很好的问题。如果是在C语言中,这个函数真的是鸡肋,但是在C中,如果你学会了模板,你会发现这个auto真的很好用。我先跟你演示一下。如果你看不懂下面的代码也没关系。以后我们都会知道的。这里有一个例子。
看看下面的代码。
int main()
{
std:map std:string,STD:string dict;
dict[ sort ]= sort ;
dict[ string ]= string ;
std:map std:string,STD:string:iterator it=dict . begin();
返回0;
}
变量类型太长,但是我们用auto的时候就不一样了,编译器会自动推送。
int main()
{
std:map std:string,STD:string dict;
dict[ sort ]= sort ;
dict[ string ]= string ;
//std:map std:string,STD:string:iterator it=dict . begin();
auto it=dict . begin();
返回0;
}
我们已经知道了汽车的基本用法。现在我们可以看看它的一些特性。
Auto必须初始化,就像reference一样。我们必须初始化auto修饰的变量,否则它不会编译。
int main()
{
汽车a;
返回0;
}
在同一行中定义多个变量auto可以在同一行中定义多个变量,但是这些变量的类型必须相同,否则将会报告错误。
当在同一行中声明多个变量时,这些变量必须是同一类型的,否则编译器会报告一个错误,因为编译器实际上只
第一种类型是派生的,然后派生的类型用于定义其他变量。
int main()
{
汽车a=1,b=2;
auto c=1.0,b= c//报告错误
返回0;
}
结合auto pointer和reference,我们来看看这两个的用法。
指针:这个我必须跟你仔细分析一下。auto可以推导出指针类型,这是毋庸置疑的。
int main()
{
int a=10
auto pa=a;
cout typeid(pa)。name()endl;
返回0;
}
但是你能看出下面的代码是否正确吗?
int main()
{
int a=10
auto * pa=a;//添加了一个*
cout typeid(pa)。name()endl;
返回0;
}
结果我们看到加*或者不加的效果都是一样的,大家可以选择用哪个。
这里有一段引语。auto不能自动推导出这种类型的引用,这意味着我们必须帮助编译器识别它。
int main()
{
int a=10
auto pa=a;
cout a: a endl;
cout pa: pa endl;
返回0;
}
Auto不是万能的,我们也不能把所有的期望都寄托在编译器身上。auto有以下几个方面是演绎不出来的。
Auto不能用作函数的参数。auto不能直接用于声明数组的基于范围的for循环(C 11)。打印数组时应该怎么做?让我们试一试。
int main()
{
int arr[]={ 1,2,3,4,5,6,7,8,9,10 };
int SZ=sizeof(arr)/sizeof(arr[0]);
for(int I=0;我SZ;我)
{
cout arr[I] ;
}
cout endl
返回0;
}
但是C 11标准出来后,你可以用range for,很简单。
int main()
{
int arr[]={ 1,2,3,4,5,6,7,8,9,10 };
int SZ=sizeof(arr)/sizeof(arr[0]);
for(整数:数组)
{
cout val“”;
}
cout endl
返回0;
}
for range的原理(粗略来说)目前我们还不能完全理解它的原理,只有后面的迭代器可以。现在,我们简单说一下它的原理。
编译器为val打开一个空间,自动获取数组arr中的元素,并将它们的值赋给val,直到编译器觉得数组已经打印出来。
for(auto val:arr)//此处也可以使用auto
{
cout * val“”;
} range for的缺点我们用range for,存在一定的问题。你会发现,它打印的时候,打印的是整个数组,不会停下来。也就是说,编译器控制了整个打印过程。这给我们的加印造成了很大的困难。
的范围无法将数组作为参数打印,并且编译器找不到它可以开始和停止的位置。
void func(int* arr)
{
for(整数:数组)
{
cout val“”;
}
cout endl
}
int main()
{
int arr[]={ 1,2,3,4,5,6,7,8,9,10 };
int SZ=sizeof(arr)/sizeof(arr[0]);
func();
返回0;
}
NULLptrNULLptr和我们C语言中的NULL一样,都是空指针。但是C中的null和nullptr不一样。现在我们来看看C中的null。
现在我们要看看哪个func函数会被调用。
void func(int* p)
{
Cout p是指针 endl
}
void func(int p)
{
Cout p是整数 endl
}
int main()
{
func(NULL);
返回0;
}
我们被愚弄了。NULL不是空指针吗?为什么调用第二个函数?这是不是有点可笑?
NULL本质上是一个宏。我们来看看C对NULL宏的定义。
如果没有定义NULL,如果有宏_ _ cplusplus(C独有),那么将数字0定义为NULL,否则将地址0定义为NULL。也就是说C中的NULL就是数字0.nullptr是一个关键字,它的原理是0地址。
#ifndef NULL
#ifdef __cplusplus
#定义NULL 0
#否则
#define NULL ((void *)0)
#endif
# endifint main()
{
func(nullptr);
返回0;
}
Nullptr特性在使用nullptr表示指针空值时不需要包含头文件,因为nullptr是C 11作为新的关键字引入的。在C 11中,sizeof(nullptr)和sizeof((void*)0)的字节数相同。为了提高代码的健壮性,建议在后续的指针空值表示中使用nullptr。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。