成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

C語(yǔ)言指針——從入門(mén)到精通-創(chuàng)新互聯(lián)

〇、前言

本文是本人在學(xué)習(xí) C語(yǔ)言的過(guò)程中所積累的對(duì) C語(yǔ)言指針的感悟,可能會(huì)有些地方描述不準(zhǔn)確,還請(qǐng)指出。本文遵循一般文章結(jié)構(gòu),從簡(jiǎn)單到難,從基本概念到抽象總結(jié)。適合任何任何學(xué)習(xí) C語(yǔ)言的人群。

我們提供的服務(wù)有:成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、微信公眾號(hào)開(kāi)發(fā)、網(wǎng)站優(yōu)化、網(wǎng)站認(rèn)證、來(lái)賓ssl等。為超過(guò)千家企事業(yè)單位解決了網(wǎng)站和推廣的問(wèn)題。提供周到的售前咨詢(xún)和貼心的售后服務(wù),是有科學(xué)管理、有技術(shù)的來(lái)賓網(wǎng)站制作公司一、指針的概念

指針的值就是某一個(gè)變量的內(nèi)存地址,指針變量就是用來(lái)存放某個(gè)變量的內(nèi)存地址的變量,和廣義的變量沒(méi)有什么區(qū)別。

在同一CPU構(gòu)架下,不同類(lèi)型的指針變量所占用的存儲(chǔ)單元長(zhǎng)度是相同的。這是因?yàn)椴僮飨到y(tǒng)的位數(shù)與其所能支持的大內(nèi)存有直接的關(guān)系。由于計(jì)算機(jī)是按照字節(jié)尋址的,如在 32 位操作系統(tǒng)下,32位比特位一共能描述 2^32 個(gè)狀態(tài),一個(gè)狀態(tài)標(biāo)記大小為 1B(一般定義8位(bit,比特)為一字節(jié)),所以一共有 2^32*1B = 4GB。因此 32 位系統(tǒng)所能支持的大內(nèi)存為 4GB。而對(duì)于 64 位操作系統(tǒng)(目前主流操作系統(tǒng)),所能支持的大內(nèi)存為 2^64*1B = 17179869184GB,這是一個(gè)很大的數(shù),基本上可以支持任何現(xiàn)實(shí)中任意存在的內(nèi)存。

而指針最小就是以字節(jié)為單位進(jìn)行指引,因此對(duì)于 32 位操作系統(tǒng),它也要是 32 位的,即 4 字節(jié)大??;而對(duì)于 64 位操作系統(tǒng),它就得是 64 位 即 8 字節(jié)大小。

我們可以寫(xiě)一個(gè)程序驗(yàn)證下:

#includeint main() {int a = 4;
    int* p = &a;
    printf("%zu\n", sizeof(p));
    // 指針變量占據(jù) 8 個(gè)字節(jié)
    printf("%p\n", p);
    // 變量 a 存放在以?xún)?nèi)存地址為0x16f85f71c開(kāi)頭的內(nèi)存單元中
}

輸出結(jié)果為:

8
0x16f85f71c

在 C/C++語(yǔ)言中,指針一般被認(rèn)為是指針變量,指針變量的內(nèi)容存儲(chǔ)的是其指向的對(duì)象的首地址,指向的對(duì)象可以是變量(指針變量也是變量),數(shù)組,函數(shù)等占據(jù)存儲(chǔ)空間的實(shí)體。

二、指針詳解

以下的例子由易到難,每次增長(zhǎng)一顆星。

(一)★
#includeint main() {int a = 0, b = 1;
    int *p1 = &a, *p2 = &b;
    printf("%p\n%p\n", p1, p2);
    return 0;
}

輸出為:

0x16bacb718
0x16bacb714

這是一個(gè)很簡(jiǎn)單的例子,程序中創(chuàng)建了兩個(gè)局部變量,然后利用指針輸出它們的地址。其中&是取地址符,取出來(lái)以后賦給兩個(gè)指針變量p1、p2,并將其打印出來(lái)。
細(xì)心的話(huà)可以發(fā)現(xiàn)這兩個(gè)地址由大到小,相差為 4。這說(shuō)明棧中的這兩個(gè)變量恰好相鄰,且一個(gè)int類(lèi)型的變量占用 4B大小空間。而且還說(shuō)明??臻g的增長(zhǎng)方向是由大到小的,當(dāng)然我們的主題是指針,這里不再贅述。

