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

2.5.2 冒泡排序

整個(gè)過(guò)程執(zhí)行n-1趟,每一趟從左到右一次比較相鄰的兩個(gè)數(shù),如果大的數(shù)在左邊,則交換這兩個(gè)數(shù),當(dāng)該趟結(jié)束時(shí),該趟最大的數(shù)被移動(dòng)到當(dāng)前剩余數(shù)的最右邊。
第二個(gè)for循環(huán)的理解:當(dāng)?shù)趇趟時(shí),從a[0]到a[n-i-1]都需要與下一個(gè)數(shù)進(jìn)行比較。

代碼(C++):

#include "stdafx.h"

#include <stdio.h>

int main(){

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

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

//第i趟時(shí)從a[0]到a[n-i-1]都與它們下一個(gè)數(shù)進(jìn)行比較

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

if(a[j]>a[j+1]){  //如果左邊的數(shù)更大,則交換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;

}

輸出結(jié)果:
1 2 3 4 5

2.5.4 memset——對(duì)數(shù)組中每一個(gè)元素賦相同的值

memset函數(shù)的格式為:
memset(數(shù)組名,值,sizeof(數(shù)組名)); //需要添加string.h頭文件
【注1】只建議初學(xué)者使用memset賦0或-1,因?yàn)樗褂玫氖前醋止?jié)賦值。如果要對(duì)數(shù)組賦其他數(shù)字(例如1),則使用fill函數(shù)(但memset的執(zhí)行速度快)。
【注2】vs2012實(shí)現(xiàn)for、if語(yǔ)句括號(hào)自動(dòng)補(bǔ)全:按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運(yùn)行時(shí)閃退
        return 0;

}

輸出結(jié)果:
0 0 0 0 0
-1 -1 -1 -1 -1

2.5.5 字符數(shù)組

(1)scanf輸入,printf輸出
(2)getchar和putchar分別用來(lái)輸入和輸出單個(gè)字符

代碼(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;
}

運(yùn)行結(jié)果(與教材有偏差):
輸入:

_
_

輸出:

_
_

(3)gets輸入,puts輸出
gets用來(lái)輸入一行字符串,以\n結(jié)束;puts用來(lái)輸出一行字符串,以\n結(jié)束。

代碼(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();//由于建立的是空項(xiàng)目,若不添加這句,輸入之后黑窗口閃退
    return 0;
}

運(yùn)行結(jié)果:
輸入與輸出相同
woaiderenbuairen
qaq
t_t
woaini

2.5.6 string.h頭文件

(1)strlen:得到第一個(gè)\0前的字符的個(gè)數(shù),格式:
strlen(字符數(shù)組);
int len=strlen(str);
(2)strcmp():返回兩個(gè)字符串?dāng)?shù)組的大小比較結(jié)果,比較原則是按字典排序,格式:
strcmp(字符數(shù)組1,字符數(shù)組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;
}

運(yùn)行結(jié)果:
輸入字符串:
Dear Mozart
Canon
輸出:
str1>str2
(3)strcpy():把一個(gè)字符串復(fù)制給另一個(gè)字符串,格式:
strcpy(字符數(shù)組1,字符數(shù)組2);
【注】是把字符數(shù)組2復(fù)制給字符數(shù)組1,這里的“復(fù)制”包括了結(jié)束符\0。
(4)strcat():把一個(gè)字符串接到另一個(gè)字符串后面,格式:
strcat(字符數(shù)組1,字符數(shù)組2);
【注】是把字符數(shù)組2接到字符數(shù)組1后面。

2.5.7 sscanf與sprintf

sscanf(str,"%d",&n);
上面sscanf寫法的作用是把字符數(shù)組str中的內(nèi)容以"%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;
}

運(yùn)行結(jié)果:
123
sprintf(str,"%d",n);
上面sprintf的寫法是把n以"%d"的格式寫到str字符數(shù)組中(從右到左)

代碼(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;
}

運(yùn)行結(jié)果:
233

2.6函數(shù)

2.6.1 函數(shù)的定義

基本語(yǔ)法格式:
返回類型 函數(shù)名稱(參數(shù)類型 參數(shù)){
函數(shù)主體
}
(1)全局變量
(2)局部變量:定義在函數(shù)內(nèi)部,且只在函數(shù)內(nèi)部生效,函數(shù)結(jié)束時(shí)局部變量銷毀。

代碼(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;

}

運(yùn)行結(jié)果:10
主函數(shù)對(duì)一個(gè)程序來(lái)說(shuō)只能有一個(gè),并且無(wú)論主函數(shù)寫在哪個(gè)位置,整個(gè)程序一定是從主函數(shù)的第一個(gè)語(yǔ)句開始執(zhí)行,然后在需要調(diào)用其他函數(shù)時(shí)才去調(diào)用。

