C語言數(shù)組講解(二)

謹記

一個人的潛力有多大、能力有多強,是一個未知數(shù),因為我相信能力就是干出來的,以前讀過一本書《能力就是干出來的》,這本書就講述了化保力人生最艱難和輝煌的那段時間,一個農(nóng)村家境非常不好的他,經(jīng)理了怎樣的磨練才有明天的成功,今天推薦大家可以去品讀一下這本書,讀完這本書過后,你會覺得命運的改變就在那一瞬間,一切的一切都不在是借口,都將不在是理由。因為,能力就是干出來的,所以,積極的努力奮斗吧,你的能力有多大就在于你干多少實實在在有意義的事。

前言

上一篇文章已經(jīng)介紹了C語言數(shù)組中一維數(shù)組、二維數(shù)組的相關(guān)知識點,通過上篇文章讀者能夠收獲關(guān)于數(shù)組的概念、定義、初始化、排序等知識點,今天向讀者展示的也是C語言數(shù)組相關(guān)的知識點,那就是字符數(shù)組以及字符串的一些用法。

字符數(shù)組

1、字符數(shù)組的定義
有一定順序關(guān)系的若干個字符型變量的集合,就是字符數(shù)組。可以是一維的,也可以是多維的。字符數(shù)組具有普通數(shù)組的性質(zhì),又有一些特殊的性質(zhì)。
字符數(shù)組的定義形式如下:
char c[7];
char ch[4][3];
字符數(shù)組初始化方式
1、和普通的數(shù)組相同,逐個為數(shù)組元素賦值
char ch[4] = {‘a(chǎn)’, ‘b’, ‘c’, ‘\0’};
2、使用字符串常量來賦值
char ch[10] = {"abcdefghjk"};
這里需要注意下:用字符串來初始化字符數(shù)組,字符串結(jié)尾是以“\0”結(jié)尾,上面看起來只有10個字母,但字符串隱含了結(jié)束標志\0,相當于11個字母,越界了。(字符串后面講解)

遍歷字符數(shù)組
#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[]) {
char ch[10] = {"abcdefghjk"};
    printf("%lu\n",sizeof(ch));
    for (int i = 0 ; i <sizeof(ch) / sizeof(char); i++) {
        printf("%c\n",ch[i]);
    }
    return 0;
}
結(jié)果:
        10
        a
        b
        c
        d
        e
        f
        g
        h
        j
        k
        Program ended with exit code: 0

3、不完全初始化
char ch[5] = {"qw"};

#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[]) {
char ch[5] = {"abc"};
    printf("%lu\n",sizeof(ch));
    for (int i = 0 ; i <sizeof(ch) / sizeof(char); i++) {
        if (ch[i] != NULL) {
             printf("%c\n",ch[i]);
        } 
    }
    return 0;
}
運行結(jié)果:
5
a
b
c
Program ended with exit code: 0
這里雖然字符數(shù)組初始化的時候只有3個元素,在進行數(shù)組遍歷的時候,可以看到,ch[3]和ch[4]是為空的,但是在內(nèi)存空間分配的時候,還是有內(nèi)存空間的,只不過里面沒存東西而已,所以對數(shù)組求sizeof的時候是5。

字符串
在C語言中,嚴格上講師沒有字符串這個數(shù)據(jù)類型的,不管是原生的還是構(gòu)造的數(shù)據(jù)類型,但是為何在程序員心中是有字符串這個類型的,首先,我們知道C語言是一個面向過程的一門語言,而基于C語言更高級的語言比如Ojective-C是面向?qū)ο蟮恼Z言,而在高級語言中有字符串這一類型,所以,在C語言中,程序員可以通過字符數(shù)組模擬字符串。字符串指的是以‘\0’作為結(jié)束字符的一組字符,因此當把一個字符串存入一個數(shù)組時,也把結(jié)束符'\0'存入數(shù)組,并以此作為該字符串是否結(jié)束的標志。如何定義字符串變量, 由于字符串是同一種類型的數(shù)據(jù)組成, 并且是有序的而數(shù)組就是用于存儲很多同一種類型的有序數(shù)據(jù), 所以可以使用數(shù)組來保存字符串

 // 注意: 字符串變量和普通的字符數(shù)組有一定的區(qū)別
 // C語言規(guī)定, 字符串必須以\0結(jié)尾(作為字符串的結(jié)束符號), 所以字符串變量的元素個數(shù)比字符數(shù)組的元素個數(shù)多一個 \0
 char str[] = "lnj"; // 字符串變量 l n j \0
 printf("str size = %lu\n", sizeof(str));
 
 char charValues[] = {'l', 'n', 'j'}; // 字符數(shù)組 , 這個并不是字符串, 而是字符數(shù)組
 printf("charValues size = %lu\n", sizeof(charValues));
 
 int num = 10;
 float floatValue = 10.1f;
 double doubleValue = 9.9;
 char  charValue = 'm';
 printf("%i, %f, %lf, %c\n", num, floatValue, doubleValue, charValue);

