c/c++易混与技巧

 

调试:

#define DEBUG printf("Passing [%s] in LINE %d\n",__FUNCTION__,__LINE__)

1、c/c++定义数组

int a[N];  //N只能为常量,数值或宏常量

int n;
cin>>n;

int a[n];//或  scanf("%d",&n);  有的编程软件支持,但是不规范!

 

int n;

int a[n];//或  scanf("%d",&n);  

cin>>n;       //编译错误!

 

2、for语句块内if else if可不加括号

3、max函数

c/c++头文件中原本有用宏#define max(a,b) (a>b?a:b)

 

4、字符串

char *p,*h;
    p="qaz";
h="wsx";

5、case里有for语句要加{ },其他的如if可不加

6、矩阵顺时针旋转90°:①final[j][10-i]=start[i][j] ②转置再左右倒换

7、指向顺序内存的指针可以相加减

8、#include<bits/stdc++.h>

包含C++所有头文件

9、取整:

 

浮点数取整或者四舍五入的数据处理情况经常见到,下面做一下总结

注意函数取整返回值均为double型,在用printf输出时应注意

头文件#include<cmath>

 

[cpp] view plain copy

  1. #include<iostream>  
  2. #include<cmath>  
  3. using namespace std;  
  4. int main()  
  5. {  
  6.     double a=2.5;  
  7.     cout<<ceil(a)<<endl;   //向上取整  
  8.     cout<<floor(a)<<endl;   //向下取整  
  9.     cout<<round(a)<<endl;   //四舍五入  
  10.     //不使用函数实现  
  11.     //向下取整  
  12.     cout<<(int)a<<endl;  
  13.     //向上取整  
  14.     cout<<(a>(int)a?(int)a+1:(int)a)<<endl;  
  15.     //四舍五入  
  16.     cout<<(int)(a+0.5)<<endl;  
  17.     return 0;  
  18. }  

10、while(cin>>a)结束条件

int a;
    while(cin>>a)

        cout<<a;

当输入a不为int型是结束

11、int 范围

int占32位的时候,最大可以赋值为:2147483647。也就是0x7fffffff。注意:7的二进制形式最高位为0,如果你对2147483647+1.输出的就是-2147483648。这个数是负数中最大的数,也就是int型可以表示的最小的负数。它的十六进制表示为:0x8fffffff,8的二进制形式最高位是符号位,是1,为负。

12、gets()

回车结束

