2022考研機(jī)試復(fù)習(xí)——C/C++學(xué)習(xí)筆記(一)

起步

// C++向下兼容C,在練習(xí)過(guò)程中,請(qǐng)將代碼保存為.cpp文件
/*
 * 頭文件
 * 1. ".h"為頭文件的文件格式
 * 2. C++等價(jià)寫法:#include <cstdio>
 */
#include <stdio.h>
/*
 * 主函數(shù)
 * 1. 程序入口
 * 2. 程序從主函數(shù)開始執(zhí)行
 * 3. 一個(gè)程序最多只能有一個(gè)主函數(shù)
 */
int main(){
    int a,b;
    scanf("%d%d",&a,&b);
    printf("%d",a+b);
    return 0;
}

一、基本數(shù)據(jù)類型

變量類型

整型

常用整型(int)和長(zhǎng)整型(long long)。

說(shuō)明:

  1. 絕對(duì)值在109范圍以內(nèi)的整數(shù)都能定義成int型。
  2. 如果給long long型賦一個(gè)大于231-1的初值,請(qǐng)?jiān)跀?shù)字后加LL。如:long long bigNum = 1234567890123345LL。
  3. 題目要求109以內(nèi)或32位整數(shù)時(shí),用int存放;若是1018以內(nèi)(如1010)或者說(shuō)64位整數(shù),使用long long存放。

浮點(diǎn)型

浮點(diǎn)型就是小數(shù),氛圍單精度(float)和雙精度(double)。

說(shuō)明:

  1. float有效精度6~7位,少用。
  2. 碰到浮點(diǎn)型的數(shù)據(jù)使用double來(lái)存儲(chǔ)。

字符型

說(shuō)明:

  1. C語(yǔ)言中,字符常量統(tǒng)一使用ASCII碼統(tǒng)一編碼(范圍0~127)。
  2. 小寫字母比大寫字母的ASCII碼值大32(a->97,A->65,空格->32)。
  3. 字符常量(必須是單個(gè)字符)必須使用單引號(hào)標(biāo)注('z','h','r')。
  4. 可以將整數(shù)的ASCII碼值賦給字符變量,因?yàn)樵谟?jì)算機(jī)內(nèi)部,字符就是按ASCII碼存儲(chǔ)的。
  5. 轉(zhuǎn)義字符"\0"代表空字符NULL(注意不是空格),其ASCII碼為0。

字符串常量

