找的c++基础知识

来源:互联网 发布:淘宝导航栏代码生成器 编辑:程序博客网 时间:2024/05/16 09:49


一  C++基础知识
1.1  "Hello, world!" 
C++对于大小写是敏感的。
首先,让我们通过一个非常简单的C++程序,来初步地了解C++语言。
#include <iostream>
using namespace std;// 注意如果不使用.h将要增加本行
int main() 
{
    cout << "Hello, world!" << endl; return 0;
} ///:~
这个程序的作用就是在屏幕上输出“Hello, world!”的字样。
以“#”开始的内容被称为预处理指令,这一行的作用是把一个叫做iostream的头文件包含到我们的程序中来。C++默认是不包含任何头文件的。另外,C语言中的头文件都是以.h结尾的,而标准的C++提倡使用没有扩展名的头文件。
第四行让我们可以在程序中直接使用std名字空间内的标识符。std名字空间包含了所有标准C++提供的类和函数,为了简便起见,一般总在包含头文件的预处理命令后写上这一行。如果是C语言的话,程序将变成:
#include <iostream.h>
int main() 
{
    printf(“%s\n”,"Hello, world!");
 return 0;
} ///:~
1.2 类型
C++提供了基本类型以及程序员可以自定义的类型:
 
名称 C++类型 范围 大小   
布尔型 bool true / false 1  
字符型 char 所有单字节字符 1   
8位有符号整型 char -128 .. 127 1   
8位无符号整型 unsigned char0 .. 255 1  
16位有符号整型 short-32768 .. 32767 2  
16位无符号整型 unsigned short0 .. 65535 2  
32位有符号整型 int -2147483648 .. 2147483647 4  
32位无符号整型 unsigned int0 .. 4294967295 4  
64位有符号整型 long long-263 .. 263-1 8  
64位无符号整型 unsigned long long0 .. 264-1 8  
单精度浮点型 float 1.17e-38 .. 3.40e38 4  
双精度浮点型 double 2.22e-308 .. 1.79e308 8  
扩展浮点型 long double3.36e-4932 .. 1.18e4932 10/12 
在C++中,很多其他类型的量都可以隐式地转化为布尔型,这时,非零的值都被转化成true,而零被转化成false。
其中VC中没有long long类型,可用_int64代替,sizeof的作用就是返回括号里的类型的大小(也可以是变量或者常量)。
单个字符的常数要用单引号括起来,一些不能显示的字符可以通过转义符来表示(参见下表)。另外,从上表中可以看出,在C++中,字符型和单字节的整型实际上是等价的。举例来说,'A'的数值就是65。
 
名称 ASCII名称 C++名称   
换行 NL(LF) \n   
水平制表符 HT \t   
竖直制表符 VT \v   
退格 BS \b  
回车 CR \r  
复位 FF \f  
铃声 BEL \a   
反斜杠 \ \\  
问号 ? \? 


1.3 操作符
首先,我们来看下表:
 
操作符名称 C++操作符   
加法 +   
减法 -   
乘法 *   
整数除法 /   
实数除法 /   
取余数 %   
小于 <   
小于等于 <=   
大于 >   
大于等于 >=   
相等 ==   
不等 !=   
位非 ~   
逻辑非 !   
位与 &   
逻辑与 &&   
位或 |   
逻辑或 ||   
位异或 ^   
位左移 <<   
位右移 >>  
从中可以看出,C++语言最大的特点就是几乎所有的操作符都是由符号字符构成的。注意:
1、C++中,整数除法和实数除法都是由“/”来完成的,当两个操作数都是整数时进行整数除法,当至少有一个是实数时进行实数除法;
2、C++中,位运算与逻辑运算的操作符是不同的。
1.4 常用的库函数和格式输出
标准C++提供了十分强大的库。在这一节,我们只介绍一些和Pascal所提供的标准过程和函数功能相似的库函数。
 
