天天看點

傳說中的大山-指針

總有人說c語言的三座大山及,指針,函數,數組,在學習當中給我們帶來了很大的困擾,對抽象問題無法了解,好,很高興我翻越了其中一座山,接下來我會分享這三個問題的學習方法,每個章節後面都會附有練習題,需要着重強調的是,題一定要自己想辦法敲一下,對概念的了解和發現問題有很大的幫助,好了,祝大家盡快渡過難關!!!

  1. 指針的定義:

    格式: <存儲類型> <資料類型> * 變量名稱;

    eg: char * pc;

    ==》資料類型用于辨別目标存儲空間大小

    ==》* 表示該類型是一個指針

    ==》變量名稱則用于存儲位址的值。

2 “&”用以擷取一個變量的位址,“ * ”取出一個位址内的值

px+n指針向下偏移一個單元,不改變指針的值,

px++改變指針的值

注意:數組名稱是常量,不能指派(++用的時候會報錯)

if(pa = NULL) :pa變量指派,且值為假,不執行

if(pa == NULL):邏輯判斷,看pa内部是不是為空

3.指針初始化

char * pc = NULL;

作用 避免野指針,沒有任何初始化的指針。

指針的變量位址初始化: char *pc = &c;

用其他指針初始化: char *pc = &c;

用絕對位址初始化:char *pc = 0x23423423; 注意:該位址必須是可以通路的位址。一般不建議采用

5.數組與指針

  • 相同點啊a[i] = pa[i]

    (pa + i) =(a+i)

    a[i] = pa[i] = *(pa+i) = *(a+i);

數組名稱是一個指針常量,不允許改變。

pa指針是指針變量,可以随時修改。

char buff[] ="aasdfadsf"; ===>buff是本地記憶體
137 char *pa = &buff[0];  ==>pa 指向本地記憶體,可以修改。
138 char *pb = "asdfadf"; ==>pb 指向靜态常量區資料,不允許修改。