#include <cstdio>
int main(){
/*
* 字符數(shù)組
* 1. 字符串常量為""標(biāo)記的字符集。
* 2. 不能把字符串常量賦值給字符變量(不允許char c = "zhanghaoran";)
* 3. 字符串常量可以作為初值賦值給字符數(shù)組,使用%s的格式輸出。
*/
char str[50] = "2022,kaoyanbisheng!";
printf("%s",str);
return 0;

布爾型

#include <cstdio>
int main(){
    bool flag1 = 10;
    bool flag2 = -10;
    bool flag3 = 0;
    printf("%d\n%d\n%d",flag1,flag2,flag3);
    /**
       /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        1
        1
        0
        Process finished with exit code 0
     */
    return 0;
}

說(shuō)明:

  1. 布爾型(bool)在cpp文件中直接使用,在C語(yǔ)言中要添加stdbool.h頭文件才能使用。
  2. 給布爾型變量賦值的時(shí)候可以使用true、false或者整型常量。整型常量在賦值給bool變量時(shí),會(huì)自動(dòng)轉(zhuǎn)換成true(非0)和false(0)。
  3. bool中,true使用1存儲(chǔ),false使用0存儲(chǔ),%d打印時(shí)會(huì)輸出數(shù)字。

常量定義

常用的定義常量的方式有兩種:

#define PI 3.1415 // 宏定義
const double PI = 3.1415; // const關(guān)鍵字

二、順序結(jié)構(gòu)

scanf與printf

#include <cstdio>
int main(){
    /*
      n = n + 2 <=> n += 2 后者稱為符合賦值運(yùn)算符,可以加快編譯速度和提高可讀性,應(yīng)常用這種方式。
    */
    int n = 0;
    n += 2;
    printf("%d",n);
    int age;
    /* 關(guān)于scanf()
     * 1. scanf("格式控制",變量地址)
     * 2. "&"——取地址運(yùn)算符
     * 3. 特別的數(shù)據(jù)類型變量的scanf格式符:
     *  - long long: %lld
     *  - double: %lf
     * 4. scanf中,char數(shù)組整個(gè)輸入的情況下不加&,因?yàn)閿?shù)組名稱本身就代表了數(shù)組第一個(gè)元素的地址
     * 5. 字符數(shù)組讀入時(shí)以空格和換行符為讀入結(jié)束的標(biāo)志,因此當(dāng)輸入"zhang haoran"想賦值給name時(shí),name只會(huì)保存"zhang"
     * 6. scanf的%c格式可以讀入空格和換行。
     */
    scanf("%d",&age);
    char name[20];
    scanf("%s",name);
    /*
     * 關(guān)于printf():
     * 1. 對(duì)于double類型的變量,在printf中的輸出格式為%f,而在scanf中是%lf
     * 2. 輸出%和\時(shí),需要轉(zhuǎn)義,即"%%"和"\\"
     */
    printf("姓名:%s\n年齡:%d",name,age);
    /*
     * /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        20
        zhanghaoran
        姓名:zhanghaoran
        年齡:20
        Process finished with exit code 0
     */
    // 補(bǔ)充三種常用的輸出格式
    {
        int num = 720;
        // 1. %md 使不足m位的int型變量以m位進(jìn)行右對(duì)齊輸出,高位空格補(bǔ)齊
        printf("%5d",num);
        // 2.  區(qū)別于%md,%0md高位0補(bǔ)齊
        printf("%05d",num);
        double d = 1.1234567;
        // 3. 讓浮點(diǎn)數(shù)保留m位小數(shù)輸出
        printf("%.2f",d);
    }
    return 0;
}

getchar與putchar

#include <cstdio>
int main(){
    char c1,c2,c3;
    // 1. getchar()能識(shí)別空格和換行符
    // 2. getchar()用來(lái)輸入單個(gè)字符,putchar用來(lái)輸出單個(gè)字符
    c1 = getchar();
    c2 = getchar();
    c3 = getchar();
    putchar(c1);
    putchar(c2);
    putchar(c3);
    return 0;
    /*
     * /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        z hr
        z h
        Process finished with exit code 0
     */
}

typedef

typedef關(guān)鍵字用于給復(fù)雜的一個(gè)數(shù)據(jù)類型取別名。

// 給long long數(shù)據(jù)類型取一個(gè)別名Long
typedef long long Long;
Long l = 123456789LL;

常用的math函數(shù)

在使用數(shù)學(xué)函數(shù)前,要使用<code>#include<math.h></code>引入頭文件。

  • fabs(double x)
    對(duì)double型變量取絕對(duì)值。
  • floor(double x) 和 ceil(double x)
    對(duì)double型的變量進(jìn)行向下取整和向上取整。
  • pow(double r,double p)
    返回rp
  • sqrt(double x)
    返回double型變量的算數(shù)平方根。
  • log(double x)
    返回double型變量以自然對(duì)數(shù)為底的對(duì)數(shù)
  • sin(double x)、cos(double x)、tan(double x)
    返回對(duì)應(yīng)的三角函數(shù)值,參數(shù)要求是弧度制。
  • round(double x)
    將double型變量x四舍五入后取整然后返回double類型。

三、選擇結(jié)構(gòu)

下面這種寫法在許多數(shù)據(jù)結(jié)構(gòu)算法的書上經(jīng)常出現(xiàn)。

#include "cstdio"
int main(){
    int a = 100;
    int b = 0;
    if(a){
        printf("a is not zero!");
    } else {
        printf("a is zero!");
    }
    if(!b){
        printf("a is zero!");
    } else {
        printf("a is not zero!");
    }
}

技巧

  1. 在if條件中,如果表達(dá)式是"!=0",可以省略。
  2. 在if條件中,如果表達(dá)式是"==0",可以省略,然后在表達(dá)式前加取反運(yùn)算符"!"。

四、循環(huán)結(jié)構(gòu)

對(duì)于以下這種寫法:

for(int i = 0; i < 10 ; i ++){
    // ···
}

說(shuō)明:
在C語(yǔ)言中是不允許在for語(yǔ)句的表達(dá)式A中定義變量的,但是在C++中可以,因此以上這種寫法需要把文件保存為.cpp后綴才能通過(guò)編譯。

五、數(shù)組

一維數(shù)組初始化

基本方法

#include <cstdio>

int main(){
    /*
     * 一維數(shù)組初始化
     * 1. 數(shù)組對(duì)部分元素進(jìn)行賦值操作,未被賦值的元素默認(rèn)為0。
     * 2. 當(dāng)數(shù)組沒(méi)有被賦初值,每個(gè)元素可能是0,也有可能是一個(gè)隨機(jī)數(shù)。
     * 3. 如果想給數(shù)組的每一個(gè)元素賦初值0,只需要把第一個(gè)元素賦為0,或者只用一個(gè){}表示:
     *    a. int nums[10] = {0};
     *    b. int nums[10] = {};
     */
    int nums[10] = {11,22,33,44,55};
    for(int i = 0; i < 10 ; i ++){
        printf("nums[%d]=%d\n",i,nums[i]);
    }
    return 0;
    /*
        /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        nums[0]=11
        nums[1]=22
        nums[2]=33
        nums[3]=44
        nums[4]=55
        nums[5]=0
        nums[6]=0
        nums[7]=0
        nums[8]=0
        nums[9]=0

        Process finished with exit code 0
     */
}

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

#include "cstdio"
#include "cstring"
#define n 5
int main(){
/*
 * 使用memset給數(shù)組賦初值
 * 1. 添加string.h頭文件
 * 2. memset按字節(jié)賦值
 * 3. 一般使用memset賦初值0或-1
 */
int arr[n];
memset(arr,-1,sizeof(arr));
for(int i = 0; i< n; i ++){
printf("%2d ",arr[i]);
}
memset(arr,0,sizeof(arr));
printf("\n");
for(int i = 0; i< n; i ++){
printf("%2d ",arr[i]);
}
return 0;
/*
 *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
    -1 -1 -1 -1 -1 
     0  0  0  0  0 
    Process finished with exit code 0
 */
}

數(shù)組順推

#include <cstdio>
// 數(shù)組遞推包括:
// 1. 順推 
// 2. 逆推
int main(){
    int nums[10];
    scanf("%d",nums);
    for(int i = 1; i < 10 ;i ++){
        nums[i] = nums[i - 1] * 2;
    }
    for(int i = 0; i < 10 ;i ++){
        printf("nums[%d]=%d\n",i,nums[i]);
    }
    return 0;
    /*
        /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        1
        nums[0]=1
        nums[1]=2
        nums[2]=4
        nums[3]=8
        nums[4]=16
        nums[5]=32
        nums[6]=64
        nums[7]=128
        nums[8]=256
        nums[9]=512
        
        Process finished with exit code 0
     */
}

冒泡排序

#include <cstdio>
/*
 * 冒泡排序:
 * 1. 進(jìn)行若干趟排序,每趟排序?qū)?shù)組元素的最大值移動(dòng)到最右邊
 * 2. 當(dāng)剩余元素為0時(shí),排序結(jié)束
 */
const int n = 10;
int main(){
    int nums[n] = {1,4,3,2,7,6,5,9,8};
    for(int i = 0 ;i < n - 1; i ++){
        for(int j = 0; j < n - i - 1; j ++){
            if(nums[j] > nums[j + 1]){
                int tmp = nums[j];
                nums[j] = nums[j + 1];
                nums[j + 1] = tmp;
            }
        }
    }
    for(int i = 0; i< n ; i ++){
        printf("%d ",nums[i]);

    }
    return 0;
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        0 1 2 3 4 5 6 7 8 9 
        Process finished with exit code 0
     */
}

二維數(shù)組

#include <cstdio>
#define n 3
int main(){
    /*
     * 二維數(shù)組初始化
     */
    int arr[n][n] = {{1,2},{2}};
    for(int i = 0; i< n ;i ++){
        for(int j = 0; j< n ;j ++){
            printf("%02d ",arr[i][j]);
        }
        printf("\n");
    }
    /*
     * 兩個(gè)三階矩陣對(duì)應(yīng)位置元素相加,并將結(jié)果存放到另外一個(gè)三階矩陣
     */
    int a[n][n];
    int b[n][n];
    int c[n][n];
    for(int i = 0; i < n ; i ++){
       for(int j = 0; j< n ; j ++){
           scanf("%d",&a[i][j]);
           scanf("%d",&b[i][j]);
           c[i][j] = a[i][j] + b[i][j];
       }
    }
//    for(int i = 0; i < n ; i ++){
//        for(int j = 0; j< n ; j ++){
//            scanf("%d",&b[i][j]);
//        }
//    }
//    for(int i = 0; i < n ; i ++){
//        for(int j = 0; j< n ; j ++){
//            c[i][j] = a[i][j] + b[i][j];
//        }
//    }
    for(int i = 0 ;i < n ; i++){
        for(int j = 0; j < n ; j ++){
            printf("%d ",c[i][j]);
        }
        printf("\n");
    }
/*
 *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
    01 02 00 
    02 00 00 
    00 00 00 
    1 9 2 8 3 7 4 6 5 5 6 4 7 3 8 2 9 1
    10 10 10 
    10 10 10 
    10 10 10 
    
    Process finished with exit code 0

 */
}

字符數(shù)組

字符數(shù)組的初始化

#include <stdio.h>
int main(){
    // 字符數(shù)組初始化方式1——普通數(shù)組初始化方式
    char str1[] = {'z','h','r'};
    for(int i = 0 ; i < 3 ; i ++){
        printf("%c",str1[i]);
    }
    printf("\n");
    // 字符數(shù)組初始化方式2——賦值字符串(僅限初始化)
    char str2[] = "zhanghaoran";
    for(int i = 0 ; i< 11; i ++ ){
        printf("%c",str2[i]);
    }
    printf("\n");
    return 0;
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        zhr
        zhanghaoran
        
        Process finished with exit code 0
     */
}

字符數(shù)組的輸入輸出

#include "cstdio"
int main(){
    /*
     * 字符數(shù)組輸入輸出方式1——printf()和scanf()
       1. scanf()的%c格式能夠識(shí)別空格和換行符并將其輸入
       2. %s通過(guò)空格和換行符來(lái)識(shí)別一個(gè)字符串的結(jié)束
       3. scanf()在使用%s時(shí),對(duì)應(yīng)數(shù)組名前不用加取地址運(yùn)算符"&"
     */
//    char name[20] = {};
//    scanf("%s",name);
//    printf("%s",name);
    /*
        /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        zhanghaoran
        zhanghaoran
        Process finished with exit code 0
     */
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        zhang haoran
        zhang
        Process finished with exit code 0
     */

    /*
     * 字符數(shù)組輸入輸出方式2——getchar()和putchar()
     * 注意:getchar()能識(shí)別空格和換行符
     */
//    const int n = 4;
//    char twoDimensionArr[n][n];
//    for(int i = 0 ; i < n - 1 ;i ++){
//        for(int j = 0 ;j < n - 1 ; j ++){
//            twoDimensionArr[i][j] = getchar();
//        }
//        getchar(); // 把輸入中每行末尾的換行符吸收掉
//    }
//    for(int i = 0 ; i < n - 1; i ++){
//        for(int j = 0 ; j < n - 1; j ++){
//            putchar(twoDimensionArr[i][j]);
//        }
//        putchar('\n');
//    }
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        ^_^
        _^_ ^_^
        ^_^
        _^_
        ^_^

        Process finished with exit code 0
     */
    /*
     * 字符數(shù)組輸入輸出方式3——gets()和puts()
     * 說(shuō)明:
     * 1. gets()識(shí)別換行符\n作為輸入結(jié)束,scanf()后如要用gets(),需要先用getchar()把換行符吸收掉。
     * 2. gets()輸入的字符串可以包含空格
     * 3. puts()輸出會(huì)自動(dòng)換行。
     */
//    int a = 0;
//    char str[20];
//    scanf("%d",&a);
//    getchar();
//    gets(str);
//    puts(str);
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        1
        warning: this program uses gets(), which is unsafe.
        zhanghaoran
        zhanghaoran

        Process finished with exit code 0
     */
    // 使用gets()和puts()操作二維數(shù)組
    const int row = 3;
    char strs[row][20];
    for(int i = 0 ; i < row ; i ++ ){
        gets(strs[i]);
    }
    for(int i = 0 ; i < row ; i ++){
        puts(strs[i]);
    }
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        warning: this program uses gets(), which is unsafe.
        zhang
        hao
        ran
        zhang
        hao
        ran
        
        Process finished with exit code 0
     */
    return 0;
}

字符數(shù)組的存放方式

說(shuō)明:

  1. 在一維數(shù)組(或二維數(shù)組的第二維)末尾都有一個(gè)空字符'\0',表示存放字符串的結(jié)尾。
  2. '\0'在使用gets()或者scanf()輸入字符串時(shí)會(huì)自動(dòng)添加在輸入的字符串后面,并占用一個(gè)字符位。
  3. puts()和printf()通過(guò)識(shí)別'\0'作為字符串的結(jié)尾來(lái)輸出的。
  4. 結(jié)束符'\0'的ASCII值為0,即空字符NULL,占用一個(gè)字符位,因此,在創(chuàng)建一個(gè)字符數(shù)組時(shí),字符數(shù)組的長(zhǎng)度至少要比實(shí)際存儲(chǔ)的字符串的長(zhǎng)度多1。
  5. 只有char數(shù)組末尾會(huì)加'\0',int等類型的數(shù)組末尾不加。
  6. '\0'和空格不是一個(gè)東西,它表示空字符NULL,空格的ASCII值為32。

string.h頭文件

string.h頭文件包含了許多用于字符數(shù)組的函數(shù)。

#include "cstdio"
// 引入string.h頭文件
#include "cstring"

/*
 * strlen()——用于獲取字符數(shù)組中第一個(gè)'\0'前的字符的個(gè)數(shù)。
 * 格式:strlen(字符數(shù)組)
 */
void strlen_test(){
    char str[20];
    // gets()可以輸入包含空格的字符串
    gets(str);
    int len = strlen(str);
    printf("%d",len);
    printf("\n");
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        warning: this program uses gets(), which is unsafe.
        zhang hao ran
        13

        Process finished with exit code 0
     */
}
/*
 * strcmp()——以字典序?yàn)楸容^原則,返回兩個(gè)字符串大小的比較結(jié)果。
 * 格式:strcmp(字符數(shù)組1,字符數(shù)組2)
 * 說(shuō)明:
 * 1. 若字符數(shù)組1<字符數(shù)組2,則返回一個(gè)負(fù)整數(shù)(不一定是-1)。
 * 2. 若字符數(shù)組1=字符數(shù)組2,則返回0。
 * 3. 若字符數(shù)組1>字符數(shù)組2,則返回一個(gè)正整數(shù)(不一定是1)。
 */
void strcmp_test(){
    char str1[30];
    char str2[30];
    gets(str1);
    gets(str2);
    int res = strcmp(str1,str2);
    if(res < 0){
        printf("str1 < str2\n");
    }else if(res == 0){
        printf("str1 = str2\n");
    }else{
        printf("str1 > str2\n");
    }
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        warning: this program uses gets(), which is unsafe.
        nanchang
        beijing
        str1 > str2

        Process finished with exit code 0
     */
}
/*
 * strcpy()——把第二個(gè)字符串復(fù)制給第一個(gè)字符串,包括結(jié)束符"\0"
 * 格式:strcpy(字符數(shù)組1,字符數(shù)組2)
 */
void strcpy_test(){
    char str1[30];
    char str2[30];
    gets(str2);
    strcpy(str1,str2);
    puts(str1);
    /*
    /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
    warning: this program uses gets(), which is unsafe.
    zhanghaoran
    zhanghaoran

    Process finished with exit code 0
     */
}
/*
 * strcat()——把字符串2拼接到字符串1的后面
 * 格式:strcat(字符數(shù)組1,字符數(shù)組2)
 */
void strcat_test(){
    char str1[30];
    char str2[30];
    gets(str1);
    gets(str2);
    strcat(str1,str2);
    puts(str1);
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        warning: this program uses gets(), which is unsafe.
        zhanghaoran
         like coding!
        zhanghaoran like coding!
        
        Process finished with exit code 0
     */
}
int main(){
//    strlen_test();
//    strcmp_test();
//    strcpy_test();
    strcat_test();
    return 0;
}

sscanf()和sprintf()

sscanf()和sprintf()屬于stdio.h頭文件下的函數(shù),用于處理字符串,可以理解為"string+scanf"和"string+printf"。

#include "cstdio"
#include "cstring"
int main(){
    char str[10] = "1234";
    int num;
    sscanf(str,"%d",&num);
    printf("%d\n",num);
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        1234
        Process finished with exit code 0
     */
    num = 12345;
    sprintf(str,"%d",num);
    for(int i = 0 ; i < strlen(str); i ++){
        printf("%c ", str[i]);
    }
    printf("\n");
//    printf("%s\n",str);
/*
    /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
    1234
    1 2 3 4 5 
    
    Process finished with exit code 0
 */
    return 0 ;
}

理解:

  • 我們常寫的scanf()和printf()可以寫成:
  scanf(screen,"%d",&n);
  printf(screen,"%d",n);

這里的screen就看成是電腦屏幕。scanf的輸入其實(shí)就是把screen中的內(nèi)容以%d的格式傳到變量n中(從左到右);而printf的輸出就是把變量n中的內(nèi)容以"%d"的格式傳到screen。

  • 類比到sscanf和sprintf,唯一的改變就是把screen換成了字符數(shù)組,使用格式如下:
  char str[20];
  sscanf(str,"%d",&n);
  sprintf(str,"%d",n);
  • sprintf()也可以做字符串的復(fù)制
#include "cstdio"
int main(){
   char str1[20];
   char str2[20] = "zhanghaoran";
   sprintf(str1,"%s",str2);
   puts(str1);
   return 0;
  /*
   /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
   zhanghaoran

   Process finished with exit code 0
   */
 }
  • sscanf支持正則表達(dá)式

六、函數(shù)

再談main函數(shù):

int main(){ 
    //···
    return 0;
}

說(shuō)明:

  1. 主函數(shù)對(duì)于一個(gè)程序來(lái)說(shuō)只能有一個(gè),無(wú)論主函數(shù)寫在哪個(gè)位置,整個(gè)程序一定是從主函數(shù)的第一個(gè)語(yǔ)句開始執(zhí)行,然后在需要調(diào)用其他函數(shù)的時(shí)候才回去調(diào)用。
  2. main函數(shù)返回0的意義在于告知系統(tǒng)程序正常終止。

七、指針

指針的相關(guān)概念

變量的存放:

  1. 變量存放在內(nèi)存中。
  2. 每個(gè)字節(jié)都會(huì)有一個(gè)地址。
  3. 計(jì)算機(jī)通過(guò)地址找到某個(gè)變量。
  4. 變量的地址指的是它占用的字節(jié)中的第一個(gè)字節(jié)的地址。

指針:

  1. 在計(jì)算機(jī)中,一個(gè)地址"指向"一個(gè)變量,可以通過(guò)地址來(lái)找到變量。
  2. 在C語(yǔ)言中,使用"指針"表示內(nèi)存地址(或稱指針指向了內(nèi)存地址)。
  3. 如果一個(gè)指針指向的內(nèi)存地址恰好是某個(gè)變量的地址,就稱"這個(gè)指針指向了該變量"。
  4. "&"為取地址運(yùn)算符,在變量前加上"&",就表示變量的地址。
  5. 指針是一個(gè)unsigned類型的整數(shù)。

指針變量

指針變量用于存放指針(或者說(shuō)地址)。

指針變量的定義與初始化

// 1. 數(shù)據(jù)類型后加"*"
int* p;
double* p;
char* p;
// 說(shuō)明:"*"的位置在數(shù)據(jù)類型后或者變量名稱之前都OK的,編譯器不會(huì)對(duì)此進(jìn)行區(qū)分。
//2. 同時(shí)定義多個(gè)指針變量
int *a,*b,*c;
//3. 以下方式只有p1會(huì)被定義為指針類型,p2不會(huì)
int* p1,p2;
//4. 給指針變量賦值的方式一般是把變量的地址使用取地址運(yùn)算符"&"取出后賦值給對(duì)應(yīng)類型的指針變量。
int a = 10;
int* pa = &a;

說(shuō)明:

  • int* 才是指針變量的類型,而后面的p才是變量名,用來(lái)存儲(chǔ)變量的地址值。
  • 地址值&a是賦值給p而不是*p的。
  • 請(qǐng)記住,對(duì)指針變量來(lái)說(shuō),星號(hào)"*"是類型的一部分。

獲取地址所指的元素:

  • 在指針變量前加"*"。
  • 指針變量p表示的是地址,*p是這個(gè)地址中存放的內(nèi)容。
  • 對(duì)指針變量來(lái)說(shuō),把其存儲(chǔ)的地址的類型稱為基類型

指針與數(shù)組

#include "cstdio"

int main(){
    // 1. C語(yǔ)言中,數(shù)組名稱也作為數(shù)組的首地址使用。
//    int a[5] = {1};
//    int* pa = a;
//    printf("%d",*pa);
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        1
        Process finished with exit code 0
     */
    // 2. 使用指針對(duì)數(shù)組進(jìn)行賦值和遍歷輸出
    const int n = 10;
    int a[n];
    for( int i = 0; i< n;i ++ ){
        scanf("%d",a+i);
    }
    // 遍歷方式1
//    for(int i = 0 ; i < n ; i ++){
//        printf("%d ",*(a+i));
//    }
//    printf("\n");
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        0 1 2 3 4 5 6 7 8 9
        0 1 2 3 4 5 6 7 8 9

        Process finished with exit code 0
     */
    // 遍歷方式2
    for(int* pa = a ; pa < a+n ; pa ++){
        printf("%d ",*pa);
    }
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        9 8 7 6 5 4 3 2 1 0
        9 8 7 6 5 4 3 2 1 0 
        Process finished with exit code 0

     */
    return 0;
}

在函數(shù)參數(shù)中使用指針

#include "cstdio"
void swap(int* a, int * b){
    int tmp = *a;
    *a = *b;
    *b = tmp;
}
int main(){
    int a = 10;
    int b = 20;
    swap(&a,&b);
    printf("%d %d",a,b);
    return 0;
}

引用

#include "stdio.h"

void change1(int x){
    x = 10;
}
// 形參為引用
void change2(int &x){
    x = 10;
}

int main(){
    int x = 0 ;
    change1(x);
    printf("%d\n",x);
    change2(x);
    printf("%d\n",x);
    return 0 ;
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        0
        10
        
        Process finished with exit code 0
     */
}

關(guān)于引用:

  1. 引用是C++中的語(yǔ)法,文件必須保存為.cpp類型。
  2. 引用不產(chǎn)生副本,只是給原變量取了一個(gè)別名,對(duì)引用變量的操作就是對(duì)原變量的操作。
  3. 使用方法:在函數(shù)的參數(shù)名前加"&"(或者參數(shù)類型之后,因?yàn)橐檬莿e名的意思,所以一般加在變量名前面)
  4. 不管是否使用引用,函數(shù)的參數(shù)名(形參名)和實(shí)際傳入的參數(shù)名(實(shí)參名)可以不同。
  5. 注意:把引用的"&"和取地址符"&"區(qū)分開,引用不是取地址的意思,它是C++中的一種語(yǔ)法。
  6. 強(qiáng)調(diào):由于引用是產(chǎn)生變量的別名,因此常量不可使用引用。

