整頓C說話中各類類型指針的特征與用法。本站提示廣大學習愛好者:(整頓C說話中各類類型指針的特征與用法)文章只能為提供參考,不一定能成為您想要的結果。以下是整頓C說話中各類類型指針的特征與用法正文
指針為何要辨別類型:
在統一種編譯器情況下,一個指針變量所占用的內存空間是固定的。好比,在16位編譯器情況 下,任何一個指針變量都只占用8個字節,其實不會隨所指向變量的類型而轉變。
固然一切的指針都只占8個字節,但分歧類型的變量卻占分歧的字節數。
一個int占用4個字節,一個char占用1個字節,而一個double占用8字節;
如今只要一個地址,我怎樣能力曉得要從這個地址開端向後拜訪若干個字節的存儲空間呢,是4個,是1個,照樣8個。
所以指針變量須要它所指向的數據類型告知它要拜訪若干個字節存儲空間。
也就是說,假如不指定指針的類型,那末當指針指向一個變量的時刻,她從首地址開端,然則它不曉得甚麼時刻停滯,它不曉得要拜訪若干個存儲空間。好比有一個char類型的變量,我用一個指針指向它,然則這個指針我設置成int類型,如許一來這個指針就會向後拜訪四個字節的存儲空間,很顯著獲得的成果不是char類型應當獲得的,所以要辨別類型。
只要指針是可以運算(挪動)的,數組名是弗成以的。
int x[10]; x++; //illegal int* p = x; p++; //legal
兩指針變量相減所得之差是兩個指針所指數組元素之間相差的元素個數。
現實上是兩個指針值(地址)相減之差再除以該數組元素的長度(字節數)。
(pointer2地址值 - pointer地址值) / sizeof(所指向數據類型)
指針之間可以相減,但弗成以相加(相加有意義)。
界說字符串:
字符數組:
char string[] = "hello"; printf("%s\n",string);
字符串指針指向字符串:
char *str = "hello"
應用字符數組來保留的字符串是存在”棧”裡的,所以它是可讀可寫的,所以我們可以修正字符數組裡的某個元素的值。
然則,應用字符指針來保留字符串,它保留的是字符串常量地址,"常量區"是只讀的,所所以弗成改的。
char *str = "hello"; *(str+1) = 'w'; // 毛病
應用留意:
char *str; scanf("%s", str); /* str是一個野指針,他並沒有指向某一塊內存空間,所以不許可如許寫。假如給str分派內存空間是可以如許用的 */ /********* 數組的辦法****************/ char name[20]; scanf("%s",name); /************* 給字符針針分派內存空間的方法***********/ char *name; name=(char*)malloc(50); //此時name曾經指向一個方才分派的地址空間。 scanf("%s",name);
指針函數(是函數,前往值是指針)留意:
假如函數前往一個字符串,那末假如用一個數組以上面的情勢來接的話,是會報錯的:
char *test() { return "hello"; } int main(int argc, const char * argv[]) { char names[10]; names = test(); return 0; }
這是由於,前往的字符串相當於一個如許的數組:{‘h', ‘e', ‘l', ‘l', ‘o', ‘\0'},然則後面我們說過,數組假如在界說的時刻沒有效{}這類方法初始化,那末前面就不克不及再用這類方法初始化了,所以會失足。
處理辦法:將char names[10]改成char *names或許char names[10]直接等於test()。
函數指針(是指針,指向函數):
格局:函數的前往值類型 (*指針變量名) (形參1, 形參2, ...);
int sum(int a,int b) { return a + b; } int (*p)(int,int); p = sum;
運用場景:
挪用函數
將函數作為參數在函數間傳遞
函數指針能更靈巧:
int minus(int a, int b) { return (a - b); } int add(int a, int b) { return (a + b); } int myFunction(int a, int b, int (*funcP) (int, int)) { return funcP(a, b); } int main() { int minusResult = myFunction(10, 20, minus); int addResult = myFunction(10, 20, add); ... return 0; } /* 函數指針能讓法式更靈巧,好比後續有乘、除函數的時刻,只需完成這兩個函數然後在主函數挪用myFunction函數便可。假如是多人協作,分歧的人寫分歧的功效,假如我們來寫myFunction那末根本就不消修正便可以一向應用,異常靈巧。 */
技能:
1、把要指向函數頭拷貝過去
2、把函數稱號應用小括號括起來
3、在函數稱號後面加上一個*
4、修正函數稱號
應用留意:
因為這類指針變量存儲的是一個函數的進口地址,所以對它們作加減運算(好比p++)是有意義的。
如上例,假如想應用p這個函數指針,可以直接向應用sum一樣:
int result = p(10, 10);
也能夠如許:
int result = (*p)(10, 10);
構造體是一種自界說數據類型,留意,它是數據類型。
struct Student { char *name; int age; }; struct Student stu;
留意,構造體的前面是有 ; 的。
在應用構造體類型的時刻,要加上struct症結字。
界說構造體類型的同時界說變量:
struct Student { char *name; int age; } stu;
這類在界說的同時也界說了變量,就相當於:
struct Student { char *name; int age; }; struct Student stu;
界說構造體類型的同時界說變量,今後假如想持續應用這個構造體類型,依然可使用慣例的方法界說:
struct Student newStu;
匿名構造體界說構造體變量:
struct { char *name; int age; } stu;
這類匿名方法與下面的方法比擬,固然看起來更簡練(省去了卻構名),然則要留意,這只能界說一個stu變量,而不克不及再界說新的變量,由於構造名沒有了。