欧美日韩不卡一区二区三区,www.蜜臀.com,高清国产一区二区三区四区五区,欧美日韩三级视频,欧美性综合,精品国产91久久久久久,99a精品视频在线观看

C語言

C語言中各種類型的指針的概念總結(jié)

時(shí)間:2025-06-05 09:07:02 登綺 C語言 我要投稿
  • 相關(guān)推薦

C語言中各種類型的指針的概念總結(jié)

  指針可以說是C語言本身所具有的最大特性,平時(shí)根據(jù)不同使用場合習(xí)慣地將其簡單分類,下面是小編為大家整理的C語言中各種類型的指針的概念總結(jié),希望對大家有所幫助。

C語言中各種類型的指針的概念總結(jié)

  C語言中各種類型的指針的概念總結(jié)

  1.什么是指針

  假設(shè)我們要去訪問一個(gè)變量,有兩種方式:1.通過變量名訪問。2.通過地址訪問。

  int a = 10;

  printf("a = %d",a); //1.通過變量名訪問

  printf("a =%d",*(&a)); //2.通過地址訪問

  //取值運(yùn)算符:把后面內(nèi)存地址中的數(shù)據(jù)取出來

  有了上面的例子,我們引入指針的概念。我們用最粗暴的方法來理解什么是指針,指針就是地址。什么是指針變量?存放地址的變量就是指針變量。指針變量可以類比跟我們之前學(xué)的整形變量,字符變量等,都是屬于變量的一種。

  2.指針基礎(chǔ)內(nèi)容

 。1)如何定義指針

  我們用指針標(biāo)識符*來定義,*的作用是告訴系統(tǒng)這是一個(gè)指針變量,用來存放別人的地址。

  注意:這個(gè)*只有在定義指針變量的時(shí)候才是指針標(biāo)識符,其它時(shí)候是運(yùn)算符的意思。

  int a;

  int *p;

  *p = &a;

  printf("a =%d",*(&a));

  printf("a =%d",*p);

 。2)指針變量對變量類型的要求

  為什么會(huì)在定義指針變量的時(shí)候要特別注意數(shù)據(jù)類型,拿下面的demo為例比來講解。定義一個(gè)int型變量a,這個(gè)變量由于是一個(gè)int型的所以大小為4個(gè)字節(jié),也就是32位。同樣,如果用char類型來定義這個(gè)指針變量的話就是只用了一個(gè)字節(jié),就是八位。這樣就會(huì)出現(xiàn)一個(gè)問題,就是這個(gè)1個(gè)字節(jié)內(nèi)存地址放不下一個(gè)4個(gè)字節(jié)大小的變量。編譯器可能會(huì)報(bào)錯(cuò),即使不報(bào)錯(cuò)打印出來的數(shù)據(jù)也是不完整的。

  #include

  int main()

  {

  int a = 0x1234;

  int *p = &a;

  char *q = &a; //這樣定義是錯(cuò)誤的

  printf("a = %x",*p);

  printf("a = %x",*q);

  return 0;

  }

 。3)練習(xí):指針實(shí)戰(zhàn)之交換數(shù)據(jù)大小

  下面這個(gè)demo的作用是用指針的方式交換兩個(gè)數(shù)據(jù)的大小,通過地址訪問到變量之后再進(jìn)行交換。

  #include

  void changedata(int *p,int *q)

  {

  int tmp;

  tmp = *p;

  *p = *q;

  *q = tmp;

  }

  int main()

  {

  int a = 10;

  int b = 20;

  printf("交換前:a=%d,b=%d",a,b);

  changedata(&a,&b);

  printf("交換后a=%d,b=%d",a,b);

  return 0;

  }

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

  3.通過指針引用數(shù)組

  (1)定義一個(gè)指針變量指向數(shù)組

  如何獲取一個(gè)數(shù)組的首地址,通常有兩種方式:

  1.數(shù)組中首個(gè)元素的地址就是數(shù)組的首地址。

  2.數(shù)組名就是數(shù)組的首地址。下面用代碼表示一下這兩種方式。

  int main()

  {

  int arrary[3] = {1,2,3};

  int *p;

  p = &arrary[0]; //1.數(shù)組中首個(gè)元素的地址就是數(shù)組的首地址。

  p = arrary; //2.數(shù)組名就是數(shù)組的首地址。

  return 0;

  }

 。2)指針偏移遍歷數(shù)組

  我們訪問了首元素的地址之后便可以訪問到該數(shù)組中的每一個(gè)元素。具體如何訪問看下面這個(gè)demo。這里要特別注意一點(diǎn) *(p+i)這里的每次+1不是地址的加一,而是偏移了一個(gè)類型的大小。比如你是int型的指針就偏移4個(gè)字節(jié),是char類型的就偏移一個(gè)字節(jié)。

  用指針的方式訪問數(shù)組在效率上是遠(yuǎn)遠(yuǎn)大于用數(shù)組名訪問數(shù)組的。

  #include

  int main()

  {

  int i;

  int arr[3] = {1,2,3};

  int *p;

  p = arr;

  for(i=0;i<3;i++){

  printf("%d ",*(p+i)); //這里的+1不是地址的加一,而是偏移了一個(gè)類型的大小

  }

  return 0;

  }

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

 。3)練習(xí):指針與數(shù)組的結(jié)合

  實(shí)驗(yàn)效果:輸入五個(gè)數(shù),并依次打印出來

  #include

  void InputArr(int *parr,int size)

  {

  int i;

  for(i=0;i

  printf("請輸入");

  scanf("%d",parr);

  parr++;

  }

  }

  void PrintArr(int *parr,int size)

  {

  int i;

  for(i=0;i

  printf("%d ",*parr);

  parr++;

  }

  }

  int main()

  {

  int arrary[5];

  int size;

  size = sizeof(arrary)/sizeof(arrary[0]);

  InputArr(arrary,size);

  PrintArr(arrary,size);

  return 0;

  }

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

  4.二維數(shù)組的地址

  為了研究二維數(shù)組的地址,我們可以把二維數(shù)組看作成“父子數(shù)組”(C語言并沒有這個(gè)概念,只是方便理解起的名字而已)。有了“父子數(shù)組”的概念,我們就可以把二維數(shù)組拆成兩個(gè)一維數(shù)組來理解。“父數(shù)組”和“子數(shù)組”都可以看作是兩個(gè)一維數(shù)組,只不過“父數(shù)組”比較特殊,它里面的每一項(xiàng)又是一個(gè)數(shù)組。我們知道數(shù)組名就是數(shù)組的首地址這個(gè)概念,如果定義一個(gè)二維數(shù)組int a[3][4],那么a就是數(shù)組名,也就是“父數(shù)組”的名字,接下來我們就要想辦法得出“子數(shù)組”的數(shù)組名,獲得了數(shù)組名也就獲得了地址,這個(gè)也是研究二維數(shù)組地址的重中之重。

  現(xiàn)在定義一個(gè)二維數(shù)組int a[3][4] = {{1,3,5,7},{9,11,13,15},{17,19,21,23}}。

  找個(gè)數(shù)組a是一個(gè)包含了三個(gè)元素的數(shù)組(也可以看作是包含了三個(gè)“子數(shù)組”),并且每一個(gè)元素又是一個(gè)數(shù)組。于是這里的a[0],a[1],a[2]就是代表了數(shù)組的名字,而中[ ]里面的“0,1,2”代表的也不是數(shù)組的大小。a[0],a[1],a[2]分別是這三個(gè)一維數(shù)組的名字,因此子數(shù)組的名字分別為a[0],a[1],a[2],也可以叫做是列地址,a就是行地址。

  所以現(xiàn)在可以思考這樣一個(gè)問題,a+1和a[0]+1分別代表什么含義?

  a+1偏移的是整個(gè)數(shù)組,也就是說從a[0]偏移到a[1],它偏移了一行。

  a[0]+1只是從一個(gè)數(shù)組的某個(gè)元素偏移到了下一個(gè)元素,它偏移了一列。

  5.指針數(shù)組

  指針數(shù)組:多個(gè)指針,叫做指針數(shù)組,數(shù)組中的每一項(xiàng)都是一個(gè)指針變量。

  int a = 2;

  int b = 3;

  int c = 4;

  int *arrary[3]; //指針數(shù)組

  arrary[1] = &a; //數(shù)組中的每一項(xiàng)存放的都是指針變量

  arrary[2] = &b;

  arrary[3] = &c; //三個(gè)普通沒有任何關(guān)系的整形變量的地址存入指針數(shù)組

  6.數(shù)組指針

  數(shù)組指針相比于指針數(shù)組最大的區(qū)別就是它是一個(gè)指針,指向的是數(shù)組。而數(shù)組指針是多個(gè)指針的集合。

  數(shù)組指針,強(qiáng)調(diào)的是類型,數(shù)組的個(gè)數(shù),偏移值是偏移了整個(gè)數(shù)組的大小。

  int arrary[3] = {3,4,5};

  int (*p)[3]; //數(shù)組指針,強(qiáng)調(diào)的是類型,數(shù)組的個(gè)數(shù),偏移值是偏移了整個(gè)數(shù)組的大小。

  p = arrary;

  7.函數(shù)指針

  我們知道普通變量有兩種訪問方式,一種是通過變量名訪問,還有一種是通過指針訪問。同樣函數(shù)也用通過函數(shù)名和指針來調(diào)用。

  #include

  void printwelcome()

  {

  printf("welcome");

  }

  int main()

  {

  void (*p)(); //定義一個(gè)函數(shù)指針

  p = printwelcome; //給指針賦值

  p(); //通過函數(shù)指針調(diào)用函數(shù)

  (*p)();

  return 0;

  }

  如何定義一個(gè)函數(shù)指針?

  void(*p)();

  1.如何表示指針:*

  2.如何指知道是函數(shù):()

  3.函數(shù)指針是專用的,格式要求很強(qiáng)(參數(shù)類型,個(gè)數(shù),返回值)。

  如何給指針賦值?

  p = printwelcome;

  函數(shù)名就是地址名,就像數(shù)組一樣,數(shù)組名就是地址。

  如何通過函數(shù)指針調(diào)用函數(shù)?

  1.直接通過指針名字加括號:p();

  2.取內(nèi)容。(*指針名字)+():(*p)();

  函數(shù)指針練習(xí):有兩個(gè)整數(shù)a和b,用戶輸入1,2或3。如果輸入1則給出a,b中的最大值,如果輸入2,則給出a,b中的最小值,輸入3則輸出a+b的和。

  #include

  int getmax(int data1,int data2)

  {

  return data1>data2 ? data1:data2;

  }

  int getmin(int data1,int data2)

  {

  return data1

  }

  int getsum(int data1,int data2)

  {

  return data1+data2;

  }

  int datahandler(int data1,int data2,int (*pfunc)(int data1,int data2))

  {

  int ret;

  ret = (*pfunc)(data1,data2);

  return ret;

  }

  int main()

  {

  int a = 10;

  int b = 20;

  int cmd;

  int ret;

  int (*pfunc)(int data1,int data2);

  printf("請輸入1最大值,輸入2取最小值,輸入3求和");

  scanf("%d",&cmd);

  switch(cmd){

  case 1:

  pfunc = getmax;

  break;

  case 2:

  pfunc = getmin;

  break;

  case 3:

  pfunc = getsum;

  break;

  default:

  printf("輸入錯(cuò)誤");

  break;

  }

  ret = datahandler(a,b,pfunc);

  printf("輸出結(jié)果為%d",ret);

  return 0;

  }

  8.無類型指針

  函數(shù)原型:void *malloc(size_t size);

  1.void作為函數(shù)返回值的時(shí)候是無類型返回值(無類型不代表沒有返回值),void*在這里同樣是返回的是無類型的指針。

  2.size_t 類型表示C中任何對象所能達(dá)到的最大長度,它是無符號整數(shù)。(其值是大于等于0的)

  3.malloc:中文叫動(dòng)態(tài)內(nèi)存分配,用于申請一塊連續(xù)的指定大小的內(nèi)存塊區(qū)域以void*類型返回分配的內(nèi)存區(qū)域地址。

  用下面的demo加深一下理解(用malloc開辟空間遍歷數(shù)組)。

  #include

  #include

  int main()

  {

  int i,n;

  int *arrary = (int *)malloc(n*sizeof(int)); //將void型指針強(qiáng)轉(zhuǎn)成int型指針

  printf("請輸入開辟個(gè)數(shù)");

  scanf("%d",&n);

  for(i=0;i

  printf("請輸入第%d個(gè)數(shù)",i+1);

  scanf("%d",&arrary[i]);

  }

  for(i=0;i

  printf("第%d個(gè)數(shù)是:%d",i+1,*arrary++);

  }

  return 0;

  }

  9.二級指針

  對二級指針的理解是和一級指針是一樣的,一級指針存放的是普通變量的,而二級指針存放的是指針變量的地址。

  #include

  int main()

  {

  int data = 10;

  int *p = &data; //定義一級指針

  int **pp = &p; //定義二級指針

  printf("通過一級指針訪問:data=%d",*p);

  printf("通過二級指針訪問:data=%d",**pp);

  printf("p的地址是%p",p);

  printf("pp的地址是%p",pp);

  return 0;

  }

  用圖像理解上面的代碼就如下圖,多級指針是相對的概念,都是一級指向另一級層層遞進(jìn)的。

  10.內(nèi)存泄漏

  什么是內(nèi)存泄漏?

  內(nèi)存泄漏最主要的體現(xiàn)是,程序剛跑起來的時(shí)候很好,跑了幾小時(shí),跑了幾天或者幾周,程序崩潰了。

  這種情況一般來說就是不斷地開辟內(nèi)存空間,最后超過了你計(jì)算機(jī)的內(nèi)存,然后就崩潰了。用malloc開辟的空間,程序不會(huì)主動(dòng)釋放。Linux系統(tǒng)中,程序結(jié)束,系統(tǒng)會(huì)回收這個(gè)空間。

  如何避免內(nèi)存泄漏?

  1.注意循環(huán)中有沒有一直申請空間。

  2.有沒有及時(shí)合理釋放。(用free釋放)

  11.為什么要用指針

 。1)可以將變量強(qiáng)制保存在我想要的地址中。

  平時(shí)我們定義一個(gè)變量int a = 10;這個(gè)a的地址是系統(tǒng)隨機(jī)分配的,那么如果我們想在指定的地址去定義這個(gè)變量該如何操作,這個(gè)時(shí)候就可以用到指針。

  例:在內(nèi)存空間0077ff00中定義int a = 10。

  int *p = (int *)0077ff00;

  *p = 10;

  通過(int *)的操作強(qiáng)制給*p這個(gè)指針變量附上一個(gè)int型的地址,然后再通過*p=10給變量附上值,這個(gè)操作就做完了。

 。2)通過被調(diào)函數(shù)修改調(diào)用函數(shù)的對象。

  還記得上面我們寫過一個(gè)交換數(shù)值大小的demo嗎?

  如果我把紅框中的函數(shù)改成以下這個(gè)樣子,想一想還能否完成數(shù)值交換的操作。很顯然是不行的,因?yàn)樾薷暮蟮暮瘮?shù)在定義參數(shù)時(shí)開辟的內(nèi)存空間與主函數(shù)在調(diào)用時(shí)所應(yīng)定義的變量開辟的內(nèi)存空間是完全兩個(gè)不一樣的空間。說白了,如果把整個(gè)程序比作是一個(gè)大樓的話,被調(diào)函數(shù)為變量開辟的空間在301房間,而在主函數(shù)定義的變量開辟的空間在403房間,301房間的人根本控制不了在403房間的人,因此傳參這種方式無效。

  什么是有效的傳參?通過指針,對變量地址進(jìn)行操作,讓指定地址中的變量值進(jìn)行交換。

【C語言中各種類型的指針的概念總結(jié)】相關(guān)文章:

C語言中各種類型的指針的概念02-14

C語言中指針的概念03-16

C語言中各種類型指針的特性與用法介紹04-17

C語言指針的概念02-25

C語言中的指針解讀04-08

什么是C語言中指針 C語言指針的基礎(chǔ)使用04-19

C語言指針數(shù)組的概念07-19

C語言中的指針指什么03-30

C語言中的指針是什么08-08