函数定义 头文件 作用 备注   
void* memset(void* p, int b, size_t n); cstring把p所指向的连续n个字节的值都设置成b 与FillChar类似,但要注意参数的顺序  
void* memmove(void* p, const* q, size_t n); cstring 把q所指向的连续n个字节的值复制到p所指向的位置与Move类似,p、q所指向的内存区域可以部分重叠   
double atof(const char* p);
int atoi(const char* p);
long atol(const char* p); cstdlib把字符串p转化成所表示的数 与Val类似  
double fabs(double); cmath绝对值函数 与Abs类似  
double ceil(double);
double floor(double); cmath取整函数,前者为上取整,后者为下取整   
double sqrt(double); cmath平方根函数 与Sqrt类似  
double pow(double d, double e); cmath幂函数,返回d的e次方   
double sin(double);
double cos(double);
double tan(double); cmath三角函数   
double asin(double);
double acos(double);
double atan(double); cmath反三角函数   
double atan2(double y, double x); cmath增强型反正切函数,返回点(x, y)的辐角 很有用,会根据点所在的象限调整弧度值  
double sinh(double);
double cosh(double);
double tanh(double); cmath双曲函数   
double exp(double); cmath指数函数,以e为底 与Exp类似  
double log(double);
double log10(double); cmath对数函数,前者以e为底,后者以10为底 与Ln类似 
另外,标准C++中并没有提供函数Pi,要获得Pi的值一般这样做:
const double pi = acos(0.) * 2;
格式化输出
具体参考C++语言等相关书籍
C++的流可以完成控制格式的操作。指定场宽由成员函数width()来完成,而指定小数部分的位数则稍微麻烦一些,要先把浮点数的输出方式设置为定点输出方式,然后再设置小数部分的位数。例如:
cout.setf(ios::fixed, ios::floatfield);
cout.precision(2);
cout << 1.2345 << endl;
以上程序段中第一个语句的作用就是把浮点数的输出方式设置为定点输出方式,第二个语句的作用是把小数部分的位数设置为2。和Pascal一样,小数部分的最后一位也会进行四舍五入的处理。
需要注意的是,width()只对接下来的一个格式化输出有效,如果有多个输出需要指定场宽,那么就要写多个width()函数。而precision()则对之后所有的浮点数输出都有效。例如:
cout.width(3);
cout << 1 << 2;  // 1的场宽为3,而2采用实际宽度
cout.width(4);
cout << 2;
如果你觉得这样写太麻烦,你也可以把它写成:
cout << setw(3) << 1 << 2 << setw(4) << 2;
不过这时不要忘了在程序的最前面加上#include <iomanip>,因为setw是在iomanip中被定义的。
这样,我们就可以完成一般的格式化输出了。C++中流的格式化输出还有很多内容,如果有兴趣可以参考有关资料。


1.5 例子
要求:每个程序在全部弄懂的前提下,自己编写一次(可以上网AC的都要尽量通过)
例1:http://acm.timus.ru/problem.aspx?space=1&num=1000  A+B Problem
Calculate a + b 
输入:  a and b
输出:  a+b
Sample Input
1 5
Sample Output
6
程序:
C++:
#include <iostream>
using namespace std;
int main()
{
    int a,b;
    while(cin >> a >> b)
        cout << a+b << endl;
}
 //cin和cout是iostream里面的东西
C:
#include <stdio.h>
int main()
{
    int a,b;
    while(scanf("%d %d",&a, &b) != EOF)
        printf("%d\n",a+b);
}
  注意一般程序要求你多次输入的!!  printf和scanf是stdio.h里面的东西,注意C语言里面没有类的存在,只有函数。
这两个函数要熟练使用的,慢慢来也行,具体见《C和C++帮助》


