日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

c语言基础3

發布時間:2023/12/15 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c语言基础3 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

指針

指針就是內存地址。通常我們說的指針是指:指針變量。

因此:指針變量存放指針,指針就是一個內存空間的地址!

int a

int *p

比較:a標示了內存的一個空間,該空間能夠存放一個整數。p是一個指針類型變量(通常稱為指針),它也標示了內存的一個空間,該空間存放的是一個內存地址(內存地址在32位下為4字節)。

理解指針:我們需要弄清指針的三方面內容

1、指針的類型

2、指針所指空間存儲數據的類型

3、指針的值及存儲指針的空間大小

以下通過例子說明這三方面:

1、int? *p;

2、char *p;

3、int **p;

4、int (*p)[3]

1、指針的類型:從語法的角度講,只要將定義中指針的名字去掉,剩下的部分就是這個指針的類型。

1、int? *p;??   int*

2、char *p;   char*

3、int **p;   int**

4、int (*p)[3]  int(*)[3]

理解:一個基本的數據類型加上*號,就構成了指針的類型,這個類型定義的變量大小是一定的,與*號前面的數據類型無關。*號前面的數據類型只是說明了指針所指向的內存里存儲數據的類型! 如:int* 就是個指針的類型,用該類型定義的變量p大小(32位的為4個字節),int說明該指針所指向的內存里存儲的是int類型的數據!

2、指針所指空間存儲數據的類型:語法上講:只需把指針定義中的指針變量名和名字左邊的指針聲明符*去掉,剩下的就是指針所指空間存儲數據的類型。

1、int? *p;??   int

2、char *p;   char

3、int **p;   int*

4、int (*p)[3]  int [3]

理解:指針所指空間的數據類型是我們所關心的,對于編譯器來說,根據該類型來確定讀寫從指針地址開始的多少個字節空間的數據。

3、指針的值以及存儲指針值的空間大小

指針的值是指針變量本身存儲的數值,由于指針就是一個內存地址,所以指針的值也就是一個內存地址。在32位系統中,內存地址均為32位長,所以存儲指針的空間為4個字節。可以用sizeof()來測試。

對比一般變量和指針變量的定義和含義:

int p;  p是整型變量,用于標識內存的一個空間內能存放一個整數

int *p;  p是指針類型變量,用于標識內存的一個內存空間內能存放一個地址,該地址處能存放一個整數

int p[5];  p是一個數組(一段連續的存儲空間),數組中有5個元素,每個元素為一個整數,p為這段連續存儲空間的首地址

int *p[5];  p是一個數組(一段連續的存儲空間),數組中有5個元素,每個元素為一個地址(類型為int *),每個地址處能存放一個整數,p為這段連續存儲空間的首      地址?????? (被成為指針數組,主體是數組,[ ]優先級高于*)

int (*p)[5];  p是一個指針類型的變量,p指向具有5個元素的數組(類型為int[5]),數組中的元素為整數。(被稱為數組指針,主體是指針!)

int **p;  p是指針類型的變量,用于標識內存的一個空間能存放一個地址(類型為int**),該地址處存放的存放的還是一個地址(類型為int *),這個地址處能存放一      個整數(類型為int)

int p(int);??? p是一個函數,函數有個整型參數,并且函數返回值為整型

int (*p)(int);  p是一個指針,一個指向函數的指針,函數有一個整型參數,并且函數返回值為整型。

1 #include<stdio.h>2 3 main()4 {5 int a=12,*p,**ptr;6 ptr=&p;7 p=&a;8 **ptr=34;9 printf("%d,%d,%d\n",a,*p,**ptr);10 }

輸出:34,34,34

?

?