字符串輸入和輸出
前面我們學習過scanf和printf,利用C語言中的循環(huán)控制語句,我們可以逐個輸出,格式化采用“%s”。

#include <stdio.h>
#define N 20
int main(int argc, const char * argv[]) {
   
    char s1[]="hello world";
    char s2[N];
    
    printf("String1: %s\n", s1);
    printf(">");
    scanf("%s",s2);
    printf("String2: %s\n",s2);
    return 0;
}
輸出結(jié)果情況一:
String1: hello world
>qweerrttddsrtyydddd
String2: qweerrttddsrtyydddd
Program ended with exit code: 0
輸出結(jié)果情況二:
String1: hello world
>ni hao suny
String2: ni
Program ended with exit code: 0
這里有幾種情況,讀者可以去模擬一下
結(jié)論:輸入一個字符串,并打印出來。需要注意的是,字符數(shù)組的長度定義為N,在輸入字符時,最多能輸入 N-1個字符,以留出一個字節(jié)用于存放字符串結(jié)束標志'\0'。
從第二種輸出結(jié)果的情況,可以看出,當用scanf函數(shù)輸入字符串時,以空格作為字符串的結(jié)束符。因次,若輸入字符串中含有空格,空格后面的字符將不能存到數(shù)組中

字符串常用方法一

#include <stdio.h>
#include <string.h>
int myStrlen(char str[]);//聲明函數(shù)
int myStrlen2(char str[], int length);
int main(int argc, const char * argv[]) {
    // 1.如何輸出字符串
    /*
    // 1.1可以使用printf的%s占位符來輸出
    // 弊端 : 如果想要換行, 必須加上\n
    // 優(yōu)點 : 可以自定義格式化需要輸出的字符串, 也就是可以按照我們需要的格式來輸出
    char str[] = "ljk";
    printf("name = %s!!!!\n", str);
    printf("-------\n");
    // 1.2可以使用puts函數(shù)來輸出
    // 優(yōu)點: 可以自動換行
    // 缺點: 不可以自定義格式, 只能原樣輸出
    puts(str);
    printf("-------\n");
    */
    /*************************分割線*******************************/
    // 2.如何輸入字符
    /*
    // 2.1利用scanf接收字符串的注意點
    // scanf接收字符串, 會以空格 , tab, 回車作為結(jié)束符號, 也就是說利用scanf接收字符串時, 字符串中不能出現(xiàn)空格, tab, 回車
    printf("請輸入一個字符串\n");
    char buf[10];
    scanf("%s", buf);
    printf("buf = %s\n", buf);
    printf("-------\n");
    // 2.2利用gets接收字符串
    // warning: this program uses gets(), which is unsafe.
    // 如果使用gets接收字符串, 系統(tǒng)會提示我們正在使用一個不安全的方法接收字符
    // 優(yōu)點: 如果利用gets接收字符串 , 可以在字符串中輸入空格, tab
    printf("請輸入一個字符串\n");
    char buf2[10]; // lnj c
    gets(buf2);
    printf("buf = %s\n", buf2);
    printf("-------\n");
    */
    /*************************分割線*******************************/
    // 3.如何計算字符串的長度
    //            0123
    char str[] = "lnj cool"; // 3
//    int length = sizeof(str) / sizeof(str[0]) - 1;
    // strlen的原理: 從傳入的地址開始逐個取出字符串, 每取出一個就讓計數(shù)器+1. 直到遇到\0為止
//    size_t size =  strlen(str); // 計算出來的結(jié)果不包括\0
//    int size = myStrlen(str);
    int length = sizeof(str) / sizeof(str[0]);
    int size = myStrlen2(str, length);
    
    printf("length = %lu\n", size);
    for (int i = 0; i < size; i++) {
        printf("str[%i] = %c\n", i , str[i]);
    }
    return 0;
}
//函數(shù)實現(xiàn)(后面會詳細講解函數(shù))
int myStrlen2(char str[], int length)
{
    // 1.定義變量記錄取出了多少個字符
    int count = 0;
    // 2.遍歷字符數(shù)組
    for (int i = 0; i < length; i++) {
        if (str[i] != '\0') {
            count++;
        }
    }
    return count;
}

// 自定義一個strlen函數(shù)
int myStrlen(char str[])
{
   // 1.定義變量記錄取出了多少個字符
    int count = 0;
  // 2.遍歷字符數(shù)組
    while (str[count] != '\0') {
        count++; // 1 2 3
    }
    return count;
}