例2:1到n求和
输入:n 代表一个非负整数 1=<n<=10000
输出:1到n求和
Sample Input
100
Sample Output
5050
程序:
C:
#include<stdio.h>
int n,sum;
int main()
{
while (scanf("%d",&n)!=EOF)
{
sum=n*(n+1)/2;
printf("%d",sum);
}
return 0;
}
C++:
#include<iostream>
using namespace std;
int n,sum;
int main()
{
while (cin>>n)
{
sum=n*(n+1)/2;
cout<<sum<<endl;
}
return 0;
}
例3:判断一个数是不是素数 1<N<=50000
Sample Input
100
31
Sample Output
NO
YES
程序:
#include<iostream>
#include<cmath>
using namespace std;
bool tf(int n)
{
int i;
for(i=2;i<sqrt(n);i++)
  if (n%i==0) return false;
    return true;
}
int main()
{
int n;
while (cin>>n)
{
if(tf(n))
  cout<<"YES"<<endl;
else
        cout<<"NO"<<endl;
}
return 0;
}
例4 求两个数的最大公约数和最小公倍数
Sample Input
12 18
Sample Output
6 36
程序:
#include<iostream>
#include<cmath>
using namespace std;
int gcd(int n,int m) //求最大公约数的递归函数
{
if(m==0) return n;
else  return gcd(m,n%m);
}
int main()
{
int n,m,g;
while (cin>>n>>m)
{
g=gcd(n,m);
        cout<<g<<' '<<m*n/g<<endl;
}
return 0;
}
例5 排序
输入:n个整数的序列 1=<n<=10000   第一行输入n,第二行输入n个整数
输出:排好序的序列
Sample Input
5
1 5 3 2 4
Sample Output
1 2 3 4 5
程序一(顺序排序):
#include<iostream>
using namespace std;
int n,a[10001];
void sxpx(int *a)//顺序排序函数 
{
int i,j,temp; 
for(i=1;i<=n;i++)
  for(j=i+1;j<=n;j++)
    if(a[i]>a[j])
    {
    temp=a[i];
    a[i]=a[j];
    a[j]=temp;
    }
}
int main()
{
while (cin>>n)
{
        int i;
for(i=1;i<=n;i++) cin>>a[i];
sxpx(a);
cout<<a[1];
        for(i=2;i<=n;i++) cout<<' '<<a[i];
        cout<<endl;
}
return 0;
}
程序二(快速排序):必懂算法
#include<stdio.h>
int a[10000];
int n;
void quicksort(int s,int t)//总的思想就是第s个节点派到它最后应该排的位置;
{
int i,j,x,t1;
i=s;j=t;x=a[i];
while (i<j)
{
while ((a[j]>=x)&&(j>i)) j=j-1;
if (j>i) { t1=a[i]; a[i]=a[j];a[j]=t1;}
while ((a[i]<=x)&&(i<j)) i=i+1;
if (i<j) { t1=a[j];a[j]=a[i];a[i]=t1;}
}
a[i]=x;
i=i+1;j=j-1;
if (s<j)  quicksort(s,j);
if (i<t)  quicksort(i,t);
}
int main()
{
while (EOF!=scanf("%d",&n))  //也可是这样写:->  while (EOF!=0)
{                                              {
for (int p=0;p<n;p++)                               scanf("%d",&n);
scanf("%d",&a[p]);                             for (int p=0;p<n;p++)
quicksort(0,n-1);                                      scanf("%d",&a[p]); 
for (p=0;p<n;p++)                                  quicksort(0,n-1);
printf("%d ",a[p]);                                 for (p=0;p<n;p++) 
}                                                   printf("%d ",a[p]);
return 0;                                         }
}
比较以上两种排序的方法,哪个比较快呢? 快速排序比较难理解,可以分两步理解:
1 :开数据结构的书,看懂手工是怎么操作的
2 : 自己写一组数据,单步跟踪一下,看看数据怎么变化的。
初学时,单步跟踪很重要!!!!!!
如果上面蓝色的字体你都做到了,好了,恭喜~!!你已经具有自学的能力了,加油加油,以后很多算法只要做这两个工作就行了,再加上一些相关的习题训练就可以灵活运用算法了,再进一步就是成为大牛~~说远了,加油~~
这里插入STL的使用,可以使用系统的排序函数(具体参考相关STL的资料):
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n;
int main()
{
while (cin>>n)
{
        int i,x;
        vector<int> a;//a是一个容器
for(i=1;i<=n;i++)
{
cin>>x;
   a.push_back(x);//往容器中塞东西
}
sort(a.begin(),a.end());
cout<<a[0];
        for(i=1;i<n;i++) cout<<' '<<a[i];
        cout<<endl;
}
return 0;

例6:http://acm.stu.edu.cn/cgi-bin/problem_cn?id=3020 级数求和
[问题描述]:
  已知:Sn= 1+1/2+1/3+…+1/n。显然对于任意一个整数K,当n足够大的时候,Sn大于K。
  现给出一个整数K(1<=k<=15),要求计算出一个最小的n;使得Sn>K。
[输入文件]
输入有多组测试数据,每组一行,一个数 k
[输出文件]
输出有多组数据,每组一行,一个数n。
[输入样例]
 1
[输出样例]
 2
程序:
#include<iostream>
using namespace std;
int main()
{
int k;
while (cin>>k)
{
        double s=1.0;
int n=1;
        while(s<=k)
        {
        n++;
        s+=1.0/n;
        }
        cout<<n<<endl;
}
return 0;
}
建议C和C++语言两个版本都自己编写提交
例7:http://acm.zju.edu.cn/show_problem.php?pid=2482 IP Address
简单的说就是8个0或1为一个数,要你转化为十进制数(但是要注意格式)
Suppose you are reading byte streams from any device, representing IP addresses. Your task is to convert a 32 characters long sequence of '1s' and '0s' (bits) to a dotted decimal format. A dotted decimal format for an IP address is form by grouping 8 bits at a time and converting the binary representation to decimal representation. Any 8 bits is a valid part of an IP address. To convert binary numbers to decimal numbers remember that both are positional numerical systems, where the first 8 positions of the binary systems are:
 
27 26 2524 23 22 21 20  
128 64 32 16 84 2 1  


Input
The input will have a number N (1 <= N <= 9) in its first line representing the number of streams to convert. N lines will follow.
Output
The output must have N lines with a doted decimal IP address. A dotted decimal IP address is formed by grouping 8 bit at the time and converting the binary representation to decimal representation.
Sample Input
4
00000000000000000000000000000000
00000011100000001111111111111111
11001011100001001110010110000000
01010000000100000000000000000001
Sample Output
0.0.0.0
3.128.255.255
203.132.229.128
80.16.0.1
算法解释:
简单说就是考两个点:1:字符串的操作  2:数制转化
#include<stdio.h>
#include<string.h>
const int d[8]={128,64,32,16,8,4,2,1};
int main()
{
int n,i,j,k,x;
int a[4];
char s[33];
while (scanf("%d",&n)!=EOF)
{
for (i=1;i<=n;i++)

    scanf("%s",&s);
    memset(a,0,sizeof(a));//a中所有元素都为0
    for (j=0;j<4;j++)
    {
    for(k=0;k<8;k++)
    if (s[j*8+k]=='1')
           a[j]+=d[k];
            }
            for (j=0;j<3;j++) printf("%d.",a[j]);
            printf("%d\n",a[3]);
}
}
return 0;
}
例8: http://acm.stu.edu.cn/cgi-bin/problem_cn?id=4026  What is Left
My lovely sister QingQing has many books. One day she numbers her books with integer. Of cause same books are marked by the same number. When all the books are marked, it is easy to find how many are the same J
Now QingQing  has a list of books( given by numbers they are marked). In order to buy a gift for her dear brother, she plans to sell some books.  But she wants to keep one copy for each kind. After selling, what books will be left ? Please write a program to tell QingQing the answer.
Input
First line is an number N(1<=N<=50000), meaning the books that QingQing has before selling.
Next line will contain N numbers, the marks of the books, separated by a single space.
(the marks are between 0 and 999, inclusively)
Output
A line for each test case contains the marks of the books after selling. (sorted in non-descending order).
Two numbers are separated by a single space.
Sample Input
5
1 2 5 4 5
2
1 2
Sample Output
1 2 4 5
1 2
算法分析:
sample第一组数据的解释是:5本书,它们的编号分别是1 2 5 4 5 ,问有多少种书,明显是四种,要你列出来而且要编号从小到大列出来。
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
int n,i,x;
bool a[1000],k;
char s[33];
while (cin>>n)
{
memset(a,0,sizeof(a));
for (i=1;i<=n;i++) 
{
cin>>x;
a[x]=true;
}
k=true;
for(i=0;i<999;i++)
{
if (a[i])
{
if(k){ cout<<i;k=false;}
else cout<<' '<<i;
}
}
cout<<endl;
}
return 0;
}
例9:http://acm.stu.edu.cn/cgi-bin/problem_cn?id=1059 Points In Line(集训题III-几何)
问题描述: 
    给出平面上的n(3<=n<=100)个点的坐标,(x1,y1),(x2,y2),...,(xn,yn),请编写程序判断这n个点,是否都在同一条直线上。所有坐标的取值范围[-100,100]。 
