第2章 C/C++快速入门

2.5.2 冒泡排序

整个过程执行n-1趟,每一趟从左到右一次比较相邻的两个数,如果大的数在左边,则交换这两个数,当该趟结束时,该趟最大的数被移动到当前剩余数的最右边。
第二个for循环的理解:当第i趟时,从a[0]到a[n-i-1]都需要与下一个数进行比较。

代码(C++):

#include "stdafx.h"

#include <stdio.h>

int main(){

int a[10]={3,1,4,5,2};

for(int i=1;i<=4;i++){  //进行n-1趟

//第i趟时从a[0]到a[n-i-1]都与它们下一个数进行比较

for(int j=0;j<5-i;j++){

if(a[j]>a[j+1]){  //如果左边的数更大,则交换a[j]和a[j+1]

int temp=a[j];

a[j]=a[j+1];

a[j+1]=temp;
}
}
}
for(int i=0;i<5;i++){
printf("%d ",a[i]);
}

return 0;

}

输出结果:
1 2 3 4 5

2.5.4 memset——对数组中每一个元素赋相同的值

memset函数的格式为:
memset(数组名,值,sizeof(数组名)); //需要添加string.h头文件
【注1】只建议初学者使用memset赋0或-1,因为它使用的是按字节赋值。如果要对数组赋其他数字(例如1),则使用fill函数(但memset的执行速度快)。
【注2】vs2012实现for、if语句括号自动补全:按tab+enter

代码(C++):
#include <stdio.h>
#include <string.h>
int main(){
    int a[5]={1,2,3,4,5};
    //赋初值0
    memset(a,0,sizeof(a));
    for (int i=0;i<5;i++){
        printf("%d ",a[i]);
    }
    printf("\n");
    //赋初值-1
    memset (a,-1,sizeof (a));
    for (int i = 0; i < 5; i++)
    { 
        printf("%d ",a[i]);
    }
        printf("\n");
        getchar ();  //避免vs运行时闪退
        return 0;

}

输出结果:
0 0 0 0 0
-1 -1 -1 -1 -1

2.5.5 字符数组

(1)scanf输入,printf输出
(2)getchar和putchar分别用来输入和输出单个字符

代码(C++):
#include<stdio.h>
#include <stdlib.h>
int main()  {
   char str[5][5];
   for (int i = 0; i < 3; i++)
   {
       for (int j = 0; j < 3; j++)
       {
           str[i][j]=getchar();
       }
       getchar();//这句是为了把输入中每行末尾的换行符吸收掉
   }

    for (int i = 0; i < 3; i++)
   {
       for (int j = 0; j < 3; j++)
       {
        putchar(str[i][j]);
       }
        putchar('\n');
   }
    system ("pause");
    return 0;
}

运行结果(与教材有偏差):
输入:

_
_

输出:

_
_

(3)gets输入,puts输出
gets用来输入一行字符串,以\n结束;puts用来输出一行字符串,以\n结束。

代码(C++):
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
int main(){
    char str1[20];
    char str2[5][10];
    gets(str1);
    for (int i = 0; i < 3; i++)
    {
        gets(str2[i]);
    }
    puts(str1);
    for (int i = 0; i < 3; i++)
    {
        puts(str2[i]);
    }
    getchar();//由于建立的是空项目,若不添加这句,输入之后黑窗口闪退
    return 0;
}

运行结果:
输入与输出相同
woaiderenbuairen
qaq
t_t
woaini

2.5.6 string.h头文件

(1)strlen:得到第一个\0前的字符的个数,格式:
strlen(字符数组);
int len=strlen(str);
(2)strcmp():返回两个字符串数组的大小比较结果,比较原则是按字典排序,格式:
strcmp(字符数组1,字符数组2);

代码(C++):
#include <stdio.h>
#include <string.h>
int main(){
    char str1[50],str2[50];
    gets(str1);
    gets(str2);
    int cmp=strcmp (str1,str2);
    if(cmp<0)
        printf ("str1<str2\n");
    else if(cmp>0)
        printf ("str1>str2\n");
    else 
        printf ("str1+str2\n");
    getchar ();//避免输入字符串之后黑窗闪退
    return 0;
}

运行结果:
输入字符串:
Dear Mozart
Canon
输出:
str1>str2
(3)strcpy():把一个字符串复制给另一个字符串,格式:
strcpy(字符数组1,字符数组2);
【注】是把字符数组2复制给字符数组1,这里的“复制”包括了结束符\0。
(4)strcat():把一个字符串接到另一个字符串后面,格式:
strcat(字符数组1,字符数组2);
【注】是把字符数组2接到字符数组1后面。

