指針數組
#include<stdio.h>
int main()
{int a[3] = {0,1,2};//指針數組,它是數組,每個元素都是指針int *p[3];p[0] = &a[0];p[0] = a;p[1] = &a[1];p[1] = a+1;p[2] = &a[2];p[2] = a+2;//sizeof(p):3個元素,int*(32位)//3 * 4 = 12//sizoef(p[0]):第0給元素,int * = 4int n = sizeof(p)/sizeof(p[0]);int i =0;for(i = 0;i < n;i++){p[i] = &a[i]; //a+i}for(i = 0;i < n;i++){//printf("%d\n",*p[i])printf("%d\n", *(*(p+i)));//p[i]等價于*(p+i)}return 0;
}
指針和函數
通過函數交換兩個變量
#include<stdio.h>
void swap(int m, int n)
{int tmp;tmp = m;m = n;n = tmp;printf("m = %d,n = %d\n",m,n);
}
int main()
{ int a = 11;int b = 22;swap(a,b);//值傳遞printf("a = %d,b = %d\n",a,b);return 0;
}
地址傳遞
#include<stdio.h>
void swap(int *m, int *n)
{int tmp;tmp = *m;*m = *n;*n = tmp;
}
int main()
{int a = 11;int b = 22;//值傳遞,不管這個變量什么類型,只要是變量本身傳遞,就是值傳遞//swap(a,b);//值傳遞swap(&a,&b); //地址傳遞,變量的地址printf("a = %d,b = %d\n",a,b);return 0;
}
?形參中的數組01
#include<stdio.h>
int main()
{int a[] = {1,-2,3,-4,5,-6,7,-8,9};int i = 0;int n = sizeof(a)/sizeof(*a);printf("排序前\n");for(i = 0;i < n;i++){printf("%d ", a[i]);}printf("\n");//冒泡排序int j = 0;int tmp;for(i = 0;i < n-1;i++){for(j = 0;j < n-i-1;j++){ if(a[j] > a[j+1]) //升序{tmp = a[j];a[j] = a[j+1];a[j+1] = tmp;}}}printf("排序后\n");for(i = 0;i < n;i++){printf("%d ", a[i]);}printf("\n");
形參中的數組02
#include<stdio.h>
//1、形參中的數組,不是數組,它是普通指針變量
//2、形參數組:int a[100000],int a[],int *a對編譯器而已,沒有任何區別
//3、編譯器都是當做int*處理
//4、形參中的數組和非形參數組區別:形參中的數組是指針變量,非形參數組就是數組
//void print array(int a[100000])
//void print array(int a[])
void print_array(int a[], int n)
{int i = 0;//64位系統,sizeof(a),a是指針變量,結果為8//sizeof(a[0])第0個元素,是int類型,結果為4/*int n = sizeof(a)/sizeof(a[0]);printf("sizeof(a) = %d\n". sizeof(a));printf("sizeof(a[0] = %d\n),sizeof(a[0])");*/for(i = 0;i < n;i++){printf("%d, ",a[i]); //等價于*(a + i)}printf("\n");//a = NULL; //形參中的數組,不是數組,它是普通指針變量
}
int main()
{int a[] = {1,-2,3,-4,5,-6,7,-8,9};//print_array(a); //傳遞的是,數組的首元素地址,&a[0]//a = NULL;int n = sizeof(a)/sizeof(*a);print_array(a,n); //應該把數組元素個數傳遞過去return 0;
}
?返回局部變量的地址
#include<stdio.h>
int *fun()
{int a; //Linux64位,不允許返回局部變量的地址return &a;
}
int main()
{int *p = NULL;p = fun(); //接受函數返回的地址 //到上一步使用完fun(),fun()內的a,自動釋放,下面操作野指針*p = 100; //操作指針所指向的內存return 0;
}
返回全局變量的地址
#include <stdio.h>int a; // 明確注釋全局變量的用途int *fun() {return &a; // 函數名更明確
}int main() {int *p = fun();*p = 100;printf("*p = %d, a = %d\n", *p, a); // 合并輸出*(fun()) = 111;printf("a = %d\n", a);return 0;
}
指針和字符串
字符串打印說明
#include<stdio.h>
int main()
{char str[] = "hello mike";//1、%s,從首元素開始打印,直到結束符位置//2、%s,操作的是指針所指向的內容//printf("str = %s\n", str);//2、str是首元素地址,如果想打印str本身的值,%p,&x,&d,%oprintf("str = %p\n",str); //一個個打印出來,地址//3、str代表第0個元素,它是char//printf("str3 = %s\n", *str);printf("str3 = %c\n", *str);int i = 0;while(str[i] != '\0') //while(*(str+i) != '\0')){printf("%c",str[i]);i++;}printf("\n");return 0;
}
字符指針
#include<stdio.h>
int main()
{char str[] = "hello";str[0] = '1';*(str + 1) = '2';//printf("str = %s\n", str); //12lloprintf("str = %s\n",&str[0] +1); //2lloprintf("str = %s\n",str+1); //2llo//定義一個指針,指向首元素char *p = NULL;p = &str[0];p = str; //數組名就是首元素地址*p = 'a';p++; //p = p +1 *p = 'b';printf("str = %s\n", str); //ablloprintf("str = %s\n", p); // &str[0]+1 //blloprintf("str = %s\n",p-1);return 0;
}
字符串拷貝問題
#include<stdio.h>
#include<string.h>
int main()
{char buf[100];char *p = buf;//1、p指向buf的首元素//2、strcpy()是給p所指向的內存拷貝內容,字符串拷貝了bufstrcpy(p,"hello mike abc");printf("p = %s, buf = %s\n",p,buf);return 0;
}
int main01()
{char *p;//1、不是給p變量拷貝內容//給p所指向的內存拷貝內容//3、P是野指針,給野指針所指向的內存拷貝內容,結果導致段錯誤strcpy(p, "hello mike abc");return 0;
}
?字符串拷貝函數
#include<stdio.h>
//void my_strcpy(char dst[].char src[])
void my_strcpy(char *dst, char *src)
{int i = 0;while(*(src+i)!='\0'){*(dst+i) = *(src+i);i++}//結束符*(dst + i) = 0;
int main()
{ char src[] = "hello mike";char dst[100];char *p = buf;my_strcpy(p,src); //自定義拷貝函數printf("dst = %s\n",dst);return 0;
}
const修飾的字符指針?
#include<stdio.h>
int main()
{char buf[] = "hello";char *p1 = buf;*p1 = 'a'; //改變指針所指向的內存p1 = NULL;//改變指針變量本身//const修飾*,指針所指向的內存不能修改const char *p2 = buf;//*p2 = 'a'; //errp2 = NULL; //okreturn 0;
}
?字符串常量
#include<stdio.h>
void fun()
{printf("fun s2 = %p\n","hello mike");
}
int main()
{//1、每個字符串都是一個地址,這個地址是指字符串首元素地址//2、字符串常量放在data區,文字常量區printf("s1 = %s\n","hello mike");printf("s2 = %s\n","hello mike");printf("s3 = %s\n","hello mike"+1);//fun();return 0;
}
?文字常量區不允許修改01

#include<stdio.h>
#include<string.h>
int main()
{//1、字符串常量就是字符串的首元素地址printf("s1 = %p\n","hello mike");char *p1 = "hello mike";printf("p1 = %p\n",p1);char *p2 = "hello mike";printf("p2 = %p\n",p2);//2、字符串常量,文字常量區的字符串,只讀,不能修改printf("*p1 = %c\n",*p1); //讀,ok//3、p1指向字符串常量,字符串常量為只讀,不能修改//*p1 = 'a'; //修改 //errchar *p3 = "hello";//4、p3指向文字常量區,不能改strcpy(p3,"abc"); //errreturn 0;
}
??文字常量區不允許修改02
#include<stdio.h>
void fun(char *tmp)
{*tmp = 'a'; //err
}
int main()
{char *p = NULL; //p是變量"hello mike" //字符串常量,首元素地址p = "hello mike"; //p指向字符串//*p = 'a'; //err,指向文字區常量,文字常量區內容只讀p = NULL; //okp = "hello" //okchar *p2 = "abc";fun(p2); //p2的值,是“abc”首元素地址return 0;
}

字符串常量初始化問題
#include<stdio.h>
int main()
{ //1、p指針保存了“hello”的地址//2、指針所指向的內存不能修改char *p = "hello";//1、把"hello"一個一個字符放在buf數組中//2、數組的元素可以修改char buf[] = "hello";return 0;
}
main形參使用說明?
#include<stdio.h>//argv[]:它是數組,數組每個元素都是char*,每個元素都是字符地址
//argc:argv[]元素個數
//main()函數參數,需要用戶傳遞
int main(int argc,char *argv[])
{int i =0;for(i = 0;i < argc;i++){printf("test = %s\n",argv[i]);}return 0;
}

?字符指針數組
#include<stdio.h>
//void fun(int a[])
//void fun(int a[100])
void fun()
{
}//void print_array(char * p[100],int n)
void print_array(char *p[], int n)
//void print_arrauy(char **p, int n)
{int i = 0;for(i = 0;i < n;i++){printf("%s\n",p[i]);}
}
int main()
{char *p1 = "hello";char *p2 = "abc";char *p3 = "mike";char *p[] = {"hello", "abc", "mike"};int n = sizeof(p)/sizeof(*p);int i = 0;for(i = 0;i < n;i++){printf("%s\n", p[i]);}return 0;
}
查找匹配字符串出現的次數
#include<stdio.h>
#include<string.h>
int main()
{char *p = "11abcd11122abcd333abcd3322abcd3333322qqq";int i = 0; //累加器char *tmp = NULL;while(1){//查找匹配字符串,如果找到,返回匹配字符串的地址,沒有找到返回空tmp = strstr(p, "abcd");if(tmp == NULL){break; //跳出循環}else //找到{i++; //累加//重新設置新的起點p = tmp + strlen("abcd");}}printf("出現abcd的次數為; %d\n", i);return 0;
}
兩頭堵類型
#include<stdio.h>
#include<string.h>
int main()
{char *p = " 123456789 ";char *start = p; //首元素地址char *end = p + strlen(p) - 1; //尾元素地址//從左往右while(*start == ' ' && *start != '\0'){start++;}while(*end == ' ' && end != p){end--;}int n = end-start+1; //5-1=4,但是實際上元素由5個所以+1printf("n = %d\n", n);char buf[100]="aaaaaaaaaaa";strncpy(buf,start,n);buf[n] = 0; //結束符printf("buf = %s\n",buf);return 0;
}
課堂筆記
void fun(int b[10][10]); //ok
void fun(int **p); //err,二維數組不是二級指針int *fun(); //返回值是指針類型,指針函數0 數字0,和'\0'等價
'\0'
'0''0'字符'0',不是結束符,ascii為48char a[] = {'a', 'b'};
printf("%s\n",a); //亂碼,沒有結束符char a[10] = {'a', 'b'}; //后面自動補0
printf("%s\n",a); //正常char a[] = {'a', 'b', 0};
char a[] = {'a', 'b','\0'};
printf("%s\n",a);//正常char a[] = {'a','b','0'};
printf("%s\n",a); //亂碼,沒有結束符char buf[] = "hello"; //以字符串初始化,自動隱藏結束符'\0'