(二)★★
#includeint main() {int a = 0;
    int* p = &a;
    printf("通過(guò)指針修改前 a 的值為:%d\n", a);
    *p = 10;
    printf("通過(guò)指針修改后 a 的值為:%d\n", a);
    return 0;
}

輸出為:

通過(guò)指針修改前 a 的值為:0
通過(guò)指針修改后 a 的值為:10

這里就比上面稍微多了一點(diǎn)東西,就是可以通過(guò)指針去修改被該指針?biāo)傅淖兞康闹?。換句話(huà)說(shuō),就是間接修改變量的值。其中*p的含義為解引用,指代的就是變量a。

(三)★★★
#includeint main() {int a = 0, b = 1;
    int *p1 = &a, *p2 = &b;

    printf("a在%p\n", p1);
    printf("b在%p\n", p2);

    int **pp1 = &p1, **pp2 = &p2;

    printf("a的指針p1在%p\n", pp1);
    printf("a的指針p1在%p\n", pp2);
    
    return 0;
}

輸出為:

a在0x16da73718
b在0x16da73714
a的指針p1在0x16da73708
a的指針p1在0x16da73700

可以看到,指針變量也有一個(gè)內(nèi)存地址,它指向的是一個(gè)指針變量的內(nèi)存地址。那么,我們同樣可以通過(guò)二級(jí)指針對(duì)一級(jí)指針作出修改:

#includeint main() {int a = 0, b = 1;
    int *p1 = &a, *p2 = &b;

    printf("a在%p\n", p1);
    printf("b在%p\n", p2);

    int **pp1 = &p1, **pp2 = &p2;

    printf("a的指針p1在%p\n", pp1);
    printf("b的指針p2在%p\n", pp2);

    // 交換兩個(gè)二級(jí)指針
    int** temp = pp1;
    pp1 = pp2;
    pp2 = temp;
    printf("a的指針p1在%p\n", pp1);
    printf("b的指針p2在%p\n", pp2);
    
    return 0;
}

輸出為:

a在0x16fa0b718
b在0x16fa0b714
a的指針p1在0x16fa0b708
b的指針p2在0x16fa0b700
a的指針p1在0x16fa0b700
b的指針p2在0x16fa0b708

這里需要提一點(diǎn),就是當(dāng)一個(gè)變量(前提是一個(gè)變量)為表達(dá)式左值時(shí),它代表一個(gè)變量,當(dāng)其為右值時(shí),它代表變量的值。關(guān)于左值右值的概念,不再贅述。

交換前的指針關(guān)系:
在這里插入圖片描述
交換后的指針關(guān)系:
在這里插入圖片描述
我們還可以嘗試通過(guò)pp2來(lái)直接修改變量a的值:

#includeint main() {int a = 0, b = 1;
    int *p1 = &a, *p2 = &b;

    printf("a在%p\n", p1);
    printf("b在%p\n", p2);

    int **pp1 = &p1, **pp2 = &p2;

    printf("a的指針p1在%p\n", pp1);
    printf("a的指針p1在%p\n", pp2);

    // 交換兩個(gè)二級(jí)指針
    int** temp = pp1;
    pp1 = pp2;
    pp2 = temp;
    printf("a的指針p1在%p\n", pp1);
    printf("a的指針p1在%p\n", pp2);
    
    **pp2 = 10;
    printf("修改后a的值為:%d\n", a);
    return 0;
}

輸出為:

a在0x16b1ff718
b在0x16b1ff714
a的指針p1在0x16b1ff708
a的指針p1在0x16b1ff700
a的指針p1在0x16b1ff700
a的指針p1在0x16b1ff708
修改后a的值為:10