2.5.7 sscanf与sprintf

sscanf(str,"%d",&n);
上面sscanf写法的作用是把字符数组str中的内容以"%d"的格式写到n中(从左往右)。

代码(C++):
#include <stdio.h>
#include <string.h>
int main(){
    int n;
    char str[100]="123";
    sscanf (str,"%d",&n);
    printf ("%d\n",n);
    getchar();
    return 0;
}

运行结果:
123
sprintf(str,"%d",n);
上面sprintf的写法是把n以"%d"的格式写到str字符数组中(从右到左)

代码(C++):
#include <stdio.h>
#include <string.h>
int main(){
    int n=233;
    char str[100];
    sprintf (str,"%d",n);
    printf ("%s\n",str);
    getchar();
    return 0;
}

运行结果:
233

2.6函数

2.6.1 函数的定义

基本语法格式:
返回类型 函数名称(参数类型 参数){
函数主体
}
(1)全局变量
(2)局部变量:定义在函数内部,且只在函数内部生效,函数结束时局部变量销毁。

代码(C++):
#include <stdio.h>
void change(int x){
    x=x+1;
}
int main(){
    int x=10;
    change (x);
    printf ("%d\n",x);
    getchar();
    return 0;

}

运行结果:10
主函数对一个程序来说只能有一个,并且无论主函数写在哪个位置,整个程序一定是从主函数的第一个语句开始执行,然后在需要调用其他函数时才去调用。

2.6.4 以数组作为函数参数

函数的参数也可以是数组,且数组作为参数时,参数中数组的第一维不需要填写长度(如果是二维数组,二维需要填写长度),实际调用时只需要填写数组名。

数组作为参数时,在函数中对数组元素的修改就等同于对原数组元素的修改(这与普通的局部变量不同)。
代码(C++):
#include <stdio.h>
void change(int a[],int b[][5]){
    a[0]=1;
    a[1]=3;
    a[2]=5;
    b[0][0]=1;

}
int main(){
    int a[3]={0};
    int b[5][5]={0};
    change (a,b);
    for (int i = 0; i < 3; i++)
    {
        printf ("%d\n",a[i]);
    }
    getchar ();
    return 0;
}

运行结果:
1
3
5
数组不能作为返回类型出现,如果想要返回数组,则只能用上面的方法,将需要返回的数组作为参数传入。

2.6.5 函数的递归调用

递归是函数自己调用自己的过程。

代码(C++):
#include <stdio.h>
#include <stdlib.h>
int F(int n){
    if(n==0)
        return 1;
    else return F(n-1)*n;
}
int main(){
    int n;
    scanf ("%d",&n);
    printf ("%d\n",F(n));
    system ("pause");
    return 0;
}

运行结果:
输入:3
输出:6

2.7指针

2.7.1 什么是指针

计算机是通过地址找到某个变量的,变量的地址一般指它占用的字节中第一个字节的地址。可理解为指针就是变量的地址(不严谨)。
指针是一个unsigned类型的整数。
只要在变量前面加上&,就表示变量的地址。

2.7.2 指针变量

给指针变量赋值的方式一般是把变量的地址取出来,然后赋给对应类型的指针变量。例如:
int a;
int p=&a;
int 是指针变量的类型(是类型的一部分),而后面的p才是变量名,用来存储地址,因此地址&a是赋值给p而不是
p。
p保存的是地址,p是地址中存放的元素,如果直接对p进行赋值,也可以起到改变保存的元素的值的作用。
对一个int *型的指针变量p来说,p+1是指p所指的int型变量的下一个int型变量的地址。
指针变量支持自增和自减操作,p++等同于p=p+1使用。
数组名称也作为数组的首地址来使用。

2.7.4 使用指针变量作为函数参数

指针类型也可以作为韩数参数的类型,这时视为把变量的地址传入函数,如果在函数中这个地址中的元素进行改变,原先的数据就会确实地被改变(地址传递)。b
例:交换变量a、b的值

代码(C++):
#include <stdio.h>
void swap(int *a,int *b ){
    int temp=*a;
    *a=*b;
    *b=temp;
}
int main(){
    int a=3,b=4;
    swap (&a,&b);
    printf ("%d%d",a,b);
    getchar ();
    return 0;
}

运行结果:43
错误写法一:
void swap(int *a,int *b ){
int *temp;
temp=a;
a=b;
*b=temp;
}
错误原因:在定义int *类型的指针变量temp时,temp没有被初始化,temp中存放的地址是随机的,如果该随机地址指向的是系统工作期间,就会出错。
错误写法二:
void swap(int *a,int *b ){
int *temp=a;
a=b;
b=temp;
}
错误原因:函数参数的传递是单项 一次性的,main函数传给swap函数的“地址”其实是一个“无符号整型”的数,其本身也跟普通变量一样只是“值传递”,swap函数对地址本身进行修改并不能对main函数中的地址进行修改,能使main函数里的数据发生变化的只能是swap函数里对地址指向的数据进行修改。