char buf[5] = {"a,b,c,d,e,f};	
char *p = "a,b,c,d,e,f"
差別:	記住所有帶雙引号的字元串都存儲在靜态常量區,前者可操作,後者不可操作,因為前者是把字元常量區的字元串拿到了棧區,變成了可操作數,而後者是直接定義了一個指針,指向了文本區,所有靜态常量區的都是隻讀的!!!
           
面試題:
141 int main()
142 {
143     int a[5]= {1,2,3,4,5};:
144     int *p = (int *)(&a+1);
145     printf("%d %d \n",*(a+1),*(p-1));
146 }
列印結果 2,5
           

*(a+1) :首位址向下偏移一個int類型機關,到了a[1]的位置

(&a+1) :&a為取數組名的位址,即為整個數組的位址,它的類型為數組類型,指針偏移到數組後面的元素上-1剛好到數組最後一個元素即5

練習題:

1、輸入一行文字,找出其中大寫字母,小寫字母,空格,數字以其他的字元各有多少

int main(int argc, char *argv[])
{
    char buf[N] = {0};
    char * pf = &buf[0];
    int da = 0,xiao = 0,kong = 0,num = 0,other = 0; 

    printf("請輸入字元串以檢測\n");
    gets(pf);
    printf("%s\n",pf);
    while(*pf != '\0')
    {
        if(*pf >= 'A' && *pf <= 'Z')
            da++;
        else if((*pf >= 'a') && (*pf <= 'z'))
            xiao++;
        else if(*pf == ' ')
            kong++;
        else if((*pf >= '0') && (*pf <= '9'))
            num++;
        else                                                                                                         
            other++;
        pf++;
        
    }printf("大寫字母;%d\n小寫字母:%d\n空格:%d\n數字%d\n其他%d\n",da,xiao,kong,num,other);
    return 0;
}



           

2、輸入一個字元串,用指針求出字元串的長度。

int main(int argc, char *argv[])
{
    char buf[N] = {0};
    char * pf = &buf[0];
    int count = 0;
    printf("請輸入字元串以檢測\n");
    scanf("%s",pf);
    while(*pf++ != '\0');
    printf("%ld\n",(long int)pf-(long int)&buf[0]-1);                                                                
    return 0;
}

           

3、 main()

  {

   int a[5]={1,2,3,4,5};

   int ptr=(int )(&a+1);

   printf("%d,%d",(a+1),(ptr-1));

  }

輸出結果是什麼?

2,5,上面概念處講過了
           

4、請問以下代碼有什麼問題:

int main()

  {

   char a;

   char *str=&a;

   strcpy(str,“hello”);

   printf(str);

   return 0;

  }

main函數内部第一行和第三行沖突,定義的是一個字元變量,而非一個字元串常量
           

5、 char* s=“AAA”;

  printf("%s",s);

  s[0]=‘B’;

  printf("%s",s);

有什麼錯?

第一行的意思為把字元串常量存放在靜态常量區,不可修改
           

6、編寫一個程式實作功能:将兩個字元串合并為一個字元串并且輸出,用指針實作。

char str1[20]={“Hello ”}, str2[20]={“World ”};

int main(int argc,char *argv[])
{
    char str1[20] = {"Hello"};                                                                                       
    char str2[20] = {"World"};
    char *p1  = str1;
    char *p2  = str2;
    while(*p1 != '\0'){
        p1++;
    }
    //p1--;
    while(*p2 != '\0'){
        *(p1++) = *(p2++);
    }
    *p1 = '\0';
    p1 = str1;
    p2 = str2;
    printf("str1 = %s\nstr2 = %s\n",p1,p2);     //在main函數的時候,不可以拿p1,p2直接列印值,重新定義一個函數就可以?
???
    return 0;
}
           

7、編寫一個程式實作功能:将字元串”Computer Secience”賦給一個字元數組,然後從第一個字母開始間隔的輸>出該串,用指針完成。

int main(int argc,char *argv[])
{
    char src[128] = {"Computer Secience"};
    char dest[128] = {0};
    char *ps = src;
    char *pd = dest;
    while(*ps != '\0'){
        *pd++ = *ps++;
        *pd++ = ' ';        
    }
    printf("dest = %s\n",dest);
    return 0;   
}

           

8、使用C語言實作字元串中子字元串的替換

描述:編寫一個字元串替換函數,如函數名為 StrReplace(char* strSrc, char* strFind, char* strReplace)>,strSrc為原字元串,strFind是待替換的字元串,strReplace為替換字元串。

舉個直覺的例子吧,如:“ABCDEFGHIJKLMNOPQRSTUVWXYZ”這個字元串,把其中的“RST”替換為“ggg”這個字元串,>結果就變成了:

ABCDEFGHIJKLMNOPQgggUVWXYZ

void StrReplace(char * strSrc,char *strFind,char *strReplace)
{
    char *ps = strSrc;
    char *pf = strFind;
    char *pr = strReplace;

    char cat[128] = {0};                                                                                                                                                               
    char *pc = cat;
    char *p1 = NULL;char *p2 = NULL;char *p3 = NULL;
    while(*ps++ != '\0')
    {
        if( (*(ps) == *(pf)) && 
                (*(ps+1) == *(pf+1))  &&
                ( *(ps+2) == *(pf+2) ))
        {

#if 0
                p1 = ps;
                while(*p1 != '\0')
                {
                    *pc++ = *p1++;  
                }
#endif      //這段沒作用
#if 0
            *ps = *pr;
            *(ps+1) = *(pr+1);
            *(ps+2) = *(pr+2);
            printf("find it\n");
#endif
            while(*pr != '\0')
            {
                *ps++ = *pr++;
            }
        }
    }
    strcat(cat,strSrc);
}
int main(int argc,char *argv[])
{
    char src[128] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
    char dest[128] = {"RST"};
    char place[128] = {"ggg"};
    printf("替換前:%s\n",src);
    StrReplace(src,dest,place);
    printf("替換後:%s\n",src);
    return 0;
}   
           

繼續閱讀