嵌入式linux學習筆記:05_C語言_數組及指針

1、字符數組?

1、什麼是字符數組?
一個數組中全部成員都是字符來的。

例子:char A[5];

2、字符數組賦值?
1)定義同時初始化?
char A[10] = {'h','e','l','l','o'}; -> 剩餘沒有賦值的5個元素都爲0

char A[10] = {"hello"}; -> 將字符串hello賦值給數組

char A[10] = {"10086"}; -> char A[10]已經決定每一個成員都是字符類型,所以 ‘1’,‘0’,‘0’,‘8’,‘6’

int A[10] = {1,0,0,8,6}; -> int A[10]已經決定每一個成員都是整型類型,所以 1,0,0,8,6

char A[10] = "hello"; -> {}可以省略!

3、將字符串常量賦值給數組在內存中是如何變化?
int a = 10;

char A[10] = "hello";

其實將常量區中的值賦值給棧區空間。

1)注意:
所有字符串常量在常量區存在都會以'\0'作爲結束的標誌。

Oct    Dec      Hex     Char

000     0       00      NULL  '\0'

2)例如:
hello\0world\0apple\0tree\0

2 、字符指針?

整型指針 -> int類型

字符指針 -> char類型

例子1:
char a = 'h';

char *p = &a; ->p就是字符指針 -> 指向一個字符類型的數據a

例子2:
char *p = "hello"; -> 正確!

究竟p指向字符?還是指向一個字符串?

字符指針p永遠只能指向字符,不可能指向整個字符串,在這個例子,p指向"hello"這個字符串的首元素'h'的地址

注意:
1)p是一個指針變量,所以只能存放地址,存放着是hello中’h’的地址。

2)p是一個指針變量,不能存放字符串,不是將常量區的hello拷貝過來。

3)字符指針只能指向字符,不能指向字符串。

4)%s輸出字符串

輸出原則:給定一個地址,判斷地址上值是不是'\0'
如果不是\0,則打印該地址上的值並將該地址往後挪動一個單位。
如果是\0,就停止打印。

請問以下代碼是什麼含義?

char A[10] = "hello";

char *p = "hello";

printf("A = %s\n",A);  //A是字符串首元素的地址,結果:hello   -> 打印的是棧區的hello

printf("p = %s\n",p);  //p是字符串首元素的地址,結果:hello   -> 打印的是常量區的hello

結論:
1)只要將一個字符串賦值給一個字符數組,那麼就會把常量區的字符串拷貝到該字符數組中。

2)只要將一個字符串賦值給一個字符指針,那麼該指針就是存放着這個字符串的首元素的地址。
在這裏插入圖片描述

#include <stdio.h>
int main(int argc,char *argv[])
{
       char A[] = "helloworld";
       char *p = "helloworld";
       char *pa = A; //pa等價於數組名A,使用pa來訪問東西,都是屬於棧區!
       printf("sizeof(A) = %d\n",sizeof(A));//11
       printf("sizeof(p) = %d\n",sizeof(p));//4
       printf("A = %s\n",A); //helloworld
       printf("*A = %c\n",*A); //h  棧區
       printf("*(A+1) = %c\n",*(A+1)); //e  棧區
       printf("A+1 = %s\n",A+1); //elloworld  棧區
       printf("p = %s\n",p); //helloworld  常量區
       printf("pa = %s\n",pa); //helloworld  棧區
       printf("A[0] = %c\n",A[0]); //h 棧區
       A[0] = 'k';
       printf("A = %s\n",A); //kelloworld  棧區  
       printf("*p = %c\n",*p); //h  常量區
       //*p = 'k';  //26行段錯誤,原因常量區不能修改值。
       //printf("p = %s\n",p);
       printf("*pa = %c\n",*pa); //k  棧區
       pa[0] = 'm';
       printf("pa = %s\n",pa); //melloworld
       return 0;
}

14、有以下程序

main()
{   
       char s[]=“Yes\n/No”,*ps=s;
        puts(ps+4);
        *(ps+4)=0;
        puts(s);
}

程序運行後的輸出結果是( B )

A) n/No      B) /No     C) n/No     D) /No

   Yes          Yes        Yes         /No

   /No                     /No         Yes

在這裏插入圖片描述
16、有以下程序

main()                               
{  
       char s[]= “ABCD”,*p;             
        for(p=s+1;p<s+4;p++) 
              printf(%s\n”,p);
}  

程序運行後的輸出結果是()

BCD

CD

D

17、以下程序運行後的輸出結果是( gae )

