c語言指標初級,指標初級
1:
/*
變數能夠使用,就要在電腦中儲存起來;
*/
int main(int argc, const char * argv[]){ int a=10;//棧上的四個位元組; //&取地址符,&a表示a的地址 printf("a的地址是:%p\n",&a);//列印a的地址 a的地址是:0x7fff5fbff81c //*間接定址符 printf("a的地址上的值是:%d\n",*(&a));//列印a的值 a的地址上的值是:10 return 0;}<span style="color:#e32400;"></span>
2:
/*
指標:儲存變數的地址的一種變數;
指標定義: int *p;// *是指標標識,說明p是指標名,int表示指向的資料類型,或者說p儲存的是一個int型變數的地址;
*/
int main(){ int *p;//*只是指標標識 int a=10; int b=20; p = &a;//p可以儲存一個int型資料的地址;a是一個int,所以p就可以儲存a的地址;如果p儲存a的地址,就說明p指向a; printf("p=%p,&a=%p\n",p,&a); printf("*p = %d\n",*p);//p指向的內容; *p = 100;//通過地址,修改了地址上的內容;*間接定址符,取出p地址裡的內容; printf("a=%d\n",a); p = &b;//p的值變了;p指向的資料變了;p指向了另一個資料; *p = 200;//修改了指向的內容,b被修改; printf("a=%d,b=%d\n",a,b); return 0;}
int main(){ int a=10; int *p = &a;//int *p;*是指標標識,int * 只是說明了p得類型;等價於 int *p ;p=&a; printf("%d\n",*p); int *q;//定義了一個指標變數,如果沒有指向就是任意的,*q操作可能會異常;指標也要先賦值,後使用(告訴指標指向哪個變數)// *q = 100; printf("*q=%d\n",*q); return 0;}
int main(){ int *p;// char *q;//其他的指標類型// long *w; printf("sizeof(p)=%lu\n",sizeof(p));//sizeof(p)=8 printf("sizeof(int *)=%lu\n",sizeof(int *));//sizeof(int *)=8 printf("sizeof(char *)=%lu\n",sizeof(char *));//sizeof(char *)=8 printf("sizeof(long *)=%lu\n",sizeof(long *));//sizeof(long *)=8 printf("sizeof(double *)=%lu\n",sizeof(double *));//sizeof(double *)=8 //各種指標類型在記憶體中佔有的記憶體都是一樣的,在64位系統下都是8位元組; return 0;}
3:
/*
指標的運算 ++, --, +, -
地址的運算;
*/
int main(){ int a[] = {1,2,3,4,5};//a是數組名,裡面儲存的是數組首個元素的地址,也就是a=&a[0]; int *p;//p可以儲存int型資料的地址;a裡面有5個int,p可以指向裡面任何一個元素; //p指向第一個元素a[0]? p = &a[0];//等價於p=a; printf("p = %p\n&a[0] = %p\na = %p",p,&a[0],a);//p = 0x7fff5fbff810 &a[0] = 0x7fff5fbff810 a = 0x7fff5fbff810 p++;//p向後位移了一個int的距離,就是4個位元組=p指向的資料類型的大小; printf("\np = %p\n *p=%d\n",p,*p);//p指向了a[1] p = 0x7fff5fbff814 *p=2 p = a; for (int i=0; i<5; i++)//1 2 3 4 5 { printf("%d ",*p); p++; } p = &a[4]; for (int i=0; i<5; i++)//5 4 3 2 1 { printf("%d ",*p--); } return 0;}
int main(){ int a[]={1,2,3,4,5}; int sum = 0; int *p = a; p++;//p指向a[1]; printf("%lu\n",p-a);//地址1-地址2:表示兩個地址之間可以放幾個指向的資料的類型,放幾個int; 1 printf("%d \n",*(p-1));//地址-一個數,是一個地址,就是指標往前位移 N*N個指向的資料類型; 1 p = a; //通過p+i來遍曆數組;p+i = &a[i] ,*(p+i) = a[i]; for(int i=0;i<5;i++)//1 2 3 4 5 { printf("%d ",*(p+i)); } p = &a[4]; for(int i=0;i<5;i++)//5 4 3 2 1 { printf("%d ",*(p-i)); } p = a; for(int i=0;i<5;i++) { sum += *(p+i); } printf("\nsum = %d\n",sum);//sum = 15 return 0;}
4:
/*
野指標
*/
int main(){ int *p;//只定義,沒有賦值,指向是任意的,就是野指標; printf("p=%p\n",p); *p = 100;//修改了不確定的東西;禁止使用,禁止這樣操作,低級錯誤; return 0;}
5:
/*
null 指標:如果p的值=NULL,p就是null 指標;
NULL是個非法地址; *p既不能讀,也不能寫;
指標使用前必須判空;
*/
int main(){ int *p = NULL; printf("p=%p",p);// printf("*p=%d\n",*p);//錯誤,程式出錯 if(p == NULL) { printf("p是個null 指標不能使用\n"); } else { printf("p合法\n"); }}
6:
/*
void * 指標,通配型指標,可以指向任意的資料類型,但是在使用時要注意強制轉換成指向的類型;
*/
int main(){ void *p; char ch = 'a'; int i=1234; double b=12.38; printf("sizeof(p)=%lu\n",sizeof(p));//sizeof(p)=8 p = &ch;//p指向char型的變數// printf("%c\n",*p);//編譯失敗,類型不符; printf("%c\n",*(char *)p);//(char *)是類型說明; a p = &i; printf("%d\n",*(int *)p);//1234 p = &b; printf("%lf\n",*(double *)p);//12.380000 return 0;}
void swap(int a,int b)//只是形參傳遞,函數結束即銷毀,達不到交換的目的{ int temp = a; a = b; b = temp;}void swap_true(int *a,int *b)//地址傳遞,操作的任然是地址記憶體儲的值,可以達到交換目的{ int temp = *a; *a = *b; *b = temp;}int main(){ int x=10,y=20; swap(x,y); printf("x=%d,y=%d\n",x,y);//x=10,y=20 swap_true(&x,&y); printf("x=%d,y=%d\n",x,y);//x=20,y=10 return 0;}
7:
/*
數組和指標
數組作為函數的入參傳遞的時候
形式參數和實際參數都可以是指標形式或者是數組形式;
*/
void setArray(int a[],int len)//形式參數是數組形式{// printf("sizeof(a)=%lu\n",sizeof(a));//結果為8 a就是個指標,8個位元組,只能傳遞數組的首地址,不能傳遞元素的個數 for(int i=0;i<len;i++) { a[i]=100; }}void printArray(int a[],int len)//形式參數是數組形式{ for(int i=0;i<len;i++) { printf("%d ",a[i]); }}void setArray1(int *a,int len)//形式參數是指標形式{ //a[0]=*a &a[0]=a a[i]=*(a+i) for(int i=0;i<len;i++) { *(a+i)=10; }}int main(){ int a[5] = {1,2,3,4,5};//a是數組名,儲存數組的首地址;數組的名字a可以看成是常量指標; int *p = a;//p只能指向一個int,指向一個元素,不能指向一個數組;這裡p指向的是數組首地址 setArray(a, 5);//實際參數是數組形式 printArray(p,5);//實際參數是指標形式 setArray1(p,5); printArray(p,5); printf("%d\n",*(a+2)); return 0;}
8:
/*
數組和指標的總結
1:數組作為函數的入參傳遞的時候
形式參數和實際參數都可以是指標形式或者是數組形式;
形參是數組的時候,其實本質是已經完全是指標變數;
setArray(int a[],int len)
這個裡面,a就是指標,不能根據它計算元數組元素的個數
這個裡面,a是個變數,可以被賦值,a++是允許的;
2:數組名可以看成是常量指標(指向首個元素的常量指標); 儲存數組的首個元素的地址;
int a[5];
此時a不能被賦值,a++就是錯誤的;
a[i] = *(a+i) = *(p+i)
*/
//用指標傳遞數組,進行排序void sortArray(int *p,int len)//排序{ for(int i=0;i<len-1;i++) { for(int j=0;j<len-i-1;j++) { if(*(p+j) > *(p+j+1)) { int temp = *(p+j); *(p+j) = *(p+j+1); *(p+j+1) = temp; } } }}void printArray(int *p,int len)//列印{ for(int i=0;i<len;i++) { printf("%d ",*(p+i)); }}int printMax(int *p,int len)//找最大值{ int max = *p;//定義最大值為數組第一個元素 for(int i=0;i<len;i++) { if(max < *(p+i)) { max = *(p+i); } } return max;}int main(){ int a[] = {43,54,32,1,43,67,543,6578,867,64,53,2}; int len = sizeof(a)/sizeof(a[0]); sortArray(a, len); printArray(a,len); printf("\nthe max is %d\n",printMax(a,len)); return 0;}
9:
/*
字元數組和指標
*/
/*
常量字串和字元數組的差別;
常量字串不能改;
字元數組可以改,字元數組必須要有自己的空間;
*/
int main(){ char str[100]="helloworld";//常量字串給變數字元數組賦值; char *p = "helloworld";//p指向常量字串,不能通過*p去修改常量字串;p指向常量字串裡的'h'// *p = 'H';//不可修改,p指向常量區,唯讀,不可寫; printf("%s\n",p); str[0] = 'H';//str的元素都是char型變數;如果要修改字元,就需要定義成數組形式; printf("%s\n",str); return 0;}
<span style="color:#ff0000;">//通過指標來傳遞字元數組,不需要傳遞數組的長度;因為在做字串處理的時候,字串本身到'\0'結束</span>//把小寫字母改成大寫#include <string.h>void convert(char *s)//將小寫字母改成大寫字母{ printf("in convert s is %s\n",s); int len = (int)strlen(s); for(int i=0;i<len;i++) { if(*(s+i)>='a' && *(s+i)<='z')//如果是字母的話就轉換 { *(s+i) -= 'a'-'A'; } }}char * convert(char *s)//一般字元數組需要返回價值{ char *p = s; while(*p)//當*p不等於0的時候進入迴圈 { if(*p>='a' && *p<='z') { *p -= 'a'-'A'; } p++; } return s;}int main(){ char str[100]="helleworld"; convert(str); printf("in convert s is %s\n",str); return 0;}
10:
/*
"hello"-->"heLLo"替換的目標是給定的 l-->A
replace(char *s,char old,char new)
*/
char *replace(char *s,char old,char new){ char *p = s; while(*p) { if(*p == old) { *p = new; } p++; } return s;}//計算字串的長度,實現strlen的功能;int myStrlen(char *s){ char *p = s; int count=0; while(*p) { count++; p++; } return count;}int main(){ char str[100] = "helloworld"; replace(str,'l','Y'); printf("%s \n",str); int len = myStrlen(str); printf("%d \n",len); return 0;}
//字串裡面插入一個字元
//pos表示插入的位置,ch表示插入的字元;
char *insert(char *s,int pos,char ch){ int len = (int)strlen(s); char *p = s; int count=1; while(*p)//當*p不等於0的時候進入迴圈 { if(pos == len+1)//如果需要插入的元素的位置是字元數組的最後一個位置,也就是'\0'處的時候直接將原'\0'處賦值為目標字元,然後退出迴圈 { *(s+len) = ch; break; } if(pos == count)//如果插入的位置為數組中間任意位置的時候進入判斷 { for (int i=len-1; i>=pos-1; i--)//將數組插入位置(包括插入位置)之後到'\0'之前的所有元素往後移位 { *(s+i+1) = *(s+i);//也就是'\0'之前的第一個元素移位到'\0'位置,依次類推 } *(s+pos-1) = ch;//將原數組中移動的最後一個元素賦值為需要插入的字元; break; } count++; p++; } return s;}int main(){ char str[100]="helloworld"; insert(str,1,'M'); printf("%s \n",str); return 0;}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。