字符串常用方法二

#include <stdio.h>
#include <string.h>

int main(int argc, const char * argv[]) {
    
    // 1.字符串拼接
    /*
     // 原理 : 首先遍歷第一個字符串,直到遇到\0為止, 然后取出第二個字符串中的字符, 從\0的位置開始添加, 添加完畢之后再在最后添加一個\0
     
    char str1[7] = "lnj"; // l n j c o o l \0
    char str2[10] = " cool";
    printf("拼接前: %s\n", str1);
    // dest : 目標 src : 源
    // 將src中的數(shù)據(jù)拼接到dest后面
    // 注意: 要想使用字符串拼接函數(shù), 那么dest必須是一個數(shù)組, 并且數(shù)組的長度必須大于拼接之后的長度 \
    如果dest數(shù)組的長度, 不能完全存放dest+src+\0, 那么就會報錯
//    strcat(str1, str2);
    
    // char * 相當于dest  const char * 相當于src size_t 需要拼接的個數(shù)
    // 為了避免拼接之后超出str1的存儲范圍, 那么可以動態(tài)計算str2中需要拷貝幾個到str1后面不會超出
//                  str1能夠存放的元素個數(shù)            -   str1已經(jīng)存放的個數(shù)  - \0
    size_t length = sizeof(str1) / sizeof(str1[0]) - strlen(str1) - 1;
    printf("length = %lu\n", length);
    strncat(str1, str2, length);
    printf("拼接后: %s\n", str1);
     */
    
    /*************************華麗的分割線*******************************/
    
    // 2.字符串拷貝函數(shù)
    /*
    char str1[4] = "hello";
    char str2[] = "cool";
    printf("拷貝前 : str1 = %s\n", str1);
    // char * 目標, const char * 源
    // strcpy函數(shù)會將源的數(shù)據(jù)拷貝到目標中, 并且會覆蓋掉目標中原有的數(shù)據(jù)
    // 目標的容積必須能夠存放拷貝的數(shù)據(jù), 如果容積不夠會報錯
//    strcpy(str1, str2);
    
    // char * 目標, const char * 源 size_t 需要拷貝幾個
    // 注意: 拷貝操作是逐個替換, 拷貝了幾個就替換幾個
    //     str1能夠存放元素的個數(shù) - 1是給\0留出位置
    int length = sizeof(str1) / sizeof(str1[0]) - 1;
    strncpy(str1, str2, length);
    printf("拷貝后 : str1 = %s\n", str1);
    */
    /*************************分割線*******************************/
    
    // 3.字符串比較函數(shù)
    /*
    char str1[] = "aac"; // a a
    char str2[] = "abc"; // a b
    // strcmp它會對傳入的字符串進行比較, 比較完畢之后會返回一個整型的值給我們
    // 1、該值等于0,那么證明兩個字符串相等
    // 2、該值小于0, 那么證明str1小于str2
    // 3、該值大于0, 那么證明str1大于str2
    // strcmp的比較原理: 取出字符串中的每一個字符進行逐個比較, 如果發(fā)現(xiàn)不相等就不會繼續(xù)往下比較
    int res = strcmp(str1, str2);
    printf("res = %i\n", res);
     */
    
    return 0;
}

總結(jié)

希望讀者能夠良好的掌握字符數(shù)組和字符串,對字符串常用的方法要有所了解和運用,對前面所學的知識要連貫運用。

結(jié)尾

最后,希望讀者在讀文章的時候發(fā)現(xiàn)有錯誤或者不好的地方,歡迎留言,我會及時更改,感謝你的閱讀和評論已經(jīng)點贊收藏。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內(nèi)容

  • 數(shù)組在程序設(shè)計中,為了處理方便, 把具有相同類型的若干變量按有序的形式組織起來。這些按序排列的同類數(shù)據(jù)元素的集合稱...
    朱森閱讀 4,007評論 2 13
  • 指針是C語言中廣泛使用的一種數(shù)據(jù)類型。 運用指針編程是C語言最主要的風格之一。利用指針變量可以表示各種數(shù)據(jù)結(jié)構(gòu); ...
    朱森閱讀 3,473評論 3 44
  • 在c語言中,字符串是用字符數(shù)組來存儲的(并不像c++或者java等語言中有單獨的string類型), 存放時在字符...
    朱森閱讀 1,596評論 0 2
  • 本文轉(zhuǎn)自:http://www.cnblogs.com/lidabo/p/5225868.html 1)字符串操作...
    XiaohuiLI閱讀 9,555評論 0 0
  • 引自STM32的時鐘系統(tǒng)RCC詳細整理
    道無顯隱閱讀 610評論 0 2