2.7.5 引用

引用不产生副本,对引用变量的操作就是对原变量的操作。

代码(C++):
#include<stdio.h>
void change(int &x){
    x=1;

}
int main(){
  int x=3;
  change(x);
  printf ("%d\n",x);
  getchar ();
  return 0;
}

运行结果:1
不管是否使用引用,函数的参数名和实际传入的参数名可以不同。
【注】要把引用的&和取地址的&区分开来,引用并不是取地址的意思。

2.8 结构体的使用

2.8.1 结构体的定义

定义一个结构体的基本格式如下:
struct Name{
//一些基本的数据结构或自定义的数据类型
};
【注】结构体里面能定义除了自己本身(这样会引起循环定义的问题)之外的任何数据类型,但能定义自身类型的指针变量。
struct node{
node n;//不能定义node类型的变量
node * next;//能定义node*型指针变量
}

2.8.2 访问结构体内的元素

访问结构体内的元素有两种方法:“.”操作和“->”操作。
struct studentInfo{
int id;
char name[20];
studentInfo next;
}stu,
p;//结构体变量中定义了普通变量stu和指针变量p。
访问stu中的变量:
stu.id;
stu.name;
stu.next;
访问指针变量p中的元素:
(p).id; p->id;
(
p).name; p->name;
(*p).next; p->next;

2.8.3 结构体的初始化

struct studentInfo{
int id;
char gender;
//默认生成的构造函数
studentInfo(){}
};
struct studentInfo{
int id;
char gender;
//下面的参数用以对结构体内部变量进行赋值
studentInfo(int _id,char _gender){
//赋值
id=_id;
gender=_gender;
}
};
写法二:struct studentInfo{
int id;
char gender;
studentInfo(int _id,char _gender):id(_id),gender(_gender){}
};
【注】如果自己重新定义了构造函数,则不能不经过初始化就定义结构体变量,因为默认生成的构造函数"studentInfo()"此时被覆盖了。只要参数个数和类型不完全相同,就可以定义任意多个构造函数。

2.9 补充

2.9.1 cin与cout

cin与cout是C++中的输入与输出函数,需要添加头文件"#include <iostream>"和"using namespace std;"才能使用。cin与cout不需要像C语言中的scanf、printf函数那样指定输入输出的格式,也不需要使用取地址运算符&,而可以直接进行输入输出。

1.cin

cin采用">>"来进行输入。
例如:

#include <iostream>
using namespace std ;
int main(){
    int n;
    cin >>n;
    return 0;
}

读入double型浮点数db、char型字符c的方法:
cin >>db;
cin>>c;
如果同时读入多个变量,只需要往后面使用>>进行拓展即可。
例:cin>>n>>db>>c>>str;
如果读入一整行,则需要使用getline函数,
例:
(1)对字符数组:
char str[100];
cin.getline(str,100);
(2)对string容器:
string str;
getline(cin,str);

2.cout

使用的是输出运算符<<。
cout <<n<<""<<db<<""<<c<<""<<str;//输出并加上空格
cout<<n<<"haha"<<db<<"heihei"<<"wawa"<<str;//输出时在中间加上字符串
对cout来说,换行有两种方式: 第一种和C相同,也就是使用\n来换行;第二种是使用endl来换行:
cout<<n<<"\n"<<db<<endl;
控制double型的精度(需要添加#include <iomanip>头文件):
cout <<setiosflags(ios:fixed)<<setprecision(2)<<123.4567<<endl;//输出123.46
对考试而言,不推荐使用cin、cout来进行输入输出,因为它们在输入输出大量数据 时容易超时。只有在必要时使用(如string)。

2.9.2浮点数的比较

1.等于==
8如果一个数a落在了[b-eps,b+eps]区间上,就应判断a==b。其中eps定义为1e-8。
2.大于>
3.小于<
4.大于等于>=
5.小于等于<=
6.圆周率π:cos(π)=-1,所以写成常量acos(-1.0)。
const double Pi=acos(-1.0);
scanf读文件失败时返回-1,且C语言中使用EOF来代表-1。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,026评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,655评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,726评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,204评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,558评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,731评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,944评论 2 314
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,698评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,438评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,633评论 2 247
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,125评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,444评论 3 255
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,137评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,103评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,888评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,772评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,669评论 2 271

推荐阅读更多精彩内容