下面是swap方法的另一種實(shí)現(xiàn)方式,這里使用到了指針的引用:

#include "cstdio"
void swap(int* &pa,int* &pb){
    int* tmp = pa;
    pa = pb;
    pb = tmp;
}
int main(){
    int a = 10, b = 20;
    int *pa = &a;
    int *pb = &b;
    printf("%d %d\n",*pa,*pb);
    swap(pa,pb);
    printf("%d %d\n",*pa,*pb);
    return 0;
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        10 20
        20 10
        
        Process finished with exit code 0
     */
}

八、結(jié)構(gòu)體

定義結(jié)構(gòu)體的基本格式:

struct struct_name{
    // 一些基本的數(shù)據(jù)結(jié)構(gòu)或者自定義的數(shù)據(jù)類型
};

結(jié)構(gòu)體變量和結(jié)構(gòu)體數(shù)組的2種定義方式:

// 方式1
struct studentInfo{
    int id;
    char gender;
    char name[20];
    char major[20];
}ZHANGHAORAN,stu[38];
// 方式2
struct studentInfo{
    int id;
    char gender;
    char name[20];
    char major[20];
};
studentInfo ZHANGHAORAN;
studentInfo stu[38];

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

說(shuō)明:

結(jié)構(gòu)體內(nèi)部可以定義除了自己本身的任意數(shù)據(jù)類型(定義自己本身會(huì)引起循環(huán)定義問(wèn)題),但是可以定義自身類型的指針變量。