其中二級(jí)指針pp2解引用了兩次,才與a等價(jià)。這里的例子大量使用了二級(jí)指針,即int**類(lèi)型的變量。具體來(lái)說(shuō),指針類(lèi)型有多種,比如int* p,int** p,int*** p等等。

(四)★★★★

前面幾節(jié)都是很簡(jiǎn)單的概念,接下來(lái)幾節(jié)將會(huì)引入數(shù)組、字符串等來(lái)對(duì)指針的使用進(jìn)行更深的闡述。

(1)關(guān)于數(shù)組名
#includeint main() {int a[3] = {1, 2, 3};
    printf("%p\n", a);
    printf("%zu\n", sizeof(a));
}

輸出為:

0x16fc9b708
12

可以看到,數(shù)組名 a 是一個(gè)指針類(lèi)型的值,它實(shí)際上指向的是大小為 12B 的連續(xù)空間的首地址。數(shù)組名其實(shí)是一個(gè)常量,因此它不能當(dāng)做左值。當(dāng)我們修改它的值時(shí),它會(huì)提示array type 'int [3]' is not assignable,意思是這個(gè)變量不可被修改。另外,a 的大小為 12B 這表明和普通的指針并不一樣,或者a并不是簡(jiǎn)單的指針。因此,很多參考書(shū)上說(shuō)“數(shù)組名本質(zhì)上就是一個(gè)指針”的說(shuō)法是完全錯(cuò)誤的。

(2)利用數(shù)組名來(lái)訪(fǎng)問(wèn)某個(gè)內(nèi)存單元

我們剛提到,數(shù)組名是一個(gè)常量,因此我們可以利用一個(gè)指針變量來(lái)訪(fǎng)問(wèn)內(nèi)存單元:

#includeint main() {int a[3] = {1, 2, 3};
    int* p = a;
    for (int i = 0; i< 3; i++) {printf("%d ", *(p + i));
    }
    return 0;
}

輸出為:

1 2 3

其中p+i的含義是,指針指向了p所指的內(nèi)存再向右偏移i個(gè)類(lèi)型為int的內(nèi)存單元。之所以是int,是因?yàn)槲覀兟暶鞯氖?code>int類(lèi)型的指針。比如:

#includeint main() {int a[3] = {1, 2, 3};
    
    int* p = a;
    printf("%p\n", p);
    printf("%p\n", p + 1);
    printf("%p\n", p + 2);

    long *q = a;
    printf("%p\n", q);
    printf("%p\n", q + 1);

    return 0;
}

輸出為:

0x16f1c3708
0x16f1c370c
0x16f1c3710
0x16f1c3708
0x16f1c3710

可以看到,因?yàn)?code>long類(lèi)型占 8 個(gè)字節(jié)(long的定義為不少于int類(lèi)型的大小,有些計(jì)算機(jī)系統(tǒng)longint等價(jià),但大部分long類(lèi)型都占 8 字節(jié)),int占 4 個(gè)字節(jié),所以long類(lèi)型的指針偏移的長(zhǎng)度為int類(lèi)型的兩倍。同樣,我們可以搞點(diǎn)稍微復(fù)雜的事情:

#includeint main() {int a[3] = {1, 2, 3};

    printf("數(shù)組的首地址為:%p\n", a);

    int* p = (int*)(&a + 1);
    int* q = a + 3;
    printf("此時(shí) p 指向:%p\n", p);
    printf("此時(shí) q 指向:%p\n", q);
    return 0;
}

輸出為:

數(shù)組的首地址為:0x16b25f708
此時(shí) p 指向:0x16b25f714
此時(shí) q 指向:0x16b25f714

這說(shuō)明,&a + 1的偏移量為3個(gè) int 類(lèi)型大小。這里就需要格外注意,指針偏移一個(gè)單位是參考哪一種類(lèi)型的變量指針的。這里參考的是int a[3],也就是說(shuō),a的數(shù)據(jù)類(lèi)型為int[3],偏移一次當(dāng)然偏移 12B了,因?yàn)?code>int[3]的大小就是 12B!

我們就可以很簡(jiǎn)單地預(yù)見(jiàn)以下的程序輸出:

#includeint main() {int a[3] = {1, 2, 3};

    int* p = (int*)(&a + 1);
    printf("%d\n", *(p - 1));
    return 0;
}

輸出為:

3

因?yàn)?code>p指向的是數(shù)組最后一個(gè)元素的下一個(gè)內(nèi)存單元,又因?yàn)?code>p是int類(lèi)型的指針,因此一個(gè)偏移量大小為int,所以p-1之后,就指向了數(shù)組的最后一個(gè)元素。

(3)字符串

字符串是一個(gè)重點(diǎn),也是一個(gè)難點(diǎn)。但是只要掌握指針基本概念,把握字符數(shù)組和字符串的區(qū)別和聯(lián)系,也是送分題。

首先得了解下字符串輸出的基本原理:

#includeint main() {char c[3] = {'a', 'b', 'c'};
    printf("%s\n", c);
    return 0;
}

輸出為:

abc*/

為什么會(huì)有這么奇怪的輸出呢?這是因?yàn)?code>printf("%s\n", c)輸出字符串時(shí),只要輸入一個(gè)指針(任何類(lèi)型的指針都可以),就會(huì)一直打印,直到遇到'\0'為止。比如下面這個(gè)程序:

#includeint main() {int a[3] = {100, 101, 102};
    printf("%s\n", a);
    return 0;
}

輸出結(jié)果為:

d

這是因?yàn)閿?shù)據(jù)存放為大端方式,100存在到第一個(gè)高地址字節(jié)空間后,后面三個(gè)存放的都是'\0',所以就停止打印了。我們可以印證一下:
假設(shè)我們想要打印出"abc",這就要保證內(nèi)存單元里面放的是97\98\99\00。即0x61626300。大端方式存入內(nèi)存單元就為:0x00636261,這個(gè)數(shù)字 10 進(jìn)制大小為6513249,因此:

#includeint main() {int a[3] = {6513249,100,200};
    printf("%s\n", a);
    return 0;
}

程序輸出為:

abc

果然輸出了"abc",這無(wú)疑是一件令人激動(dòng)的事情!當(dāng)然,這里的重點(diǎn)是字符串輸出,就不再贅述其它了。

經(jīng)過(guò)上面的例子,可以充分地說(shuō)明輸出函數(shù)的特性,即只要是一個(gè)指針,丟給printf("%s\n", a)后,就會(huì)打印出結(jié)果。

所以字符串是使用空字符'\0'結(jié)尾的一組數(shù)據(jù),就這么簡(jiǎn)單。我們可以很容易地構(gòu)造出一些字符串,比如我們上面通過(guò)一些手段構(gòu)造的"abc",以及下面用字符數(shù)組構(gòu)造的字符串(常用手段):

#includeint main() {char string[12] = {'H','e','l','l','o','w','o','r','l','d','!','\0'};
    printf("%s\n",string);

    char *string1 = "Helloworld!";
    printf("%s\n",string1);

    return 0;
}

在用字符數(shù)組構(gòu)造字符串時(shí),一定要注意在最后一個(gè)內(nèi)存單元加上’\0’,因?yàn)槲覀儾荒鼙WC字符串結(jié)束后的下一個(gè)內(nèi)存單元放的是不是’\0’,因此字符串可能不會(huì)正常終止。

還可以使用字面值常量來(lái)創(chuàng)建字符串,比如char *string1 = "Helloworld!"。這種不需要在在最后一個(gè)內(nèi)存單元加上'\0',編譯系統(tǒng)會(huì)自動(dòng)加。

(4)字符串賦值

為了明白字符串賦值的本質(zhì),這里不會(huì)使用庫(kù)函數(shù)提供的各種函數(shù),比如strcpy(),strcat()等。

#includeint main() {char string[12] = {'H', 'e', 'l', 'l', 'o', 'w',
                       'o', 'r', 'l', 'd', '!', '\0'};
    char string1[12] = {0};  // 初始化與否都可以,因?yàn)榫o接著我們就要對(duì)其賦值
    for (int i = 0; i< 12; i++) {string1[i] = string[i];
    }
    printf("%s\n", string1);

    return 0;
}

