C++文字列ポインタと文字配列の違い

7706 ワード

          
#include <iostream>

using namespace std;

int main()

{ 

    char ch1[10];

    strcpy_s(ch1,"123456");//    

    char* p = new char[10];

    strcpy_s(p,"123456");//  :   2   

}

以下のように変更すれば問題ありません.
strcpy_s(p,10,"123456");//    

どうしてこんなことになったの?
まず、文字配列と文字列ポインタの違いを見てみましょう.
1.二重引用符で囲まれた文字列定数は静的記憶タイプに属し、メモリの静的記憶領域に格納されるので、文字列定数がプログラムのどこに現れても、プログラムの実行中に1部しか格納されません.
文字列定数で文字配列を初期化すると、静的ストレージ領域から文字列全体を配列にコピーします.例:
char a[] = "hello";

文字列定数で文字ポインタを初期化すると、文字列の静的記憶領域のアドレスをポインタにコピーします.例:
char *p = "world";

この2つの形式の1つは重要です
違いは、ポインタで文字列の値を変更することはできませんが、
文字配列にはこの問題はありません.
文が間違っています.
p[0] = 'p';

次の文は問題ありません.
a[0] = 'a';

ポインタで文字列を変更するエラーを回避するには、次のように文字ポインタをconstタイプとして宣言することをお勧めします.
const char *p = "world";

例:
.int  main()

 {

  char str1[40]="hello world!";     //char *str1="hello world!";

  str1[4]='A';                      // str1     ,    ,          

 printf("%s
",str1); return 0; }

2.配列とポインタは、それらの定義で文字列定数で初期化できますが、同じように見えますが、最下位の実装メカニズムは異なります.
コンパイラは、ポインタが指すオブジェクトに空間を割り当てるのではなく、定義と同時にポインタに文字列定数を初期化しない限り、ポインタ自体の空間を割り当てるだけです.たとえば、次の定義では、メモリが割り当てられた文字列定数が作成されます.
char *p=”abcdefg”;

文字列定数のみがそうであることに注意してください.浮動小数点数などの定数に空間を割り当てることは期待できません.たとえば、次のようにします.
Float *p=2.34;  /**/

次に、ポインタを初期化するときに作成される文字列定数と配列内の文字列の違いについて例を挙げて説明します.
  • ANSI Cでは、ポインタを初期化するときに作成される文字列定数を読み取り専用として定義します.ポインタでこの文字列の値を変更しようとすると、プログラムは未定義の動作をします.一部のコンパイラでは、文字列定数は、読み取りのみが許可されているテキストセグメントに格納され、変更されないようにします.
  • 配列は文字列定数で初期化することもできます.
    Char a[]=”abcdefg”;


  • ポインタの反対に、文字列定数によって初期化された配列は変更できます.その中の1文字は後で変更できます.
    次に、vc 6の例を示します.1つの文字列のすべての大文字を小文字に変換する機能を完了します.
    #include<iostream>
    
    #include<ctype.h>  
    
    using namespace std;
    
    /******************************************************************************/  
    
    /* 
    
    *    Convert a string to lower case 
    
    */  
    
    
    
    int strlower(char *string)  
    
    {  
    
        if(string==NULL)  
    
        {  
    
        return -1;  
    
        }
    
        while(*string)  
    
        {  
    
            if(isupper(*string))  
    
            *string=tolower(*string);  
    
            string++;  
    
        }  
    
        *string='\0';  
    
        return 0;  
    
    }
    
    /*
    
    char *strlower(char *string) 
    
    { 
    
        char *s;
    
        if(string == NULL)
    
        { 
    
            return NULL; 
    
        }
    
        s = string; 
    
        while(*s)
    
        { 
    
            if(isupper(*s))
    
            { 
    
                *s = (char) tolower(*s); 
    
            } 
    
            s++; 
    
        } 
    
        *s = '\0'; 
    
        return string; 
    
    } 
    
    */
    
    void main()  
    
    {  
    
        char *test="ABCDEFGhijklmN"; 
    
        strlower(test);  
    
        cout<<test<<endl;  
    
    }

    ただし、char*test="ABCDEFGhijklmN";ランタイムエラーが発生します.Char test[]="ABCDEFGhijklmN"は、前述したようにプログラムが正常に動作します.