国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

20170215C語言提升08_指針_02數組指針及指針數組及函數指針

2019-11-08 20:09:17
字體:
來源:轉載
供稿:網友

數組指針:

1:一維數組:數組名相當于當前類型的一個指針,而且為const的指針,指向(指針里面的內容)不可變。

2:一維數組和二維數組的內存分布是完全一樣的,但是還是有不同。首地址+1的時候,一位數組加的數組類型的大小,二位數組加的是第二維大小*數據類型大小(類型為數組類型)。
#include <stdio.h>int main(){	int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };	int other[2][5] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };	PRintf("%p/t%p/n", array, array + 1);		//后者   +1*sizeof(*array) = +4	printf("%p/t%p/n", other, other + 1);		//后者   +1*sizeof((*array)[5]) = +20	return 0;}

3:上面二維數組的時候用數組名+1實際上是加上數組類型的大小。在以為數組名前面加&符號得到的實際上也是數組類型。

    注意:數組類型實際上是由兩個因素決定的:

            1:元素類型 2:數組大小。任何一個數組都存在其數組類型。

下面是數組指針的用法:    int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };    int (*parray)[10] = &array; //前面的就是數組指針,它指向的是數組類型    printf("%p/t%p/n", parray, parray + 1); //這里 +1 實際上是 + 1*sizeof(*(parray[10])) = +40;

4:平時使用數組指針不會像上面這種方式定義。可以使用typedef來定義。

#include <stdio.h>typedef int (INT10)[10];		//數組類型int main(){	int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };	int other[2][5] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };	printf("%p/t%p/n", array, array + 1);		//后者   +1*sizeof(*array) = +4	printf("%p/t%p/n", other, other + 1);		//后者   +1*sizeof(*(array[5])) = +20	int (*parray)[10] = &array;		//前面的就是數組指針,它指向的是數組類型	printf("%p/t%p/n", parray, parray + 1);		//這里  +1  實際上是  +  1*sizeof(*(parray[10])) = +40;	INT10 *intarray = &array;	printf("%d/n", sizeof(INT10));		//40	printf("%p/t%p/n", intarray, intarray + 1);		//+1 = +40byte	return 0;}

5:數組指針兩個比較重要的因素:元素類型,數組大小

    注意:定義數組指針的時候,數組大小必須要吻合(warning C4048: “int (*)[5]”和“int (*)[10]”數組的下標不同),類型也應該吻合(warning C4133: “初始化”: 從“int (*)[10]”到“char (*)[10]”的類型不兼容),否則會產生警告。

6:二維數組里面的第一個維度相當于就是存儲的數組指針,他們指向的是多個以而為下標大小的數組類型。+1也就是加的二維的大小。

    下面的代碼可以更好的讓我們理解數組指針:

#include <stdio.h>void foo(int (*array)[10])	//定義成數組指針,這樣才是接收常量數組指針最正確的方式。二維的寫兩個[][]。{}int main(){	int array[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };	int other[2][5] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };//	foo(array);		//array -> 常量指針(int * const)//	foo(other);		//other -> 常量指針(int(*)[5])	foo(&array);		//&array -> 常量數組指針(int(*)[10])//	foo(&other);		//&other -> 常量數組指針(int(*)[2][5])	return 0;}

指針數組:

1:指針數組就是存放指針的數組,很好理解。一個數組,它里面有很多個指針。
#include <stdio.h>int main(){	char *key1s[10] = { "aaa", "bbb", "ccc" };	//這種就是指針數組,就是一個存放指針的數組。	//上面這個指針數組可以存放10個字符指針,字符串可以存放的長度和這個沒有任何關系。字符串有多長和指針無關。	char key2s[100][100] = { 0 };	//這里面可以存放(管理)100個字符串,能夠存放的字符串長度可以是10000(-1)。	return 0;}    注意:上面程序的key1s和key2s的區別:key1s是只可讀的,key2s是可讀寫的。key1s為指針數組,key2s為字符數組,C語言是沒有字符串類型。2:不同初始化方式保存的位置以及是否可改:
#define _CRT_SECURE_NO_WARNINGS#include <stdio.h>#include <stdlib.h>#include <string.h>int main(){	char *key1s[10] = { "aaa", "bbb", "ccc" };	//這種就是指針數組,就是一個存放指針的數組。	//上面這個指針數組可以存放10個字符指針,字符串可以存放的長度和這個沒有任何關系。字符串有多長和指針無關。	char key2s[100][100] = { 0 };	//這里面可以存放(管理)100個字符串,能夠存放的字符串長度可以是10000(-1)。//							指針可改?		數據可改?	//堆區:	char *str1 = malloc(100 * sizeof(char));	//可改			可改	//棧區:	char str2[100];					//不可改			可改	//常量區:	char *str3 = "";				//可改			不可改	char *str4 = str1;	strcpy(str4, "100");				//可改	正確操作		char *str5 = str3;	strcpy(str5, "100");				//不可改	錯誤操作		在常量區	char *str6 = str2;	str6[10] = '1';					//可改	正確操作	return 0;}3:指針數組的參數傳遞實際上是傳遞的指針的指針。傳參為二級指針。
#include <stdio.h>void foo(char *key[])//傳遞過來的是指針數組的首元素地址。是拷貝過來的。{	printf("%s/n", key[1]);//bbb	printf("%s/n", key[2]);//ccc	printf("%s/n", key[3]);//<null>	char *str = "123456";	key[1] = str;	printf("%s/n", key[1]);//123456}int main(){	char *key1s[10] = { "aaa", "bbb", "ccc" };	foo(key1s);	//key1s		首元素類型		char**	//&key1s	數組指針			char*(*)[10]	指針數組的數組指針	return 0;}4:指針數組在main函數里面就有運用,真實的main函數織機上是這樣的:
#include <stdio.h>//main函數實際上為操作系統調用。操作系統默認會傳遞幾個參數進去。int main(int argc, char* argv[], char* env[])//argc是argv的數量,argv是操作系統傳遞的參數,env是環境變量。{	for (int i = 0; i < argc; ++i)	{		printf("%s/n", argv[i]);	}	//操作系統傳遞的參數一是文件路徑。	//還可以在exe的快捷方式里目標的最后加上字符串 也可以傳遞進來。	//還可以通過cmd執行的時候,在后面加上一些參數	int  i = 0;	while (env[i] != NULL)	{		printf("%s/n", env[i++]);	}	return 0;}

函數指針:

1:函數也有自己的類型,函數指針主要用于做回調函數以及函數的路由等。
#include <stdio.h>int Foo(int one, int two)//函數類型是    int(*pfoo)(int, int){	return one + two;}void Foo2()//函數類型是    void(*pfoo2){}typedef int FOOTYPE(int, int);//可以定義函數類型,int main(){	void *pFoo = &Foo;	int(*pfoo)(int, int) = Foo;//int(*pfoo)(int, int) = &Foo;//這里加&和不加&是完全一樣的,這里與變量不一樣。	void(*pfoo2) = Foo2;//	printf("%d/r/n", pFoo(1, 2));	//不知為什么出錯	printf("%d/r/n", pfoo(1, 2));	FOOTYPE *p = &Foo;		//使用typedef定義的類型來申請指針。	printf("%d/r/n", p(2, 3));	return 0;}2:typedef定義的函數類型是可以當作參數來使用的,能夠在外部來傳遞,調用指定的方法
#include <stdio.h>typedef int FOOTYPE(int, int);//可以定義函數類型int Foo(int one, int two)//函數類型是    int(*pfoo)(int, int){	return one + two;}void Foo2()//函數類型是    void(*pfoo2){}typedef void (FUNCERROR)(int);void PrintError(int code){	printf("Error: %d", code);}void SetValue(char*array[], char*value, FUNCERROR *error){	if (array == NULL)		error(100);}int main(){	void *pFoo = &Foo;	int(*pfoo)(int, int) = Foo;//int(*pfoo)(int, int) = &Foo;//這里加&和不加&是完全一樣的,這里與變量不一樣。	void(*pfoo2) = Foo2;//	printf("%d/r/n", pFoo(1, 2));	//不知為什么出錯	printf("%d/r/n", pfoo(1, 2));//可以看出調用和普通的函數調用區別不大	FOOTYPE *p = &Foo;		//使用typedef定義的類型來申請指針。	printf("%d/r/n", p(2, 3));	SetValue(NULL, NULL, PrintError);//會打印error: 100	return 0;}

復習:


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 唐山市| 横峰县| 锡林郭勒盟| 叙永县| 修水县| 顺义区| 容城县| 济源市| 阜平县| 青川县| 东至县| 三台县| 林芝县| 池州市| 汉中市| 宣武区| 潍坊市| 龙里县| 油尖旺区| 阳曲县| 大港区| 方山县| 科尔| 通山县| 娄烦县| 阿城市| 犍为县| 祁连县| 于都县| 兴安县| 万荣县| 驻马店市| 永靖县| 乌鲁木齐市| 南郑县| 灌南县| 河北省| 南木林县| 紫云| 静乐县| 秀山|