2.6.4 以數(shù)組作為函數(shù)參數(shù)

函數(shù)的參數(shù)也可以是數(shù)組,且數(shù)組作為參數(shù)時(shí),參數(shù)中數(shù)組的第一維不需要填寫長(zhǎng)度(如果是二維數(shù)組,二維需要填寫長(zhǎng)度),實(shí)際調(diào)用時(shí)只需要填寫數(shù)組名。

數(shù)組作為參數(shù)時(shí),在函數(shù)中對(duì)數(shù)組元素的修改就等同于對(duì)原數(shù)組元素的修改(這與普通的局部變量不同)。
代碼(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;
}

運(yùn)行結(jié)果:
1
3
5
數(shù)組不能作為返回類型出現(xiàn),如果想要返回?cái)?shù)組,則只能用上面的方法,將需要返回的數(shù)組作為參數(shù)傳入。

2.6.5 函數(shù)的遞歸調(diào)用

遞歸是函數(shù)自己調(diào)用自己的過(guò)程。

代碼(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;
}

運(yùn)行結(jié)果:
輸入:3
輸出:6

2.7指針

2.7.1 什么是指針

計(jì)算機(jī)是通過(guò)地址找到某個(gè)變量的,變量的地址一般指它占用的字節(jié)中第一個(gè)字節(jié)的地址??衫斫鉃橹羔樉褪亲兞康牡刂罚ú粐?yán)謹(jǐn))。
指針是一個(gè)unsigned類型的整數(shù)。
只要在變量前面加上&,就表示變量的地址。

2.7.2 指針變量

給指針變量賦值的方式一般是把變量的地址取出來(lái),然后賦給對(duì)應(yīng)類型的指針變量。例如:
int a;
int p=&a;
int 是指針變量的類型(是類型的一部分),而后面的p才是變量名,用來(lái)存儲(chǔ)地址,因此地址&a是賦值給p而不是
p。
p保存的是地址,p是地址中存放的元素,如果直接對(duì)p進(jìn)行賦值,也可以起到改變保存的元素的值的作用。
對(duì)一個(gè)int *型的指針變量p來(lái)說(shuō),p+1是指p所指的int型變量的下一個(gè)int型變量的地址。
指針變量支持自增和自減操作,p++等同于p=p+1使用。
數(shù)組名稱也作為數(shù)組的首地址來(lái)使用。

2.7.4 使用指針變量作為函數(shù)參數(shù)

指針類型也可以作為韓數(shù)參數(shù)的類型,這時(shí)視為把變量的地址傳入函數(shù),如果在函數(shù)中這個(gè)地址中的元素進(jìn)行改變,原先的數(shù)據(jù)就會(huì)確實(shí)地被改變(地址傳遞)。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;
}

運(yùn)行結(jié)果:43
錯(cuò)誤寫法一:
void swap(int *a,int *b ){
int *temp;
temp=a;
a=b;
*b=temp;
}
錯(cuò)誤原因:在定義int *類型的指針變量temp時(shí),temp沒(méi)有被初始化,temp中存放的地址是隨機(jī)的,如果該隨機(jī)地址指向的是系統(tǒng)工作期間,就會(huì)出錯(cuò)。
錯(cuò)誤寫法二:
void swap(int *a,int *b ){
int *temp=a;
a=b;
b=temp;
}
錯(cuò)誤原因:函數(shù)參數(shù)的傳遞是單項(xiàng) 一次性的,main函數(shù)傳給swap函數(shù)的“地址”其實(shí)是一個(gè)“無(wú)符號(hào)整型”的數(shù),其本身也跟普通變量一樣只是“值傳遞”,swap函數(shù)對(duì)地址本身進(jìn)行修改并不能對(duì)main函數(shù)中的地址進(jìn)行修改,能使main函數(shù)里的數(shù)據(jù)發(fā)生變化的只能是swap函數(shù)里對(duì)地址指向的數(shù)據(jù)進(jìn)行修改。

2.7.5 引用

引用不產(chǎn)生副本,對(duì)引用變量的操作就是對(duì)原變量的操作。

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

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

運(yùn)行結(jié)果:1
不管是否使用引用,函數(shù)的參數(shù)名和實(shí)際傳入的參數(shù)名可以不同。
【注】要把引用的&和取地址的&區(qū)分開來(lái),引用并不是取地址的意思。

2.8 結(jié)構(gòu)體的使用

2.8.1 結(jié)構(gòu)體的定義