本例采用了逐個(gè)字符賦值的方法來(lái)完成對(duì)字符串的賦值。我們的主題是指針,那么可不可以像下面那樣賦值:

#includeint main() {char string[12] = {'H', 'e', 'l', 'l', 'o', 'w',
                       'o', 'r', 'l', 'd', '!', '\0'};
    char string1[12] = {0};  // 初始化與否都可以,因?yàn)榫o接著我們就要對(duì)其賦值
    string1 = string;
    printf("%s\n", string1);

    return 0;
}

當(dāng)然不可以,前文已經(jīng)提到,數(shù)組名只一個(gè)地址常量,既然是常量當(dāng)然就不可以被修改,自然就不能當(dāng)做左值。事實(shí)上,上文還提到了通過(guò)字面值常量來(lái)創(chuàng)造字符串,既然是常量,那么自然也就不能修改,比如:

#includeint main() {char* p = "Helloworld!";
    *(p + 1) = 'E';
    printf("%s\n", p);
    return 0;
}

這個(gè)程序的目的是把"Helloworld"改為"HElloworld",那么目的能達(dá)到嗎?自然不能,編譯器會(huì)報(bào)錯(cuò)bus error。我們不去管這個(gè)錯(cuò)誤的具體含義,只需要知道常量字符串是無(wú)法修改的。也就是說(shuō),我們的指針并不是指在哪里就改哪里,那計(jì)算機(jī)系統(tǒng)就亂套了!

如果我們迫切的想要修改,可以這樣做:

#include#include#includeint main() {char* p = "Helloworld!";
    int len = strlen(p);
    char* newString = (char*)malloc(sizeof(char) * (len + 1));
    for (int i = 0; i< len; i++) {newString[i] = p[i];
    }
    newString[len] = '\0';
    newString[1] = 'E';
    printf("%s\n", newString);

    return 0;
}

輸出結(jié)果為:

HElloworld!

過(guò)程也很簡(jiǎn)單,就是申請(qǐng)一塊內(nèi)存空間,先復(fù)制過(guò)來(lái),然后再修改成想要的樣子。

(五)★★★★★

開(kāi)始之前,我們先來(lái)談?wù)勈裁词悄涿麛?shù)組。顧名思義,匿名就是藏起來(lái)名字的意思。比如:

#includeint main() {int* p = (int[2]){19, 20};
    return 0;
}

我們定義了一個(gè)匿名的數(shù)組,并賦給一個(gè)int*類(lèi)型的變量 p。匿名類(lèi)在 Java 中 的作用之一是起到很好的封裝性,同樣在 C語(yǔ)言中也有這樣的作用。這個(gè)數(shù)組,只能通過(guò) p 訪(fǎng)問(wèn)。你可能注意到了,我并沒(méi)有用int類(lèi)型的指針去描述 p,而是用int*類(lèi)型來(lái)描述 p。

(1)數(shù)據(jù)類(lèi)型

C語(yǔ)言中的數(shù)據(jù)類(lèi)型有哪些?一般來(lái)說(shuō),有四大類(lèi)型,分別是基本類(lèi)型,構(gòu)造類(lèi)型,空類(lèi)型以及我們講的指針類(lèi)型。
在這里插入圖片描述

指針類(lèi)型是花樣最多的一種類(lèi)型,它通常包括 5 類(lèi):int*char*,int**,int(*)[],int*[]。
在這里插入圖片描述

換句話(huà)說(shuō),從語(yǔ)法的角度講,把指針聲明語(yǔ)句里的指針名字去掉,剩下的部分就是這個(gè)指針的類(lèi)型。比如,給出一個(gè)例子:

#includeint main() {int a[3] = {1, 2, 3};

    int* p;
    char* s;
    int** q;
    int(*pt)[3];
    int*[3];

    return 0;
}

在這個(gè)例子中,指針的類(lèi)型分別為:int*,char*int**,int(*)[3],int*[3]。我們經(jīng)常用到數(shù)組指針以及指針數(shù)組,因此重點(diǎn)理解它們就是關(guān)鍵。