struct studentInfo{
    int id;
    char gender;
    char name[20];
    studentInfo* next;
}stu,*p;
// 結(jié)構(gòu)體普通變量訪問(wèn)結(jié)構(gòu)體內(nèi)部元素
stu.id
stu.name
stu.next
// 結(jié)構(gòu)體指針變量訪問(wèn)結(jié)構(gòu)體內(nèi)部元素
// 說(shuō)明:方式1和方式2等價(jià)
// 方式1
(*p).id
(*p).name
(*p).next
// 方式2
p->id
p->name
p->next

結(jié)構(gòu)體的初始化:
這里介紹結(jié)構(gòu)體的構(gòu)造函數(shù):

struct studentInfo{
    int id;
    char gender;
    char name[20];
    // 默認(rèn)構(gòu)造函數(shù),在定義了新的構(gòu)造函數(shù)后被覆蓋,如需使用要單獨(dú)定義。
    studentInfo(){}
    // 自定義構(gòu)造函授
    // 方式1
    studentInfo(int _id,char* _name){
        id = _id;
        name = _name;
    }
    // 方式2 簡(jiǎn)化版
    studentInfo(int _id,char _gender, char* _name):id(_id),gender(_gender),name(_name){
        
    }
};

實(shí)例:

#include "cstdio"
struct Point{
    int x;
    int y;
    Point(){}
    Point(int _x,int _y):x(_x),y(_y){}
};
Point pt[10];
int main(){
    for(int i = 0 ;i < 10; i ++ ){
        pt[i] = Point(i+1,i+1);
    }
    for(int i = 0 ; i < 10 ; i ++){
        printf("(%d,%d) ",(*(pt+i)).x,(*(pt+i)).y);
    }
    return 0;
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        (1,1) (2,2) (3,3) (4,4) (5,5) (6,6) (7,7) (8,8) (9,9) (10,10) 
        Process finished with exit code 0

     */
}