main()
{  
       char a[]=“Language”,b[]=“Programe”;
        char *p1,*p2; 
       int k;
        p1=a;p2=b;
        for(k=0;k<8;k++)
           if(*(p1+k)==*(p2+k))   等價於 if(p1[k] == p2[k])
               printf(%c”,*(p1+k));
}

3、指針數組

1、什麼是數組指針?什麼是指針數組?
數組指針是一個指針來的,這個指針指向整一個數組。

指針數組是一個數組來的,這個數組的每一個成員都是指針。

2、如何定義指針數組?
定義的方法與定義普通數組一致。

1)給一個數組名 p

2)確定元素的個數,使用[]括號括住它 p[5]

3)確定每一個元素的類型 int *pa

4)將第3步的變量名去掉 int*

5)將第4步的結果寫在第2步結果的前面 int* p[5] -> 指針數組

3、如何定義數組指針?
int A[5];

int (*p)[5]; = &A; --> 數組指針

練習: 提示: strlen()計算字符串實際長度
15、有以下程序

main()
{  
      char str[][20]={“Hello”,”Beijing”},*p=str[0];
         printf(%d\n”,strlen(p+20));
}  

程序運行後的輸出結果是( C )

A)   0     B)  5     C)  7    D)  20

在這裏插入圖片描述
18、有以下程序

main()
{  
       char *p[10]={“abc”, “aabdfg”, “dcdbe”, “abbd”, “cd”};
        printf(%d\n”,strlen(p[4]));
}  

執行後輸出結果是( A )

A) 2      B) 3      C) 4      D) 5

在這裏插入圖片描述
19、若有定義:int *p[3];,則以下敘述中正確的是( B )

A)定義了一個基類型爲int的指針變量p,該變量具有3個指針。

B)定義了一個指針數組p,該數組含有3個元素,每個元素都是基類型爲int的指針。

C)定義了一個名爲*p的整型數組,該數組含有3個int類型元素。

D)定義了一個可指向一維數組的指針變量p,所指一維數組應具有3個int類型元素。

若有以下程序:

void main()
{
       char *a[3] = {"I","love","China"};
       char **ptr = a;
       printf("%c %s",*(*(a+1)+1),*(ptr+1));  // 'o'   "love"
}

4、const指針?

1、什麼是const指針?
已經學習了非常多指針種類,例如:整型指針int*、字符指針char* -> 指的是指針的類型

const指針並不是指針的類型,只是用於修飾特定的指針類型。

2、使用場景?
一般const作用形式參數。

例子:

int fun(int a); //a=10 ->   可以隨時通過a修改a本身的值。
int fun(const int a); //a=10  一旦a被初始化後,不能通過a修改a的值。
int main()
{
       fun(10);
}

結論: const修改了某個變量之後,就不能通過該變量修改該變量裏面的值。
3、 例子:

#include <stdio.h>
int main()
{

       /* const作用於整型變量

       const int a;//使用const修飾變量a,一旦變量初始化隨機值之後,就不能通過a修改a的值

       a = 100; //編譯出錯: error: assignment of read-only variable ‘a’

       printf("a = %d\n",a);

       //a = 200; //編譯出錯: error: assignment of read-only variable ‘a’

       //printf("a = %d\n",a);

       */

       /* const作用於指針變量本身

       int a = 100;

       int b = 50;

       int * const p = &a; //const修飾p的本身,所以一旦p被初始化之後,就不能通過p修改p的本身

       //p = &b; //編譯出錯:error: assignment of read-only variable ‘p’

       *p = 200;  //正確的,因爲const修飾p的本身,但是沒有修飾p指向的內容,所以可以通過p修改p指向的內容

       printf("a = %d\n",a);

       */

       /* const修飾指針變量指向的內容

       int a = 100;

       int b = 50;

       const int *p = &a; //const修飾p指向的內容,而不是修飾p

       p = &b;  //可以通過p修改p本身。

       //*p = 200; //編譯出錯:error: assignment of read-only location ‘*p’

                       //不可以通過p修改p指向的內容。    

       b = 200; //可以,沒有通過p修改p指向的內容

       */   

       return 0;

}

4、結論
int * const p; -> const修飾p的本身,一旦p被賦值了某個一個地址之後,就不能通過p修改p的地址。

int * const p = xxxx地址(正確) p = yyyy地址(錯誤)

  -> 但是可以通過p修改p指向的內容。

  *p 隨便搞

const int *p; 等價 int const *p;

    -> const修飾p指向的內容,p隨意指向任何的地址

    const int *p  = xxxx地址(正確)   p = yyyy地址(正確)

    *p 出現錯誤
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章