精华内容
下载资源
问答
  • C#——字符串复制+数组复制

    千次阅读 2019-11-26 20:34:15
    string.Copy(要复制字符串); CopyTo(要复制字符的起始位置(从第几个字符开始往后复制(不包括第几个字符)),目标字符数组,目标数组中的开始存放位置,要复制的字符个数); //Copy静态方法:string.方法来引用 ...

    复制是通过Copy和CopyTo来实现的。

    string.Copy(要复制的字符串);

    CopyTo(要复制字符的起始位置(从第几个字符开始往后复制(不包括第几个字符)),目标字符数组,目标数组中的开始存放位置,要复制的字符个数);

    //Copy静态方法:string.方法来引用

        string str="QiaoPeichen";
        
        string copyStr=string.Copy(str);
      
        Console.WriteLine(copyStr);
    

    //CopyTo非静态方法

        char[] array=new char[20];
        
        str.CopyTo(0,array,0,11);  //此方法无返回值
        
        Console.WriteLine(array);
    C#中数组复制有多种方法
    数组间的复制,int[] pins = {9,3,4,9};int [] alias = pins;这里出了错误,也是错误的根源,以上代码并没有出错,但是根本不是复制,因为pins和alias都是引用,存在于堆栈中,而数据9,3,4,3是一个int对象存在于堆中,int [] alias = pins;只不过是创建另一个引用,alias和pins同时指向{9,3,4,3},当修改其中一个引用的时候,势必影响另一个。复制的意思是新建一个和被复制对象一样的对象,在C#语言中应该有如下4种方法来复制。
    方法一:使用for循环
    
    int []pins = {9,3,7,2}
    int []copy = new int[pins.length];
    for(int i =0;i!=copy.length;i++)
    {
    copy[i] = pins[i];
    }
    
    方法二:使用数组对象中的CopyTo()方法
    
    int []pins = {9,3,7,2}
    int []copy2 = new int[pins.length];
    pins.CopyTo(copy2,0);
    
    方法三:使用Array类的一个静态方法Copy()
    
    int []pins = {9,3,7,2}
    int []copy3 = new int[pins.length];
    Array.Copy(pins,copy3,copy.Length);
    
    方法四:使用Array类中的一个实例方法Clone(),可以一次调用,最方便,但是Clone()方法返回的是一个对象,所以要强制转换成恰当的类类型。
    
    int []pins = {9,3,7,2}
    int []copy4 = (int [])pins.Clone();
    
    方法五:
    
    string[] student1 = { "$", "$", "c", "m", "d", "1", "2", "3", "1", "2", "3" };
    string[] student2 = { "0", "1", "2", "3", "4", "5", "6", "6", "1", "8", "16","10","45", "37", "82" };
    ArrayList student = new ArrayList();   
    foreach (string s1 in student1)
    {
          student.Add(s1);                
    }
    foreach (string s2 in student2)
    {
          student.Add(s2);
    }
    string[] copyAfter = (string[])student.ToArray(typeof(string));
    
    两个数组合并,最后把合并后的结果赋给copyAfter数组,这个例子可以灵活变通,很多地方可以用

     

    Copy(Array, Int64, Array, Int64, Int64)

    Copies a range of elements from an Array starting at the specified source index and pastes them to another Array starting at the specified destination index. The length and the indexes are specified as 64-bit integers.

     

     

    public static void Copy (Array sourceArray, long sourceIndex, Array destinationArray, long destinationIndex, long length);

     

    Copy(Array, Int32, Array, Int32, Int32)

    Copies a range of elements from an Array starting at the specified source index and pastes them to another Array starting at the specified destination index. The length and the indexes are specified as 32-bit integers.

     

     

    public static void Copy (Array sourceArray, int sourceIndex, Array destinationArray, int destinationIndex, int length);

     

    Copy(Array, Array, Int64)

    Copies a range of elements from an Array starting at the first element and pastes them into another Arraystarting at the first element. The length is specified as a 64-bit integer.

     

    Copy(Array, Array, Int32)

    Copies a range of elements from an Array starting at the first element and pastes them into another Arraystarting at the first element. The length is specified as a 32-bit integer.

     

     

    即在与硬件交互数据时,需要经过以下几步:

    第一,获得原始数据data,一般为字符串表示形式。

    第二,通过Encoding.ASCII.GetBytes(data)函数将原始数据转换为ASCII码表示形式data2

    第三,为提高存储效率,可以通过将data2进一步转换为16进制表示形式data3。所以16进制的需要存储容量较小。

    第四,将data3存入硬件。

    第五,如果需要将data3从硬件中读出。

    第六,通过先转换为2进制的ASCII码,再进一步转换为字符串进行显示,运算等。

     

     

    1、计算机存储信息的最小单位,称之为位(bit),音译比特,二进制的一个“0”或一个“1”叫一位。 
    2、计算机存储容量基本单位是字节(Byte),音译为拜特,8个二进制位组成1个字节,一个标准英文字母占一个字节位置,一个标准汉字占二个字节位置。 
    3、计算机存储容量大小以字节数来度量,1024进位制: 
    1024B=1K(千)B 
    1024KB=1M(兆)B 
    1024MB=1G(吉)B 
    1024GB=1T(太)B 
    以下还有PB、EB、ZB、YB 、NB、DB,一般人不常使用了。 
    4、字符是一种符号,同以上说的存储单位不是一回事。

     

     

    byte[] 之初始化赋值

    用for loop 赋值当然是最基本的方法,不过在C#里面还有其他的便捷方法。

    1. 创建一个长度为10的byte数组,并且其中每个byte的值为0.

    byte[] myByteArray = new byte[10];

    C# 在创建数值型(int, byte)数组时,会自动的把数组中的每个元素赋值为0.  (注:如果是string[], 则每个元素为的值为null. 

     

    2. 创建一个长度为10的byte数组,并且其中每个byte的值为0x08. 

    byte[] myByteArray = Enumerable.Repeat((byte)0x08, 10).ToArray();

    用linq来赋值,语句只要一条, 当然我们还可以赋值不同的,但是有一定规律的值。

    byte[] res= Enumerable.Range(1, 1000).Select(c=>Convert.ToByte(c)).ToArray();

     

    3. 直接赋值

    byte[] myByteArray = new byte[] { 0x01, 0x02, 0x03 };

     

    byte[] ---> ushort

                byte[] array = new byte[] { 0xFE, 0x00 };
    
                ushort register = BitConverter.ToUInt16(array, 0);

    上述转换后register 的值为 0x00FE

                byte[] array = new byte[] { 0x02, 0x01 ,0x04, 0x03 };
    
                ushort register = BitConverter.ToUInt16(array, 0);

    上述转化后,其实只是取了array[0], array[1].的值,最后register 的值是 0x00010002, 即258

    byte[] -> string

    public static string ByteArrayToString(byte[] ba)
    {
      string hex = BitConverter.ToString(ba);
      return hex.Replace("-","");
    }

     

    ushort ---> byte[]

                ushort register = 0x00F0;
    
                byte[] arr = BitConverter.GetBytes(register); 

    在PC系统里, arr[0] = 0xF0(地位), arr[1] = 0x00 . 

    互换ushort中的两个字节

     

                ushort number = 0x00F0;
    
                byte[] temp = BitConverter.GetBytes(number);
                Array.Reverse(temp); 
    
                ushort a = BitConverter.ToUInt16(temp, 0);
    
                ushort b = (ushort)(number << 8 | ((number & 0xFF00) >> 8));

     

     byte[] => Struct

     

    public StructType ConverBytesToStructure<StructType>(byte[] bytesBuffer)
            {
                // 检查长度。
                if (bytesBuffer.Length != Marshal.SizeOf(typeof(StructType)))
                {
                    throw new ArgumentException("bytesBuffer参数和structObject参数字节长度不一致。");
                }
    
                IntPtr bufferHandler = Marshal.AllocHGlobal(bytesBuffer.Length);
                for (int index = 0; index < bytesBuffer.Length; index++)
                {
                    Marshal.WriteByte(bufferHandler, index, bytesBuffer[index]);
                }
                StructType structObject = (StructType)Marshal.PtrToStructure(bufferHandler, typeof(StructType));
                Marshal.FreeHGlobal(bufferHandler);
                return structObject;
            }

     

     

    代码
    
         /// <summary>
            /// 将byte[]还原为指定的struct,该函数的泛型仅用于自定义结构
            /// startIndex:数组中 Copy 开始位置的从零开始的索引。
            /// length:要复制的数组元素的数目。
            /// </summary>
            public static T BytesToStruct<T>(byte[] bytes, int startIndex, int length)
            {
                if (bytes == null) return default(T);
                if (bytes.Length <= 0) return default(T);
                IntPtr buffer = Marshal.AllocHGlobal(length);
                try//struct_bytes转换
                {
                    Marshal.Copy(bytes, startIndex, buffer, length);
                    return (T)Marshal.PtrToStructure(buffer, typeof(T));
                }
                catch(Exception ex)
                {
                    throw new Exception("Error in BytesToStruct ! " + ex.Message);
                }
                finally
                {
                    Marshal.FreeHGlobal(buffer);
                }
            }

     

    Struct => byte[]

     

    代码 
    
         /// <summary>
            /// 将struct类型转换为byte[]
            /// </summary>
            public static byte[] StructToBytes(object structObj, int size)
            {
                IntPtr buffer = Marshal.AllocHGlobal(size);
                try//struct_bytes转换
                {
                    Marshal.StructureToPtr(structObj, buffer, false);
                    byte[] bytes = new byte[size];
                    Marshal.Copy(buffer, bytes, 0, size);
                    return bytes;
                }
                catch (Exception ex)
                {
                    throw new Exception("Error in StructToBytes ! " + ex.Message);
                }
                finally
                {
                    Marshal.FreeHGlobal(buffer);
                }
            }

     

     

    byte[] 数组比较

     

    //You can use Enumerable.SequenceEqual method.
    
    using System;
    using System.Linq;
    ...
    var a1 = new int[] { 1, 2, 3};
    var a2 = new int[] { 1, 2, 3};
    var a3 = new int[] { 1, 2, 4};
    var x = a1.SequenceEqual(a2); // true
    var y = a1.SequenceEqual(a3); // false

     

     

    string类型转成byte[]:

    byte[] byteArray = System.Text.Encoding.Default.GetBytes ( str );

     

    byte[]转成string:

    string str = System.Text.Encoding.Default.GetString ( byteArray );

     

    string类型转成ASCII byte[]:

    ("01" 转成 byte[] = new byte[]{ 0x30,0x31})

    byte[] byteArray = System.Text.Encoding.ASCII.GetBytes ( str );

     

    ASCIIbyte[]转成string:

    (byte[] = new byte[]{ 0x30, 0x31} 转成"01")

    string str = System.Text.Encoding.ASCII.GetString ( byteArray );

     

     

    参考: http://www.dotnetperls.com/initialize-array

     

     

     

     

    【C#】数据类型(sbyte,byte,short,ushort,int,uint,long,ulong和char。、、、)

      C#的数据类型可以分为3类:数值类型,引用类型,指针类型。指针类型仅在不安全代码中使用。    

      值类型包括简单类型(如字符型,浮点型和整数型等),集合类型和结构型。引用类型包括类类型,接口类型,代表类型和数组类型。

      值类型和引用类型的不同之处是值类型的变量值直接包含数据,而引用类型的变量把它们的引用存储在对象中。对于引用类型的变量,完全有可能让两个不同的变量引用同一个对象,这样一来,对其中一个变量的操作就会影响到被另一个变量引用的对象。对于值类型的变量而言,每一个变量有它们自己的数值,因此对其中一个变量的操作不可能影响到另外一个变量。

    1 值类型

      所有的值类型都隐含地声明了一个公共的无参数的构造函数,这个构造函数叫做默认构造函数。默认构造函数返回一个初始为零的值类型的实例,称之为默认值。

      对于sbyte,byte,short,ushort,int,uint,long,ulong,默认值为0。

      对于char,默认值是'\x0000' ,对于float,默认值是0。0F 对于double,默认值是0。0D 对于decimal,默认值是0。0M 对于bool,默认值是false 对于一个枚举类型,默认值是0 对于一个结构类型,默认值的设置就是把所有值类型的域都设置为它们各自的默认值,把所有的引用类型的域赋为空

      1.1 简单类型   

       C#提供一套预定义的结构类型叫做简单类型。简单类型用保留字定义,这些保留字仅仅是在System名字空间里预定义的结构类型的化名。比如int是保留字,System。Int32是在System名字空间中预定义类型。一个简单类型和它化名的结构类型是完全一样的,也就是说写int和写System。Int32是一样的。简单类型主要有整型,浮点类型,小数类型,布尔类型,字符型   

      1.1.1 整型

      C#中支持9种整型:sbyte,byte,short,ushort,int,uint,long,ulong和char。

      Sbyte:代表有符号的8位整数,数值范围从-128 ~ 127

      Byte:代表无符号的8位整数,数值范围从0~255

      Short:代表有符号的16位整数,范围从-32768 ~ 32767

      ushort:代表有符号的16位整数,范围从0 到 65,535

      Int:代表有符号的32位整数,范围从-2147483648 ~ 2147483648

      uint:代表无符号的32位整数,范围从0 ~ 4294967295

      Long:代表有符号的64位整数,范围从-9223372036854775808 ~ 9223372036854775808

      Ulong:代表无符号的64位整数,范围从0 ~ 18446744073709551615。

      char:代表无符号的16位整数,数值范围从0~65535。 Char类型的可能值对应于统一字符编码标准(Unicode)的字符集。

      Char类型与其他整数类型相比有以下两点不同之处: a,没有其他类型到char类型的隐式转换。即使是对于sbyte,byte和ushort这样能完全使用char类型代表其值的类型, sbyte,byte和ushort到char的隐式转换也不存在。 b,char类型的常量必须被写为字符形式,如果用整数形式,则必须带有类型转换前缀。

      比如(char)10赋值形式有三种: char chsomechar="A"; char chsomechar="\x0065"; 十六进制 char chsomechar="\u0065 ;

      unicode表示法 字符型中有下列转义符: 1,\'用来表示单引号 2,\"用来表示双引号 3,\\ 用来表示反斜杠 4, \0 表示空字符 5, \a 用来表示感叹号 6, \b 用来表示退格 7, \f 用来表示换页 8, \n 用来表示换行 9, \r 用来表示回车 10, \t 用来表示水平tab 11, \v 用来表示垂直tab

      1.1.2 浮点类型

      C#支持两种浮点类型:float和double。

      Float型所能表示的值的范围大约可以从1.5*10 -45~3.4* 10 38,精确到小数点后面7位。

      Double型所能表示的值的范围大约可以从5.0*10 -324~1.7* 10 308,精确到小数点后面15位或16位。 如果二元操作中的其中一个操作数为浮点类型,那么另外一个操作数是整型或浮点类型,运算规则如下: a,如果其中一个操作数是整型,则操作数被转换为另一个操作数的浮点数类型; b,如果操作数之一为double,则另一操作数也被转换成double类型,运算以double类型的精度和取值范围进行,并且所得结果也为double类型; c,否则,运算至少将以float类型的取值范围和精度进行,并且所得结果也为float型。

      1.1.3 小数(decimal)类型

      小数类型非常适用于金融和货币运算。数值范围从1.0*10 -28~7.9* 10 28,精确到小数点后面28位。如果二元操作中的其中一个操作数是小数类型,那么另外一个从操作数是整型或小数类型。整型在运算前被转化为小数类型数。如果一个小数类型的算术运算产生了一个对于小数类型的格式来说太小的值,操作的结果将会变成0。如果一个小数类型的算术运算产生了一个对于小数类型的格式来说太大的值,就会触发溢出错误。小数类型较浮点类型而言,具有更大的精确度,但是数值范围相对小了很多。将浮点类型的数向小数类型的数转化时会产生溢出错误,将小数类型的数向浮点类型的数转化时会造成精确度的损失。因此,两种类型不存在隐式或显式转换。布尔型:值为true或false。没有标准能实现布尔类型和其他类型的转换。 1.2 枚举类型 枚举类型的元素使用的类型只能是long,int,short,byte。默认类型是int。默认第一个元素的值是0,每一个连续的元素按1递增。可以给元素直接赋值。如:

     

    enum monthnames   
    {  
      January=1,  
      February,   
      march=31  
    };  
    可以强制定义其他类型,如:  
    enum monthnames : byte  
    {
      January ,  
      February,  
      March  
    };  
    enum monthnames 
    {
      January=1,
      February, 
      march=31
    };
    可以强制定义其他类型,如:
    enum monthnames : byte
    {  
      January ,
      February,
      March
    };

     


      1.3结构类型

      结构类型也是一种值类型,使用它的目的是用于创建小型的对象,用以节省内存。下面的例子表示一个使用byte类型的4个字段的IP地址。

     

    using System;  
    
    Struct IP //声明结构  
    {   
      publicbyte b1,b2,b3,b4;  
    }  
      
    Class test  
    {  
     publicstaticvoid Main()  
      {  
        IP myIP;  
        myIP.b1=192;  
        myIP.b2=168;  
        myIP.b3=1;  
        myIP.b4=101;  
        Console.Write("{0}.{1}。", myIP.b1, myIP.b2);  
        Console.Write("{0}.{1}", myIP.b3, myIP.b4);  
     }
    }  

     

     

    using System;
    Struct IP //声明结构
    { 
      public byte b1,b2,b3,b4;
    }
    
    Class test
    {
      public static void Main()
      {
        IP myIP;
        myIP.b1=192;
        myIP.b2=168;
        myIP.b3=1;
        myIP.b4=101;
        Console.Write("{0}.{1}。", myIP.b1, myIP.b2);
        Console.Write("{0}.{1}", myIP.b3, myIP.b4);
    }
    }

     

     

    2 引用类型

      引用类型包括类类型,接口类型,代表类型和数组类型。

      2.1 类类型类 类型定义了一种数据结构,这个数据结构中包含了数据成员(如常量,字段和事件等),函数成员(如方法,属性,索引,操作,构造函数和析构函数等)和嵌套 类型。支持继承。2.2 对象类型对象类型是其他所有类型最终的基础类型。在C#中每一种类型都直接或者间接的源于object这个类类型。

      2.3 字符串类型字符串类型是直接从object中继承而来的密封类。String类型的值可以写成字符串文字的形式。

      2.4 接口类型一个接口声明一个只有抽象成员的引用类型,接口仅仅存在方法标志,但没有执行代码。当定义一个类时,如果类从接口派生,可以派生自多重接口;但是如果类从类派生,就只能从一个类派生。 声明方法如例:

     

    interface iface  
    {  
     void showmyface();  
    }  
    interface iface
    {
        void showmyface();
    }

     

      2.5 代表类型

      代表引用一种静态的方法或者对象实例,引用该对象的实例方法。与其接近的是c/c++中的指针,但指针只能访问静态的函数,代表既能访问静态的方法,也能访问实例的方法。

      2.6 数组数组是包含一串变量的数据结构。数组变量也称做数组元素,它们具有相同的类型,这种类型也称做数组元素类型。数组的元素类型可以是任何类型,包括数组类型。数组用下标确定每一个数组元素的索引号。只有一个下标的数组称为一维数组,多于一个下标的数组称为 多维数组。

       例:int[] a={0,2,4,6,8}; 等价于int[] a=new int[] {0,2,4,6,8}; 也可以这样初始化:a[0]=0; a[1]=2; a[2]=4; a[3]=6; a[4]=8;

       int[] a; //int型的一维数组

       int[,] a;int型的二维数组

       int[,,] a; //int型的三维数组

       int[] []a; //int型的数组的数组

       int[][][]a; //int型的数组的数组的数组

       数组的每个维数的长度不是数组类型的一部分,维数的长度是在数组创建语句中指定的,而不是在数组类型中 指定的,

       例如: int[,,] a3=new int[10,20,30]; a3是是一个数组变量, int[,,] 没有指定数组的长度,数组创建语句new int[10,20,30]才指定。

       下面的例子创建一个数组的数组:

       int[][] J=new int[3][];

       J[0]=new int[] {1,2,3};

       J[1]=new int[] {1,2,3,4,5,6};

       J[2]=new int[] {1,2,3,4,5,6,7,8,9};

     

    展开全文
  • 数组s1中的字符串复制数组s2中

    千次阅读 2019-03-14 20:48:05
    #include&quot;stdio.h&quot; #include&quot;string.h&quot; #define N 81 void strcpy(char s2[],char s1[]) { int i,j; i=0;j=0; while(s2[j++]=s1[i++]);...请输入字符串:&
    #include"stdio.h"
    #include"string.h"
    #define N 81
    void Strcopy(char s2[],char s1[])
    {
    	int i,j;
    	i=0;j=0;
    	while(s2[j++]=s1[i++]);
    }
    int main(void)
    {
    	char s1[81];
    	char s2[81];
    	printf("请输入字符串:");
    	gets(s1);
    	//复制字符串
    	Strcopy(s2,s1);
    	printf("数组s2的值为:");
    	puts(s2);
    	return 0;
    }
    
    展开全文
  • C++ 字符串与字符数组 详解

    万次阅读 多人点赞 2018-03-03 19:28:22
    字符串实际上是使用 null 字符 ‘\0’ 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。 下面的声明和初始化创建了一个 “Hello” 字符串。由于在数组的末尾存储了空字符,所以...

    在C++中,有两种类型的字符串表示形式:

    • C-风格字符串
    • C++引入的string类

    C-风格字符串

    C 风格的字符串起源于 C 语言,并在 C++ 中继续得到支持。字符串实际上是使用 null 字符 ‘\0’ 终止的一维字符数组。因此,一个以 null 结尾的字符串,包含了组成字符串的字符。
    下面的声明和初始化创建了一个 “Hello” 字符串。由于在数组的末尾存储了空字符,所以字符数组的大小比单词 “Hello” 的字符数多一个。

    char greeting[6] = {'H', 'e', 'l', 'l', 'o', '\0'};

    其实,您不需要把 null 字符放在字符串常量的末尾。C++ 编译器会在初始化数组时,自动把 ‘\0’ 放在字符串的末尾。所以也可以利用下面的形式进行初始化

    char greeting[] = "Hello";

    以下是 C/C++ 中定义的字符串的内存表示:
    这里写图片描述
    C++ 中有大量的函数用来操作以 null 结尾的字符串:

    序号函数功能
    1strcpy(s1,s2)复制字符串 s2 到字符串 s1
    2strcat(s1,s2)连接字符串 s2 到字符串 s1 的末尾
    3strlen(s1)返回字符串 s1 的长度
    4strcmp(s1,s2)返回s1与s2的比较结果
    5strchr(s1,ch)返回一个指针,指向字符串s1中字符ch的第一次出现的位置
    6strstr(s1,s2)返回一个指针,指向字符串s1中s2的第一次出现的位置

    C++ 中的 String 类

    C++ 标准库提供了 string 类类型,支持上述所有的操作,另外还增加了其他更多的功能。比如:

    • append() – 在字符串的末尾添加字符
    • find() – 在字符串中查找字符串
    • insert() – 插入字符
    • length() – 返回字符串的长度
    • replace() – 替换字符串
    • substr() – 返回某个子字符串

    4种字符串类型

    C++中的字符串一般有以下四种类型,

    • string

    • char*

    • const char*
    • char[]

    下面分别做简单介绍,并说明其中的一些区别

    string

    string是一个C++类库中的一个类,它位于名称空间std中,因此必须使用using编译指令或者std::string来引用它。它包含了对字符串的各种常用操作,它较char*的优势是内容可以动态拓展,以及对字符串操作的方便快捷,用+号进行字符串的连接是最常用的操作

    char*

    char* 是指向字符串的指针(其实严格来说,它是指向字符串的首个字母),你可以让它指向一串常量字符串。

    const char*

    该声明指出,指针指向的是一个const char类型,即不能通过当前的指针对字符串的内容作出修改

    注意这里有两个概念:

    • char * const [指向字符的静态指针]
    • const char * [指向静态字符的指针]

    前者const修饰的是指针,代表不能改变指针
    后者const修饰的是char,代表字符不能改变,但是指针可以变,也就是说该指针可以指针其他的const char。

    char[]

    与char*与许多相同点,代表字符数组,可以对应一个字符串,如

    char * a="string1";
    char b[]="string2";

    这里a是一个指向char变量的指针,b则是一个char数组(字符数组)
    也就是说:

    二者的不同点

    一,char*是变量,值可以改变, char[]是常量,值不能改变!
    a是一个char型指针变量,其值(指向)可以改变;
    b是一个char型数组的名字,也是该数组首元素的地址,是常量,其值不可以改变

    二,char[]对应的内存区域总是可写,char*指向的区域有时可写,有时只读
    比如:

    char * a="string1";
    char b[]="string2";
    gets(a); //试图将读入的字符串保存到a指向的区域,运行崩溃! 
    gets(b) //OK

    解释: a指向的是一个字符串常量,即指向的内存区域只读;
    b始终指向他所代表的数组在内存中的位置,始终可写!

    注意,若改成这样gets(a)就合法了:

    char * a="string1";
    char b[]="string2";
    a=b; //a,b指向同一个区域
    gets(a) //OK
    printf("%s",b) //会出现gets(a)时输入的结果

    解释: a的值变成了是字符数组首地址,即&b[0],该地址指向的区域是char *或者说 char[8],习惯上称该类型为字符数组,其实也可以称之为“字符串变量”,区域可读可写。

    总结:char *本身是一个字符指针变量,但是它既可以指向字符串常量,又可以指向字符串变量,指向的类型决定了对应的字符串能不能改变!

    三,char * 和char[]的初始化操作有着根本区别:
    测试代码:

    char *a="Hello World"; 
    char b[]="Hello World"; 
    printf("%s, %d\n","Hello World", "Hello World"); 
    printf("%s, %d %d\n", a, a,  &a);                           
    printf("%s, %d %d\n", b,     b,  &b);

    结果:

    Hello World,13457308
    Hello World,13457308    2030316
    Hello World,2030316 2030316

    结果可见:尽管都对应了相同的字符串,但”Hellow World”的地址 和 a对应的地址相同,与b指向的地址有较大差异;&a 、&b都是在同一内存区域,且&b==b
    根据c内存区域划分知识,我们知道,局部变量都创建在栈区,而常量都创建在文字常量区,显然,a、b都是栈区的变量,但是a指向了常量(字符串常量),b则指向了变量(字符数组),指向了自己(&b==b==&b[0])。
    说明以下问题:
    char * a=”string1”;是实现了3个操作:

    1. 声明一个char*变量(也就是声明了一个指向char的指针变量);
    2. 在内存中的文字常量区中开辟了一个空间存储字符串常量”string1”
    3. 返回这个区域的地址,作为值,赋给这个字符指针变量a

    最终的结果:指针变量a指向了这一个字符串常量“string1”
    (注意,如果这时候我们再执行:char * c=”string1”;则,c==a,实际上,只会执行上述步骤的1和3,因为这个常量已经在内存中创建)

    char b[]=”string2”;则是实现了2个操作:

    1. 声明一个char 的数组,
    2. 为该数组“赋值”,即将”string2”的每一个字符分别赋值给数组的每一个元素

    最终的结果:“数组的值”(注意不是b的值)等于”string2”,而不是b指向一个字符串常量

    实际上, char * a=”string1”; 的写法是不规范的!
    因为a指向了即字符常量,一旦strcpy(a,”string2”)就糟糕了,试图向只读的内存区域写入,程序会崩溃的!尽管VS下的编译器不会警告,但如果你使用了语法严谨的Linux下的C编译器GCC,或者在windows下使用MinGW编译器就会得到警告。
    所以,我们还是应当按照”类型相同赋值”的原则来写代码:

    const char * a="string1";

    保证意外赋值语句不会通过编译

    另外,关于char*和char[]在函数参数中还有一个特殊之处,运行下面的代码

    void fun1 ( char *p1,  char p2[] ) {
     printf("%s %d %d\n",p1,p1,&p1);
     printf("%s %d %d\n",p2,p2,&p2);
    p2="asdf"; //通过! 说明p2不是常量! 
    printf("%s %d %d\n",p2,p2,&p2);
    }
    void main(){
    char a[]="Hello";
    fun1(a,a);
    }

    运行结果:

    Hello 3471628 3471332
    Hello 3471628 3471336
    asdf 10704764 3471336

    结果出乎意料!上面结果表明p2这时候根本就是一个指针变量!
    结论是:作为函数的形式参数,两种写法完全等效的!都是指针变量!

    const char*与char[]的区别:
    const char * a=”string1”
    char b[]=”string2”;
    二者的区别在于:

    1. a是const char 类型, b是char const类型
      ( 或者理解为 (const char)xx 和 char (const xx) )

    2. a是一个指针变量,a的值(指向)是可以改变的,但a只能指向(字符串)常量,指向的区域的内容不可改变;

    3. b是一个指针常量,b的值(指向)不能变;但b指向的目标(数组b在内存中的区域)的内容是可变的

    4. 作为函数的声明的参数的时候,char []是被当做char *来处理的!两种形参声明写法完全等效!

    字符串类型之间的转换: string、const char*、 char* 、char[]相互转换

    一、转换表格

    源格式->目标格式stringchar*const char*char[]
    stringNULL直接赋值直接赋值直接赋值
    char*strcpyNULLconst_castchar*=char
    const char*c_str()直接赋值NULLconst char*=char;
    char[]copy()strncpy_s()strncpy_s()NULL

    二、总结方法:

    1. 变成string,直接赋值。
    2. char[]变成别的,直接赋值。
    3. char*变constchar*容易,const char*变char*麻烦。<const_cast><char*>(constchar*);
    4. string变char*要通过const char*中转。
    5. 变成char[]。string逐个赋值,char* const char* strncpy_s()。

    三,代码示例

    1、string转为其他类型

    ①、string转const char*

    #include "stdafx.h"
    #include <iostream>
    int _tmain(intargc, _TCHAR* argv[])
    {
        std::string str = "HelloWorld!";     //初始化string类型,并具体赋值
        const char* constc = nullptr;         //初始化const char*类型,并赋值为空
        constc= str.c_str();                 //string类型转const char*类型
        printf_s("%s\n", str.c_str());        //打印string类型数据 .c_str()
        printf_s("%s\n", constc);             //打印const char*类型数据
        return 0;
    }

    ②、string转char*

    #include "stdafx.h"
    #include <iostream>
    int _tmain(intargc, _TCHAR* argv[])
    {
        std::string str = "HelloWorld!";     //初始化string类型,并具体赋值
        char* c = nullptr;                    //初始化char*类型,并赋值为空
        const char* constc = nullptr;         //初始化const char*类型,并赋值为空
        constc= str.c_str();                 //string类型转const char*类型
        c= const_cast<char*>(constc);        //const char*类型转char*类型
        printf_s("%s\n", str.c_str());        //打印string类型数据 .c_str()
        printf_s("%s\n",c);                  //打印char*类型数据
        return 0;
    
    }

    ③、string转char[]

    #include "stdafx.h"
    #include <iostream>
    int _tmain(intargc, _TCHAR* argv[])
    {
        std::string str = "HelloWorld!";      //初始化string类型,并具体赋值
        char arrc[20] = {0};                   //初始化char[]类型,并赋值为空
        for (int i = 0; i < str.length(); i++) //string类型转char[]类型
        {
            arrc[i]=str[i];
        }
        printf_s("%s\n", str.c_str());         //打印string类型数据 .c_str()
        printf_s("%s\n", arrc);                //打印char[]类型数据
        return 0;
    }

    2、const char*转为其他类型

    ①const char*转string

    #include "stdafx.h"
    #include <iostream>
    int _tmain(intargc, _TCHAR* argv[])
    {
        const char* constc = "Hello World!";     //初始化const char* 类型,并具体赋值
        std::string str;                        //初始化string类型
        str= constc;                            //const char*类型转string类型
        printf_s("%s\n", constc);                //打印const char* 类型数据
        printf_s("%s\n", str.c_str());           //打印string类型数据
        return 0;
    }

    ②const char*转char*

    #include "stdafx.h"
    #include <iostream>
    int _tmain(intargc, _TCHAR* argv[])
    {
        const char* constc = "Hello World!";     //初始化const char* 类型,并具体赋值
        char* c = nullptr;                       //初始化char*类型
        c= const_cast<char*>(constc);           //const char*类型转char*类型
        printf_s("%s\n", constc);                //打印const char* 类型数据
        printf_s("%s\n", c);                     //打印char*类型数据
        return 0;
    }

    ③const char*转char[]

    #include "stdafx.h"
    #include <iostream>
    int _tmain(intargc, _TCHAR* argv[])
    {
        const char* constc = "Hello World!";     //初始化const char* 类型,并具体赋值
        char arrc[20] = { 0 };                   //初始化char[]类型,并赋值为空
        strncpy_s(arrc,constc,20);              //const char*类型转char[]类型
        printf_s("%s\n", constc);                //打印const char* 类型数据
        printf_s("%s\n", arrc);                  //打印char[]类型数据
        return 0;
    }

    3、char*转为其他类型

    ①char*转string

    #include "stdafx.h"
    #include <iostream>
    int _tmain(intargc, _TCHAR* argv[])
    {
        char* c = "HelloWorld!";           //初始化char* 类型,并具体赋值
        std::string str;                   //初始化string类型
        str= c;                            //char*类型转string类型
        printf_s("%s\n", c);                //打印char* 类型数据
        printf_s("%s\n", str.c_str());      //打印string类型数据
        return 0;
    }

    ②char*转const char*

    #include "stdafx.h"
    #include <iostream>
    int _tmain(intargc, _TCHAR* argv[])
    {
        char* c = "HelloWorld!";         //初始化char* 类型,并具体赋值
        const char* constc = nullptr;     //初始化const char* 类型,并具体赋值
        constc= c;                       //char*类型转const char* 类型
        printf_s("%s\n", c);              //打印char* 类型数据
        printf_s("%s\n", constc);         //打印const char* 类型数据
        return 0;
    }

    ③char*转char[]

    #include "stdafx.h"
    #include <iostream>
    int _tmain(intargc, _TCHAR* argv[])
    {
        char* c = "HelloWorld!";         //初始化char* 类型,并具体赋值
        char arrc[20] = { 0 };           //初始化char[] 类型,并具体赋值
        strncpy_s(arrc,c,20);             //char*类型转char[] 类型
        printf_s("%s\n", c);              //打印char* 类型数据
        printf_s("%s\n", arrc);           //打印char[]类型数据
        return 0;
    }

    4、char[]转为其他类型

    #include "stdafx.h"
    #include <iostream>
    int _tmain(intargc, _TCHAR* argv[])
    {
        char arrc[20] = "HelloWorld!";//初始化char[] 类型并具体赋值
        std::string str;                 //初始化string
        const char* constc = nullptr;   //初始化const char*
        char*c = nullptr;                //初始化char*
        str= arrc;                     //char[]类型转string类型
        constc= arrc;             //char[]类型转const char* 类型
        c= arrc;                        //char[]类型转char*类型
        printf_s("%s\n", arrc);         //打印char[]类型数据
        printf_s("%s\n", str.c_str());  //打印string类型数据
        printf_s("%s\n", constc);       //打印const char* 类型数据
        printf_s("%s\n", c);            //打印char*类型数据
        return 0;
    }
    展开全文
  • IDE:codeblocks ...把较短的字符串放在a数组,把较长的字符串放在b数组,并输出 #include <iostream> #include <cmath> #include <cstring> using namespace std; void swap(char [],char...

    IDE:codeblocks

    日期:2019/12/3

    功能:任意输入两个字符串,并存放在a和b数组中。把较短的字符串放在a数组,把较长的字符串放在b数组,并输出

    #include <iostream>
    #include <cmath>
    #include <cstring>
    using namespace std;
    
    void swap(char [],char [],int n);
    
    int main(void)
    {
        char a[100],b[100];
        cout<<"依次输入字符串a和b"<<endl;
        cin>>a;
        cin>>b;
        cout<<"a="<<a<<','<<"b="<<b<<endl;
        int a_len = strlen(a);
        int b_len = strlen(b);
        if(a_len>b_len)
            swap(a,b,a_len);
        cout<<"a="<<a<<','<<"b="<<b<<endl;
        return 0;
    }
    
    void swap(char a[],char b[],int n)
    {
        for(int i=0;i<n;i++)
        {
            char t =a[i];
            a[i] = b[i];
            b[i] = t;
        }
    }
    
    
    
    展开全文
  • 如何将字符串复制数组

    千次阅读 2012-12-09 16:21:28
    好久没写过关于C语言的东西,今天发一个. 使用strcpy
  • 定义指针字符串:char*v->VOD_REQUEST_ID=“123455” 分配指针字符串地址: char *VOD_SERVER_REQUEST_DATA=(char *)malloc(strlen(v->VOD_REQUEST_ID)+1) ; 复制,v->VOD_REQUEST_ID: strcpy(VOD_SERVER...
  • C语言字符串赋值给数组/char *

    千次阅读 2021-01-27 19:22:20
    字符串(c语言): 以“abcd”为例,解释...1. 字符串赋值char * int main(int argc, const char *argv[]) { char *p1 = "hello"; printf("p1[0] = %c\n", *p1); printf("%s\n", p1); char *p2 = NULL; ...
  • C++ 复制字符串/字符数组

    千次阅读 2017-04-18 21:12:11
    【项目1-小心地放开玩字符串/字符数组】 (2)读程序,请分析其实现的功能 [cpp] view plaincopyprint? #include  using namespace std;  int main()  {   char str1[50]="I...
  • 在程序设计中,为了方便处理,...因此按照数组元素的类型不同,数组又可分为数值数组字符数组、指针数组、结构数组等各种类别。 本文主要介绍一维数组、二维数组字符数组,其余的数组将会在以后的文章中介绍到...
  • 字符串与字符数组

    2013-10-15 09:31:30
    字符串:是一种特殊的字符数组,C++没有专门的字符串类型,一个字符串即为一个字符数组,不过字符串最后面还有“\0”表示字符串结束 字符串处理函数: strcmp(字符数组名1,字符数组名2):按ASCII码值的顺序...
  • java字符串转int数组

    2020-04-27 11:06:42
    可以先将字符串转成字符串数组,在将字符串数组中的每个元素转成int类型复制给字符串数组长度的int数组 /** * 字符串转数组 * @param commentLabelIds * @return */ public int[] changeString(String ...
  • (2)用字符串初始化字符字符数组 (3)获取字符串的长度 三、字符串与指针 四、字符数组与字符指针 一、字符数组 字符数组是存放字符数据的数组,每个元素都是单个字符。 (1)字符数组的定义 char 数组名...
  • C语言-字符串与字符数组区别

    万次阅读 多人点赞 2019-05-25 21:56:48
    数字0(和字符'\0'等价)结尾的char数组就是一个字符串,但如果char数组没有以数字0结尾,那么就不是一个字符串,只是普通字符数组,所以字符串是一种特殊的char数组。 注: %s是打印一个字符串,%c是打印一个字符 ...
  •  功能说明:将字符串复制到字符数组中。该函数有两个参数。第一个参数为“目标数组”,第二个参数为“字符串”。  参考实例:  var  arrChar: array[0..255] of Char; // 这里声明了长度为256的Char型...
  •  strcmp() 对两个字符串进行大小写敏感的比较  strcmpi() 对两个字符串进行大小写不敏感的比较  stricmp() 同strcmpi()  strncmp() 对两个字符串的一部分进行大小写敏感的比较  strnicmp() 对两个字符...
  • 字符数组的初始化,最容易理解的方式就是逐个字符给数组中各元素。 char str[10]={ 'I',' ','a','m',' ',‘h','a','p','p','y'}; 即把10个字符分别赋str[0]到str[9]10个元素 如果花括号...
  • ============1.字符数组: 用来存放字符数组称为字符数组,例如: char a[10]; //一维字符数组 char b[5][10]; //二维字符数组 ...// 部分数组元素赋值 char d[]={'c', ' ',
  • 1. 字符串指针变量本身是一个变量,用于存放...字符数组是由于若干个数组元素组成的,它可用来存放整个字符串。 2. 对字符串指针方式 char *ps="C Language"; 可以写为: char *ps; ps="C Language"; 而对数组
  • 1.字符数组字符串 #include<iostream> #include<string> using namespace std; int main(){ char str[5]={'a','b','c','d'}; string s1(str);//声明时赋值转化 cout<<s1<<endl; ...
  • 字符数组的初始化,最容易理解的方式就是逐个字符给数组中各元素。 char str[10]={ 'I',' ','a','m',' ',‘h','a','p','p','y'}; 即把10个字符分别赋str[0]到str[9]10个元素 如果花括号中提供的字符个数大于...
  • Delphi 字符串转字节数组

    千次阅读 2018-04-08 11:50:48
    procedure TFlowSubtitles.btnOKClick(Sender: TObject); var nLength : Integer; TxBuf_Com : array of Byte; TxBuf_Net : array[0..13] of Byte... //发送数据数组 i, j, k, m : Integer; //循环 iCount : In...
  • 课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565题目【项目1-小心地放开玩字符串/字符数组】(2)读程序,请分析其实现的功能[cpp] view plaincopyprint?#include using namespace std;...
  • java字符串--数组(相互转化)

    万次阅读 2019-01-04 22:03:35
    字符串  1.char数组(字符数组)-&gt;字符串  可以通过:使用String.copyValueOf(charArray)函数实现。   举例:   char[] arr={'a','b','c'};  String string =String.copyValueOf(arr);  System....
  • C语言—字符串(字符数组)

    千次阅读 2014-04-10 10:55:51
    # 在C语言中使用字符数组来模拟字符串 # C语言中的字符串是以‘\0’结束的字符数组 # C语言中的字符串可以分配于栈空间,堆空间或者只读存储区 #include #include int main() { char s1[] = {'H', 'e', 'l', ...
  • c++字符串与字符数组拷贝问题

    千次阅读 2018-05-21 20:24:37
    char 数组长度 用strlen();
  • 指针 与 数组 ( 指针 | 数组 | 指针运算 | 数组访问方式 | 字符串 | 指针数组 | 数组指针 | 多维数组 | 多维指针 | 数组参数 | 函数指针 | 复杂指针解读)
  • 一组字符串常量声明数组的3种方法

    千次阅读 2018-11-22 17:01:28
    一个char指针数组、char数组数组、string对象数组
  • C语言规定,可以将字符串直接赋值字符数组 在C语言中,字符串总是以'\0'作为串的结束符。上面的两个字符串,编译器已经在末尾自动添加了'\0'。 '\0'是ASCII码表中的第0个字符,用NUL表示,称为空字符。
  • #include#define N 20 void fun(char *a,char *s) { int i; for(i=0;i;i++) { if(s[i]!='\0') a[i]=s[i]; else a[i]='\0'; } } int main() { char a[N],*b="abcd123efgch";... printf("\nThe
  • socket类有一对函数send()和recv()但是当...因此就产生了要把用GetDlgItemText()获得的字符串赋值字符数组,然后才能正常传递的问题。 到网上搜索了半天终于找到了转换的方法: char ss[1024]; CString temp; str...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 284,925
精华内容 113,970
关键字:

字符串复制给数组