九、補(bǔ)充

cin與cout(不建議使用)

cin和cout是C++中的輸入與輸出函數(shù),需要添加頭文件<code>#include<iostream></code>和<code>using namespace std;</code>后才能使用。

#include "iostream"
using namespace std;
int main(){
    char name[20];
    int age;
    char gender;
    char desc[200]={};
    /* cin函數(shù):
     * 1. cin采用輸入運(yùn)算符">>"進(jìn)行輸入,輸入不用指定格式,也不需要加取地址運(yùn)算符"&"。
     * 2. cin可同時(shí)讀入多個(gè)變量,只需往后面使用>>進(jìn)行擴(kuò)展即可。
     * 3. 當(dāng)需要讀入一整行時(shí),可以使用cin.getline()函數(shù)
     */
    cin >> name >> age >> gender;
    getchar(); // 吸收換行符
    cin.getline(desc, 200);
    /*
     * cout函數(shù):
     * 1. 使用方法和cin幾乎一致,只不過(guò)使用的是輸出運(yùn)算符"<<"。
     * 2. 兩種換行方式:
     *     a. "\n"
     *     b. endl(means 'end of line')
     */
    cout<<"name:"<<name<<"\n"<<"age:"<<age<<"\n"<<"gender:"<<gender<<"\n"<<"desc:"<<desc<<endl;
    return 0 ;
    /*
     *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
        zhanghaoran
        20
        M
        The monitor of class 1821801z
        name:zhanghaoran
        age:20
        gender:M
        desc:The monitor of class 1821801z

        Process finished with exit code 0
     */
}

