指針
未初始化和非法指針
// 聲明指針a
int *a;
/*a的地址賦值為12,但是a的地址指向哪里呢,聲明了指針變量但為初始化,所以沒(méi)有辦法預(yù)測(cè)
a的值存儲(chǔ)在聲明地方*/
*a = 12;
NULL指針
- NULL指針是一個(gè)特殊的指針變量,不指向任何變量,值為零值
- 如果訪問(wèn)NULL指針依據(jù)編譯器,可能會(huì)觸發(fā)段錯(cuò)誤,也可能會(huì)訪問(wèn)零值
指針的指針
#include <stdio.h>
int main(void)
{
int a = 12;
int *b = &a;
int **c = &b;
printf("a=%d\n",a);
printf("b=%p\n*b=%d\n",b,*b);
printf("c=%p\n",c);
printf("*c=%p\n",*c);
printf("**c=%d\n",**c);
}
上面代碼聲明了3個(gè)變量a,指向a的指針b,指向指針b的指針c,c也叫指針的指針.
| 表達(dá)式 | 相當(dāng)?shù)谋磉_(dá)式 |
|---|---|
| a | 12 |
| b | &a |
| *b | a,12 |
| c | &b |
| *c | b,&a |
| **c | a,12,*b |
指針表達(dá)式
char ch = 'a'
char *cp = &ch;
// 各類型表達(dá)式
// &ch = cp 變量ch的指針
// cp = &ch 變量ch的指針
// &cp 指針cp的指針
// *cp = ch = 'a' 使用間接訪問(wèn)操作符訪問(wèn)指針cp
// *cp + 1 = 'b' 使用間接訪問(wèn)操作符訪問(wèn)指針cp后加1
// *(cp+1) 指針cp加1后執(zhí)行間接訪問(wèn),如果指針cp加1后的地址不存在則是錯(cuò)誤的
// ++cp 前綴++先增加它的操作數(shù)的值在返回結(jié)果,這份拷貝的存儲(chǔ)位置并未清晰定義,因此不合法
// cp++ 后綴++先返回cp值的一份拷貝然后再增加cp的值,這樣,表達(dá)式的值就是cp原來(lái)的值的一份拷貝
// *++cp 間接操作符作用于增值后的指針的拷貝上
// ++*cp 首先執(zhí)行間接訪問(wèn)操作,然后cp所指向的位置的值加1
// (*cp)++ 使用后綴++操作符,必須加上括號(hào),它首先執(zhí)行間接訪問(wèn)操作
// ++*++cp 首先執(zhí)行++cp,借這個(gè)對(duì)這個(gè)拷貝值進(jìn)行間接訪問(wèn),使得訪問(wèn)ch后的內(nèi)存位置,然后對(duì)這個(gè)位置+1
// ++*cp++ 這里后綴++優(yōu)先級(jí)較高,先執(zhí)行
使用指針計(jì)算字符串長(zhǎng)度
#include <stdio.h>
int strlen_for(char *);
int strlen_while(char *);
int strlen_goto(char *);
int main()
{
char *str = "abcde";
int len;
len = strlen_for(str);
printf("for實(shí)現(xiàn):%d\n",len);
len = strlen_goto(str);
printf("goto實(shí)現(xiàn):%d\n",len);
len = strlen_while(str);
printf("while實(shí)現(xiàn):%d\n",len);
}
int strlen_for(char *string)
{
int len = 0;
for(;*string!='\0';string++)
len++;
return len;
}
int strlen_while(char *string)
{
int len = 0;
while(*string++!='\0')
len++;
return len;
}
int strlen_goto(char *string)
{
int len = 0;
LABEL:
if (*string!='\0') {
string++;
len++;
goto LABEL;
}
return len;
}
使用指針進(jìn)行字符串查找
#include <stdio.h>
int find_char_for(char **strings,int);
int find_char_while(char **strings,int c);
int find_char_goto(char *strings[3],int c);
int main(int argc,const char *argv[])
{
int result;
char *strings[4] = {"abc","def","ghi"};
result = find_char_for(strings,'a');
printf("for實(shí)現(xiàn):%d\n",result);
result = find_char_while(strings,'b');
printf("while實(shí)現(xiàn):%d\n",result);
result = find_char_goto(strings,'g');
printf("goto實(shí)現(xiàn):%d\n",result);
return 0;
}
int find_char_for(char **strings,int c)
{
// 外層循環(huán):每個(gè)字符串?dāng)?shù)組 數(shù)組不為空時(shí)
for ( ; *strings!=NULL; strings++){
if (*strings == NULL) return 0;
// 內(nèi)層循環(huán): 每個(gè)字符串?dāng)?shù)組的字符 字符不等于'\0'時(shí)
for (; **strings!='\0'; *strings++)
if (**strings == c)
return 1;
}
return 0;
}
int find_char_while(char *strings[3],int c)
{
while( *strings != NULL){
if (*strings == NULL) return 0;
while( **strings != '\0')
if (*(*strings)++ == c)
return 1;
strings++;
}
return 0;
}
int find_char_goto(char *strings[3],int c)
{
LABEL1:
if(*strings != NULL) {
LABEL2:
if(**strings!='\0') {
if(*(*strings)++ == c){
return 1;
}
goto LABEL2;
}
strings++;
goto LABEL1;
}
return 0;
}