(2)指針數(shù)組

對(duì)于指針數(shù)組,描述它的語(yǔ)法為int*p[3]。首先,它是一個(gè)數(shù)組,所以得是個(gè)p[3];其次要是一個(gè)指針類(lèi)型的也就是int*。所以就產(chǎn)生了int*p[3]。數(shù)組 p 中每一個(gè)元素都是一個(gè)指針,指向一個(gè)一維數(shù)組。比如:

#includeint main() {int a[3] = {1,2,3};
    int b[3] = {4,5,6};
    int c[5] = {7,8,9,10,11};

    int *p[3] = {a,b,c};

    return 0;
}

為了更明顯,不如把它寫(xiě)成int*(p[3]),但是由于[3]的結(jié)合度非常高,因此這個(gè)括號(hào)可以去掉。

(3)數(shù)組指針

顧名思義,數(shù)組指針就是一個(gè)指向數(shù)組的指針。我們這樣定義:·int(*p)[3]·。首先得是一個(gè)指針,因此得是(int*p);然后得是一個(gè)數(shù)組類(lèi)型的,因此就是(int*p)[3]。但這樣明顯歧義了,因此就成了int(*p)[3]。它指向一個(gè)類(lèi)型為int[3]的變量。比如:

#includeint main() {int a[3] = {1,2,3};
    int (*p)[3] = &a;
}

a 的數(shù)據(jù)類(lèi)型為int[3],p 的類(lèi)型為int(*)[3]。要想讓 p指向 a,我們只需要把變量 a 的地址賦值給 p,即int (*p)[3] = &a。為了更明顯,我們可以這樣修改一下程序:

#includeint main() {int a[3] = {1,2,3};
    int b[4] = {1,2,3,4};
    int (*p)[3];
    p = &a;
    p = &b;
}

可以看到這樣的報(bào)錯(cuò):incompatible pointer types assigning to 'int (*)[3]' from 'int (*)[4]' [-Wincompatible-pointer-types]。意思是從“int (*)[4]”[-Wincompatible-pointer-types] 分配給“int (*)[3]”的不兼容指針類(lèi)型。這也從側(cè)面反映了int(*)[3]是一種確定的指針類(lèi)類(lèi)型。

能看到這里,想必你已經(jīng)功力深厚,返璞歸真了,哈哈~

三、總結(jié)

這里只總結(jié)難點(diǎn):

  • 對(duì)于聲明一個(gè)指針數(shù)組int*p[3],這里的重點(diǎn)是 p 的數(shù)據(jù)類(lèi)型為int*[3],數(shù)組每一個(gè)元素都是一個(gè)指針,指向int 類(lèi)型的數(shù)組
  • 對(duì)于聲明一個(gè)數(shù)組指針int(*p)[3],這里的重點(diǎn)是 p 的數(shù)據(jù)類(lèi)型為int(*)[3],p 是一個(gè)指針,指向類(lèi)型為 int[3]的變量

全文完,感謝你的閱讀。

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級(jí)服務(wù)器適合批量采購(gòu),新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)站欄目:C語(yǔ)言指針——從入門(mén)到精通-創(chuàng)新互聯(lián)
當(dāng)前鏈接:http://jinyejixie.com/article38/dieopp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供企業(yè)建站、小程序開(kāi)發(fā)、動(dòng)態(tài)網(wǎng)站全網(wǎng)營(yíng)銷(xiāo)推廣、微信公眾號(hào)、網(wǎng)站維護(hù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
兴海县| 金湖县| 鲁甸县| 乐昌市| 宜兰市| 通州市| 莱芜市| 东山县| 喀什市| 东兴市| 广宗县| 梁平县| 澜沧| 元谋县| 安阳市| 镇巴县| 绍兴市| 深圳市| 巍山| 阿鲁科尔沁旗| 奉化市| 从化市| 荥经县| 塔城市| 岫岩| 寿阳县| 安图县| 同江市| 横峰县| 霍山县| 颍上县| 梅河口市| 广丰县| 上虞市| 法库县| 东乌| 江油市| 遂川县| 元江| 滨州市| 台南市|