定義一個(gè)結(jié)構(gòu)體的基本格式如下:
struct Name{
//一些基本的數(shù)據(jù)結(jié)構(gòu)或自定義的數(shù)據(jù)類型
};
【注】結(jié)構(gòu)體里面能定義除了自己本身(這樣會(huì)引起循環(huán)定義的問(wèn)題)之外的任何數(shù)據(jù)類型,但能定義自身類型的指針變量。
struct node{
node n;//不能定義node類型的變量
node * next;//能定義node*型指針變量
}

2.8.2 訪問(wèn)結(jié)構(gòu)體內(nèi)的元素

訪問(wèn)結(jié)構(gòu)體內(nèi)的元素有兩種方法:“.”操作和“->”操作。
struct studentInfo{
int id;
char name[20];
studentInfo next;
}stu,
p;//結(jié)構(gòu)體變量中定義了普通變量stu和指針變量p。
訪問(wèn)stu中的變量:
stu.id;
stu.name;
stu.next;
訪問(wèn)指針變量p中的元素:
(p).id; p->id;
(
p).name; p->name;
(*p).next; p->next;

2.8.3 結(jié)構(gòu)體的初始化

struct studentInfo{
int id;
char gender;
//默認(rèn)生成的構(gòu)造函數(shù)
studentInfo(){}
};
struct studentInfo{
int id;
char gender;
//下面的參數(shù)用以對(duì)結(jié)構(gòu)體內(nèi)部變量進(jìn)行賦值
studentInfo(int _id,char _gender){
//賦值
id=_id;
gender=_gender;
}
};
寫法二:struct studentInfo{
int id;
char gender;
studentInfo(int _id,char _gender):id(_id),gender(_gender){}
};
【注】如果自己重新定義了構(gòu)造函數(shù),則不能不經(jīng)過(guò)初始化就定義結(jié)構(gòu)體變量,因?yàn)槟J(rèn)生成的構(gòu)造函數(shù)"studentInfo()"此時(shí)被覆蓋了。只要參數(shù)個(gè)數(shù)和類型不完全相同,就可以定義任意多個(gè)構(gòu)造函數(shù)。

2.9 補(bǔ)充

2.9.1 cin與cout

cin與cout是C++中的輸入與輸出函數(shù),需要添加頭文件"#include <iostream>"和"using namespace std;"才能使用。cin與cout不需要像C語(yǔ)言中的scanf、printf函數(shù)那樣指定輸入輸出的格式,也不需要使用取地址運(yùn)算符&,而可以直接進(jìn)行輸入輸出。

1.cin

cin采用">>"來(lái)進(jìn)行輸入。
例如:

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

讀入double型浮點(diǎn)數(shù)db、char型字符c的方法:
cin >>db;
cin>>c;
如果同時(shí)讀入多個(gè)變量,只需要往后面使用>>進(jìn)行拓展即可。
例:cin>>n>>db>>c>>str;
如果讀入一整行,則需要使用getline函數(shù),
例:
(1)對(duì)字符數(shù)組:
char str[100];
cin.getline(str,100);
(2)對(duì)string容器:
string str;
getline(cin,str);

2.cout

使用的是輸出運(yùn)算符<<。
cout <<n<<""<<db<<""<<c<<""<<str;//輸出并加上空格
cout<<n<<"haha"<<db<<"heihei"<<"wawa"<<str;//輸出時(shí)在中間加上字符串
對(duì)cout來(lái)說(shuō),換行有兩種方式: 第一種和C相同,也就是使用\n來(lái)?yè)Q行;第二種是使用endl來(lái)?yè)Q行:
cout<<n<<"\n"<<db<<endl;
控制double型的精度(需要添加#include <iomanip>頭文件):
cout <<setiosflags(ios:fixed)<<setprecision(2)<<123.4567<<endl;//輸出123.46
對(duì)考試而言,不推薦使用cin、cout來(lái)進(jìn)行輸入輸出,因?yàn)樗鼈冊(cè)谳斎胼敵龃罅繑?shù)據(jù) 時(shí)容易超時(shí)。只有在必要時(shí)使用(如string)。

2.9.2浮點(diǎn)數(shù)的比較

1.等于==
8如果一個(gè)數(shù)a落在了[b-eps,b+eps]區(qū)間上,就應(yīng)判斷a==b。其中eps定義為1e-8。
2.大于>
3.小于<
4.大于等于>=
5.小于等于<=
6.圓周率π:cos(π)=-1,所以寫成常量acos(-1.0)。
const double Pi=acos(-1.0);
scanf讀文件失敗時(shí)返回-1,且C語(yǔ)言中使用EOF來(lái)代表-1。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容