输入格式: 
    每行分别有2n+1个整数,第一个表示:n,后面连续2n个分别表示:x1,y1,x2,y2,...xn,yn。有多个测试数据。 
输出格式: 
    如果输入中给出的n个点共线,则输出"YES",否则输出"NO",每行一个输出。 
输入样例: 
3 1 1 2 2 -1 -1 
4 0 1 0 0 -5 5 7 1 
输出样例: 
YES
NO
算法分析:斜率一样就YES,但是注意计算机可能表示的精度有限,所以判断斜率一样要这样: 
这是公式:    的转化
程序:
#include<iostream>
using namespace std;
struct node
{
int x;
int y;
}list[100];
int main()
{
int n,i;
bool k;
while(cin>>n)
{
k=false;
for(i=0;i<n;i++) cin>>list[i].x>>list[i].y;
for(i=2;i<n;i++)
 if ((list[1].x-list[0].x)*(list[i].y-list[0].y)!=(list[i].x-list[0].x)*(list[1].y-list[0].y))
     {
      k=true;
      break;
     }
        if (k) cout<<"NO"<<endl;
        else cout<<"YES"<<endl;
}
return 0;
}
例10http://acm.stu.edu.cn/cgi-bin/problem_cn?id=3002 赋值问题
问题描述
在很多程序设计语言中,忘记给变量赋初值的错误常令人头疼。 在下面的问题中,最开始仅有变量a中有确定的值。变量为单个小写字母, 每行恰好有三个字符,中间一个是赋值运算符'='。 请编程求出含N行的程序段运行以后有哪些变量中有确定的值。 
输入: 第一行:N (0<N<=10^6) 以下N行,每行3个字符,为一条语句
              有多组测试数据,直到输入结束为止。