指針和數組:????????????????????? (指針和數組是不同的,指針是內存單元的一個地址32位為4字節,數組其大小和元素類型和個數有關。

對指針和數組元素的訪問,可以采用下標法,也可以采用指針法。貌似指針和數組有什么關系,事實上,它兩沒有關系。指針就是指針,數組就是數組。

在內存中的數據,一種方法是用數組名加下標的方式讀寫,另一種方法是通過指針間接的讀寫。

?1.對數組元素的訪問:  int a[10]={0,1,2,3,4,5,6,7,8,9};

a為數組元素的首地址a[0],現在想讀取整數5; (1)指針法: *(a+5) (2)數組法:a[5], 編譯器把以下標形式的操作解析為以指針的形式的操作,a作為數組元素的首地址,再加上括號中5個元素的偏移量,a+5*sizeof(int)

2、對指針所指空間的訪問:  char *p=“abcde”;

p為一個指針變量,大小為4個字節(32位系統),p里面存儲了一塊內存的首地址,這塊內存在靜態區(還不明白),其空間大小為6個字節,這快內存空間沒有名字,通過匿名訪問。    讀取字符d? (1)指針法:*(p+3) (2)下標法 p[3]? ,譯法和上面相同

注意:指針加減偏移量時,不是代表指針移動多少個字節,而是代表移動多少個指針所指的元素。

?

?指針和數組的聲明和定義:

外部變量的引用問題:如果在文件1中定義了一個數組,在文件2中要引用這個數組,那么在這兩個文件中怎樣聲明和定義呢?

在同一個文件中,特別是數組名作為函數參數時,實參和形參可以用數組,也可以用指針,兩種任意組合沒有問題(還沒有試過)。但是在不同文件間引用數組時,作為外部變量的聲明形式必須和另一個文件中的定義形式相同,否則會出錯,切記!!!

例子:?? file1.c 中:

1 #include<stdio.h>2 3 extern void func(void);4 char *a={"ABCDE"};5 6 void main()7 {8 func();9 printf("%c,%c\n",a[1],a[2]);10 }

file2.c中:

1 #include<stdio.h>2 3 extern char *a;4 void func()5 {6 printf("%c\n",a[1]);7 }

gcc -c file1.c file2.c

gcc -o file file1.o file2.o

./file

輸出: B
  ???? B ,C

若將 file2.c中 extern char *a;改為 extern? char a[ ]; 則上面的輸出第一行的變成亂數! why??

因為:在file2.c中將a聲明為外部數組(注意這里聲明是不分配空間的,所以無須說明數組有多少個元素,具體是多大可以在其它文件中定義)

這時編譯器認為a是一個數組,其大小為4個字節(因為file1.c中定義了a為指針變量),因此a[1]就輸出a這個指針變量中指針的第二個字節內容!是不確定的。。。

若將file1.c中 char *a={"ABCDE"}; 該為 char a[ ]={"ABCDE"} ; file2.c 中不變,則運行出現段錯誤。。。 why??

file1.c中定義數組a,并為其分配6個字符的空間,但在file2.c中,編譯器并不知道a是個數組,認為a是個指針變量,而這時候a中存的值為數組{“ABCDE“},由于指針大小為4個字節,所以在file2.c 中a的值變為{”ABCD“},該值被作為指針(畫圖好理解),這時候輸出a[1](相當于*(p+1)),這個地址中的值不確定。。可能這個地址都越界,出現段錯誤!

?

指針的算術運算和關系運算:

指針的算術運算:因為指針是一個內存地址,所以,其加減一個整數的意義是:指針從當前地址移動多少個元素,元素是指針所指空間存儲的數據類型。

1 #include<stdio.h>2 3 main()4 {5 char s[]={"ABCDEFGH"};6 int *p; 7 p=(int *)s;8 p++;//p+sizeof(int)*1,p+4,指向E9 printf("%c\n",*p); 10 p=p+5;//p+sizeof(int)*5,p+20,越界了,這里p指向的是int類型的數據11 printf("%c\n",*p);12 }

輸出E和亂碼

1 #include<stdio.h>2 3 main()4 {5 char s[]={"ABCDEFG"};6 char *p,**ptr;7 p=s;8 ptr=&p;9 printf("%c\n",**ptr);10 ptr++;11 printf("%c\n",**ptr);12 }

輸出A和段錯誤!

在第10行,ptr++,ptr指向的類型是char *,是個指針,大小為4字節,所以ptr=ptr+sizeof(char *)*1=ptr+4,這時候ptr的值越界了。。(畫圖好理解)

另外:關系運算,兩個指針可以進行減法運算,一般是高地址減去低地址,兩個指針不能進行加法運算是非法的!關系運算符也都適用。

?

數組的首地址和數組元素的首地址:

注:它兩值是相同的,但是類型不同,數組首地址&a;;;數組元素首地址:a或a[0],等價。。。

例子:

1 #include<stdio.h>2 3 /*該程序說明 數組首地址 和 數組首元素的地址 的區別4 *數組首元素(a==a[0])和&a值是一樣的,但是類型不同5 *a/a[0]類型是:int * 6 *&a的類型是:int(*)[]7 *也就是說下面程序中p1和p2的值是一樣的8 */9 10 11 main()12 {13 int a[10]={1,2,3,4,5,6,7,8,9,10};14 int *p1;15 int (*p2)[10]; 16 p1=a;17 p2=&a;18 printf("%d\n",*p1);19 printf("%d\n",*(int *)p2); 20 printf("%d\n",*(p1+1)); 21 printf("%d\n",*(int *)(p2+1));22 }

?要是16行改為:p1=&a; 則編譯出現:

ptr1.c:16: warning: assignment from incompatible pointer type

?原程序輸出:

1 1 2 -1078863728

21行輸出亂碼,因為p2+1, p2 的類型為 int? [10](所指向數據的類型), 那sizeof(p2)=4*10 字節了,? p2+1 =p2+ 4*10*1

轉載于:https://www.cnblogs.com/byking/archive/2013/03/14/2960419.html

總結

以上是生活随笔為你收集整理的c语言基础3的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。