第一个用法:直接用gets(array's name);这种方式时,由于不知道什么时候才会到字符串结尾,所以每当键入'\n', gets()函数都会自动读取换行符前面的所有内容并且在末尾加上'\0',并且直接把这个字符串返回给调用它的程序,然后gets()再进行读取并且会把读取到的'\n'丢弃,这样下一次读取就会在新的一行开始。

13、64位系统

是可以支持64位地址存储和操作的系统,支持2的64次方大小的内存管理,可以同时对64位的数据进行加法运算

14、指针赋值

int *p,a; //p为指针,值为指向的变量如a的地址,而*p=a,为变量,可以为它赋值

而如果直接*P=a 或*p=3 错,因为指针未初始化p=&a才为初始化,*p表示已经在使用或指针了。

15、strlen

函数返回计算字符串实际长度,即不包括'\0'!!!

16、变量名区分大小写

标识符(变量名、函数名等)区分大小写(eg.add与Add不同,但最好别这样命名)

17、引用定义

int a,&b=a;

18、整型常量

整型常量分为十进制整型常量、八进制整型常量和十六进制整型常量三

种表示形式。

(1)十进制整型常量

这种常量只能出现 0~9 的数字,且可带正、负号。例如:

0 1 364 28 -34

(2)八进制整型常量

这种常量是以数字 0 开头的八进制数字串。其中数字为 0~7。例如:

0111(十进制 73) 011(十进制 9) 0123(十进制 83)

(3)十六进制整型常量

这种常量是以 0x或 0X开头的十六进制数字串。其中每个数字可以是 0~9、a~f或 A~

F 中的数字或英文字母。例如:

0x11(十进制 17) 0Xa5(十进制 165) 0x5a(十进制 90)

19、数组下标越界

程序员的职责是保证不越界而不是追问越界之后会发生什么

访问数组的本质是,访问一段连续内存中的某个单元,只要这个单元的内存是可用的,那么程序就不会崩溃。而会导致内存不可用的原因,通常是操作系统的内存保护机制,也就是说程序会因为访问未分配给他的内存而崩溃。如果没其他对象用到b[10],b[11],b[-1]就不会出错,如果用到就踩内存了。同理指向数组的指针也是一样的,不能越界(指针也是变量)

 

20、派生类函数与基类函数同名

C++标准规定:如果派生类中声明的成员与基类的成员同名,那么,基类的成员会被覆盖,哪怕基类的成员与派生类的成员的数据类型和参数个数都完全不同。

21、

如果你没有声明下列函数,体贴的编译器会声明它自己的版本。这些函数是:一个拷贝构造函数,一个赋值运算符,一个析构函数,一对取址运算符。另外,如果你没有声明任何构造函数,它也将为你声明一个缺省构造函数。所有这些函数都是公有的。换句话说,如果你这么写:

 

class Empty{};

 

和你这么写是一样的:

 

class Empty {

public:

   Empty();                         //缺省构造函数

   Empty(const Empty& rhs);         //拷贝构造函数

 

   ~Empty();                        //析构函数—-是否

                                   //为虚函数看下文说明

   Empty&

   perator=(const Empty& rhs);     //赋值运算符

 

   Empty* operator&();              //取址运算符

   const Empty* operator&() const;

 

};

 

22、全局变量作数组维度

必须加const 否则会报错,而主函数中不用

 

23、||运算符

关系运算符||左边为1则右边就不再执行,同理&&左边为0时右边不再执行

 

24 ~scanf

 

while(~scanf("%d",&n))

<=>  while(scanf("%d",&n)!=EOF)

 

1.正常输入的时候,scanf返回输入的数字如1,2,3等等,对这些数字取非,不会成为0,就会执行循环;

 

2.错误输入指的就是没有输入的时候,scanf返回的是EOF(End Of File),EOF=-1,对EOF取非,就会执行循环

 

25、C++中的auto

转自:https://blog.csdn.net/huang_xw/article/details/8760403

  C++11中引入的auto主要有两种用途:自动类型推断和返回值占位

自动类型推断:


#include <vector>
#include <map>
 
using namespace std;
 
int main(int argc, char *argv[], char *env[])
{
// 	auto a;                 // 错误,没有初始化表达式,无法推断出a的类型
// 	auto int a = 10;        // 错误,auto临时变量的语义在C++11中已不存在, 这是旧标准的用法。
 
	// 1. 自动帮助推导类型
	auto a = 10;
	auto c = 'A';
	auto s("hello");
 
	// 2. 类型冗长
	map<int, map<int,int> > map_;
	map<int, map<int,int>>::const_iterator itr1 = map_.begin();
	const auto itr2 = map_.begin();
	auto ptr = []()
	{
		std::cout << "hello world" << std::endl;
	};
 
	return 0;
};
 
// 3. 使用模板技术时,如果某个变量的类型依赖于模板参数,
// 不使用auto将很难确定变量的类型(使用auto后,将由编译器自动进行确定)。
template <class T, class U>
void Multiply(T t, U u)
{
    auto v = t * u;
}

返回值占位:

template <typename T1, typename T2>
auto compose(T1 t1, T2 t2) -> decltype(t1 + t2)
{
   return t1+t2;
}
auto v = compose(2, 3.14); // v's type is double

使用注意事项

①我们可以使用valatile,pointer(*),reference(&),rvalue reference(&&) 来修饰auto

auto k = 5;
auto* pK = new auto(k);
auto** ppK = new auto(&k);
const auto n = 6;

②用auto声明的变量必须初始化

auto m; // m should be intialized  

③auto不能与其他类型组合连用

auto int p; // 这是旧auto的做法。

④函数和模板参数不能被声明为auto

void MyFunction(auto parameter){} // no auto as method argument
 
template<auto T> // utter nonsense - not allowed
void Fun(T t){}

⑤定义在堆上的变量,使用了auto的表达式必须被初始化

int* p = new auto(0); //fine
int* pp = new auto(); // should be initialized
 
auto x = new auto(); // Hmmm ... no intializer
   
auto* y = new auto(9); // Fine. Here y is a int*
auto z = new auto(9); //Fine. Here z is a int* (It is not just an int)

⑥以为auto是一个占位符,并不是一个他自己的类型,因此不能用于类型转换或其他一些操作,如sizeof和typeid

int value = 123;
auto x2 = (auto)value; // no casting using auto
 
auto x3 = static_cast<auto>(value); // same as above 

⑦定义在一个auto序列的变量必须始终推导成同一类型
auto x1 = 5, x2 = 5.0, x3='r';  // This is too much....we cannot combine like this

⑧auto不能自动推导成CV-qualifiers(constant & volatile qualifiers),除非被声明为引用类型

const int i = 99;
auto j = i;       // j is int, rather than const int
j = 100           // Fine. As j is not constant
 
// Now let us try to have reference
auto& k = i;      // Now k is const int&
k = 100;          // Error. k is constant
 
// Similarly with volatile qualifer

⑨auto会退化成指向数组的指针,除非被声明为引用

int a[9];
auto j = a;
cout<<typeid(j).name()<<endl; // This will print int*
 
auto& k = a;
cout<<typeid(k).name()<<endl; // This will print int [9]

26、获取静态数组与动态数组长度

a、对于字符数组:strlen() 注意:不包括'\0'

b、对一般静态数组: 为 sizeof(a)/ sizeof(a[0]) 即数组占用的总字节数/每个元素占用的字节数

c、动态数组(vector等)用.size()函数

27、求平均值防止溢出

10  二进制  1010
14  二进制  1110
    公共部分: 1010
不同部分的和: 0100
不同部分除以2:0010
平均数 = 1010(相同部分) + 0010(不同部分的平均数) = 1100
因此二者平均数为12

    以上的操作我们可以用位运算来替代:

  1. 公共部分 = a & b

  2. 不同部分的平均值 = (a ^ b) >> 1

  3. 平均值 = 公共部分 + 不同部分的平均值 = (a & b) + ((a ^ b) >> 1)

    由此,我们直接就可以避免整数加法造成的溢出。仔细观察会发现,如果整数一个奇数一个偶数,我们的答案就向下取整了。因此如果有需要,我们可以根据 a 和 b 的奇偶情况,手动的添加0.5来修正答案。

 

28、unique()函数是把不重复的元素移到前面来

4替换第二个3(a[3]仍然为4)...

29、printf()的类型输出符

printf中“ ”里的%的类型输出符应与右方输出值类型一一对应,如

int a=10;

printf("%f",a); //类型不匹配!输出结果会出现乱码!(%f值是类型输出符,并不会自动类型转换)

要把int型转换为float型输出,得手动强制类型转换

printf("%f",(float)a);

30、控制台结束ctrl+z

要使控制台遇EOF结束,可输入ctrl+z,但前提是ctrl+z之前无其他字符,除回车

abc ^z//这个无法结束,吧^z也当做字符

abc

^z

才会结束

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值