說(shuō)明:

在考試中,不推薦使用cin和cout進(jìn)行輸入輸出,因?yàn)樵跀?shù)據(jù)量較大的情況下,有可能數(shù)據(jù)還沒(méi)有輸入完就超時(shí)了,因此只有在十分必要的情況下再去用cin和cout函數(shù),推薦優(yōu)先使用C語(yǔ)言的scanf()和printf()函數(shù)。

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

由于計(jì)算機(jī)中采用有限位的二進(jìn)制編碼,因此浮點(diǎn)數(shù)在計(jì)算機(jī)中的存儲(chǔ)并不總是精確的,并且再經(jīng)過(guò)大量計(jì)算后,誤差會(huì)更加明顯,這樣就會(huì)對(duì)比較操作造成極大的干擾。

于是,為了提高浮點(diǎn)數(shù)比較結(jié)果的準(zhǔn)確性,我們需要引進(jìn)一個(gè)極小數(shù)eps來(lái)對(duì)誤差進(jìn)行修正。

這樣,當(dāng)一個(gè)數(shù)a落在[b-eps,b+eps]時(shí),我們就應(yīng)判斷a==b是成立的。

實(shí)際上,eps可以任取,但經(jīng)驗(yàn)表明,eps取108最合適。

const double eps = 1e-8;