输出: 如果没有,输出 none 否则在一行中按字母表顺序给出所有有确定值的变量名。
              每输出一组数据要换行。
输入:
4
b=a
c=d
d=b
e=f
2
a=c
d=b
输出:
a b d
none
程序(from prinse):
C++的
#include <iostream>
using namespace std;
const int N = 1000000;
const int M = 26;
char a[M] = { 1 }, b[M];
int main() {
  int i, k, n;
  char ch1, ch2, ch3;
  while (cin>>n) {
    for (i=0; i<n; i++) {
      cin>>ch1>>ch2>>ch3;
      a[ch1-'a'] = a[ch3-'a'];
    }
    for (i=k=0; i<M; i++) if (a[i]) { b[k++] = i; a[i] = 0; }
    a[0] = 1;
    if (!k)
      cout<<"none";
    else {
      for (i=0; i<k-1; i++) cout<<char(b[i]+'a')<<' ';
      cout<<char(b[k-1]+'a');
    }
    cout<<endl;
  }
  return 0;
}
 
C语言:
#include <stdio.h>
#include <string.h>
const int M = 5, a = 'a', z = 'z';
int n, s[z+1];
char c[M];
int main() {
  int i, k;
  for (s[a]=1; scanf("%d",&n)!=EOF; s[a] = 1) {
    getchar();  // 因为后面是RAW输入, 故留在缓冲中的空白符被处理为输入数据
                // 有趣的是, 虽然 gets 是RAW输入, 但它却同时除掉分隔符
    for (i=0; i<n; i++) { gets(c); s[c[0]] = s[c[2]]; }
    for (k=0,i=a; i<=z&&!s[i]; i++);
    if (i<=z) { k=1; putchar(i); }
    for (i++; i<=z; i++) if (s[i]) { putchar(' '); putchar(i); }
    if (!k) puts("none"); else putchar('\n');
    memset(s,0,sizeof s);
  }
  return 0;
}
通过不断地练习,最终达到熟练掌握C++和C语言的目的。单单以上10个例子远远不足,更多的简单程序见相关的“例子”书籍。
0 0
原创粉丝点击