我們把比較操作寫成宏定義的形式:

#define equ(a,b) ((fabs((a)-(b)))<(eps))

于是,我們可以這樣對(duì)兩個(gè)浮點(diǎn)數(shù)進(jìn)行比較(注意觀察兩種方式的結(jié)果):

#include <cmath>
#include <cstdio>
const double eps = 1e-8;
#define Equ(a,b) ((fabs((a)-(b)))<(eps))

int main(){
    double d1 = 4 * asin(sqrt(2.0) / 2);
    double d2 = 3 * asin(sqrt(3.0) / 2);
    // 方式1
    printf("%d\n",(d1==d2));
    // 方式2
    printf("%d\n",Equ(d1,d2));
    return 0;
/*
 *  /Users/zhr/CLionProjects/untitled/cmake-build-debug/untitled
    0
    1

    Process finished with exit code 0
 */
}

我們可以寫出其他運(yùn)算符的宏定義形式:

// 大于(<)
#define More(a,b) ((a)-(b)) > (eps)
// 小于(<)
#define Less(a,b) ((a)-(b)) < (-eps)
// 不大于(<=)
#define LessEqu(a,b) ((a)-(b)) < (eps)
// 不小于(>=)
#define MoreEqu(a,b) ((a)-(b)) > (-eps)

關(guān)于圓周率π

圓周率π不需要死記,由 "cos(π) = -1" 得 "arccos(-1) = π",即<code>const double Pi = acos(-1.0);</code>

END

?著作權(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)容