精华内容
下载资源
问答
  • 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语言):

    以“abcd”为例,解释如下:

    1. 申请了空间(在常量区),存放了字符串 
    2. 在字符串尾加上了'/0'    
    3. 返回地址

    一定记清楚!!

     

    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;
        p2 = "world";
        printf("p2[0] = %c\n", *p2);
        printf("%s\n", p2);
    
        return 0;
    }

    小结:以下两种形式赋值效果相同

     

    char *p1 = "hello";

     

     char *p2 = NULL;

     p2 = "world";


    2. 字符串赋值给数组

    1) 字符串赋值给定长数组

    int main(int argc, const char *argv[])
    {
        char p1[10] = "hello";
        printf("%s", p1);
    
        return 0;
    }
    
    /* 结果输出:
    
    hello
    
    */
    int main(int argc, const char *argv[])
    {
        char p2[10];
        p2 = "hello";
    
        return 0;
    }
    
    /*
    ../src/demon.c: In function 'main':
    ../src/demon.c:46:8: error: assignment to expression with array type
       46 |     p2 = "hello";
          |        ^
    ../src/demon.c:45:10: warning: variable 'p2' set but not used [-Wunused-but-set-variable]
       45 |     char p2[10];
          |          ^~
    */

    小结:以下两种形式不同

     

    char p1[10] = "hello";

     

    char p2[10];

    p2 = "hello";

    对于第二种形式的理解: “hello”赋值的值是一个地址,p2是一个常量地址却。因此不能将字符串的地址赋值给一个常量

    2)字符串赋值给未知长度数组

    int main(int argc, const char *argv[])
    {
        char p[] = "hello";
    
        printf("%s", p);
        printf("sizeof(p[]) = %d", (int)sizeof(p));
    
        return 0;
    }
    
    /*结果输出:
    > Executing task: .\bin\demon.exe <
    
    hello
    sizeof(p[]) = 6
    终端将被任务重用,按任意键关闭。
    */

    char str[] = "hello";
    因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"hello",而又因为字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为
    char str[6] = {'h','e','l','l','o','\0'};
    

    小结:字符串赋值给不定长度的数组时,sizeof数组计算出来的长度结果中是包含‘\0’的。

    展开全文
  • C语言中,字符数组可以存放字符串。字符数组是对字符串有特殊处理能力的数组字符数组就是用来对字符串进行操作的,当然可以存放字符串,且字符串可以整体输入、输出。数组赋值操作是不能整体操作的,而需要对...

    e095603c64310fe843a99e9da6bfe337.png

    在C语言中,字符数组可以存放字符串。字符数组是对字符串有特殊处理能力的数组。字符数组就是用来对字符串进行操作的,当然可以存放字符串,且字符串可以整体输入、输出。数组的赋值操作是不能整体操作的,而需要对其中元素逐个赋值,字符数组也不例外。

    字符数组和字符串

    用来存放字符的数组称为字符数组。字符数组的各个元素依次存放字符串的各字符,字符数组的数组 名代表该数组的首地址,这为处理字符串中个别字符和引用整个字符串提供了极大的方便。 字符数组的定义形式与前面介绍的数值数组相同。例如:char c[10];

    字符数组也允许在定义时进行初始化赋值。例如:char c[6]={'c', ' h ', 'i', 'n', 'a' , '\0' };

    对字符数组的各个元素逐个赋值后,各元素的值为:c[0]= 'c',c[1]= 'h',c[2]= 'i',c[3]= 'n',c[4]= 'a',c[5]= '\0';

    其中,‘\0’为字符串结束符。如果不对 c[5]赋任何值,‘\0’会由系统自动添加。

    字符数组也可采用字符串常量的赋值方式,例如:char a[]={"china"};

    想要了解web开发知识,请查阅 HTML中文网 !!

    展开全文
  • 数组就是数组,其大小与元素的类型和个数有关。定义数组时必须指定其元素的类型和个数。数组可以存任何类型的数据,但不能存函数。一、以指针的形式访问和以下标的形式访问下面我们就详细讨论讨论它们之间似是而...

    指针和数组到底有什么样的关系,他们之间没有任何关系!

    指针就是指针,指针变量在32 位系统下,永远占4 个byte,其值为某一个内存的地址。指针可以指向任何地方,但不是任何地方你都能通过这个指针变量访问到。

    数组就是数组,其大小与元素的类型和个数有关。定义数组时必须指定其元素的类型和个数。数组可以存任何类型的数据,但不能存函数。

    一、以指针的形式访问和以下标的形式访问

    下面我们就详细讨论讨论它们之间似是而非的一些特点。例如,函数内部有如下定义:

    A)

    char *p = “abcdef”;

    B)

    char a[] = “123456”;

    1、以指针的形式访问和以下标的形式访问指针

    例子A)定义了一个指针变量p,p 本身在栈上占4 个byte,p 里存储的是一块内存的首地址。这块内存在静态区,其空间大小为7 个byte,这块内存也没有名字。对这块内存的访问完全是匿名的访问。比如现在需要读取字符‘e’,我们有两种方式:

    1)

    以指针的形式:*(p+4)。先取出p 里存储的地址值,假设为0x0000FF00,然后加上4 个字符的偏移量,得到新的地址0x0000FF04。然后取出0x0000FF04 地址上的值。

    2)

    以下标的形式:p[4]。编译器总是把以下标的形式的操作解析为以指针的形式的操作。p[4]这个操作会被解析成:先取出p 里存储的地址值,然后加上中括号中4 个元素的偏移量,计算出新的地址,然后从新的地址中取出值。也就是说以下标的形式访问在本质上与以指针的形式访问没有区别,只是写法上不同罢了。

    2、以指针的形式访问和以下标的形式访问数组

    例子B)定义了一个数组a,a 拥有7 个char 类型的元素,其空间大小为7。数组a 本身在栈上面。对a 的元素的访问必须先根据数组的名字a 找到数组首元素的首地址,然后根据偏移量找到相应的值。这是一种典型的“具名+匿名”访问。比如现在需要读取字符‘5’,我们有两种方式:

    1)

    以指针的形式:*(a+4)。a 这时候代表的是数组首元素的首地址,假设为0x0000FF00,然后加上4 个字符的偏移量,得到新的地址0x0000FF04。然后取出0x0000FF04 地址上的值。

    2)

    以下标的形式:a[4]。编译器总是把以下标的形式的操作解析为以指针的形式的操作。a[4]这个操作会被解析成:a 作为数组首元素的首地址,然后加上中括号中4 个元素的偏移量,计算出新的地址,然后从新的地址中取出值。

    由上面的分析,我们可以看到,指针和数组根本就是两个完全不一样的东西。只是它们都可以“以指针形式”或“以下标形式”进行访问。一个是完全的匿名访问,一个是典型的具名+匿名访问。一定要注意的是这个“以XXX 的形式的访问”这种表达方式。

    另外一个需要强调的是:上面所说的偏移量4 代表的是4 个元素,而不是4 个byte。只不过这里刚好是char 类型数据1 个字符的大小就为1 个byte。记住这个偏移量的单位是元素的个数而不是byte 数,在计算新地址时千万别弄错了。

    二、指针数组和数组指针的内存布局

    初学者总是分不出指针数组与数组指针的区别。其实很好理解:

    指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身决定。它是“储存指针的数组”的简称。

    数组指针:首先它是一个指针,它指向一个数组。在32 位系统下永远是占4 个字节,至于它指向的数组占多少字节,不知道。它是“指向数组的指针”的简称。

    下面到底哪个是数组指针,哪个是指针数组呢:

    A)

    int *p1[10];

    B)

    int (*p2)[10];

    每次上课问这个问题,总有弄不清楚的。这里需要明白一个符号之间的优先级问题。

    “[]”的优先级比“*”要高。p1 先与“[]”结合,构成一个数组的定义,数组名为p1,int *修饰的是数组的内容,即数组的每个元素。那现在我们清楚,这是一个数组,其包含10 个指向int 类型数据的指针,即指针数组。

    至于p2 就更好理解了,在这里“()”的优先级比“[]”高,“*”号和p2 构成一个指针的定义,指针变量名为p2,int 修饰的是数组的内容,即数组的每个元素。数组在这里并没有名字,是个匿名数组。那现在我们清楚p2 是一个指针,它指向一个包含10 个int 类型数据的数组,即数组指针。我们可以借助下面的图加深理解:

    eca7f3293db5

    三、a 和&a 的区别

    ①通过上面的分析,相信你已经明白数组和指针的访问方式了,下面再看这个例子:

    main()

    {

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

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

    printf(“%d,%d”,*(a+1),*(ptr-1));

    }

    打印出来的值为多少呢? 这里主要是考查关于指针加减操作的理解。

    对指针进行加1 操作,得到的是下一个元素的地址,而不是原有地址值直接加1。所以,一个类型为T 的指针的移动,以sizeof(T) 为移动单位。因此,对上题来说,a 是一个一维数组,数组中有5 个元素; ptr 是一个int 型的指针。

    &a + 1,其中&a表示取数组a 的首地址,+1表示该地址的值加上sizeof(a) 的值,即&a + 5*sizeof(int),也就是下一个数组的首地址,显然当前指针已经越过了数组的界限。

    (int *)(&a+1): 则是把上一步计算出来的地址,强制转换为int * 类型,赋值给ptr。

    *(a+1),其中的a和&a 的值是一样的,但意思不一样!a 是数组首元素的首地址,也就是a[0]的首地址,&a 是数组的首地址,a+1 是数组下一元素的首地址,即a[1]的首地址,&a+1 是下一个数组的首地址。所以*(a+1)输出为2;

    *(ptr-1),其中因为ptr是指向已越界的a[5]的,并且ptr 是int * 类型,所以*(ptr-1) 是指向a[4] ,输出为5。

    ②现在再来看看下面的代码:

    int main()

    {

    char a[5]={‘A’,’B’,’C’,’D’};

    char (*p3)[5] = &a;

    char (*p4)[5] = a;

    return 0;

    }

    上面对p3 和p4 的使用,哪个正确呢?p3+1 的值会是什么?p4+1 的值又会是什么?毫无疑问,p3 和p4 都是数组指针,指向的是整个数组。&a 是整个数组的首地址,a是数组首元素的首地址,其值相同但意义不同。在C 语言里,赋值符号“=”号两边的数据类型必须是相同的,如果不同需要显示或隐式的类型转换。p3 这个定义的“=”号两边的数据类型完全一致,而p4 这个定义的“=”号两边的数据类型就不一致了。左边的类型是指向整个数组的指针,右边的数据类型是指向单个字符的指针。在Visual C++6.0 上给出如下警告:

    warning C4047: ‘initializing’ : ‘char (*)[5]‘ differs in levels of indirection from ‘char *’。

    还好,这里虽然给出了警告,但由于&a 和a 的值一样,而变量作为右值时编译器只是取变量的值,所以运行并没有什么问题。不过我仍然警告你别这么用。

    既然现在清楚了p3 和p4 都是指向整个数组的,那p3+1 和p4+1 的值就很好理解了。

    但是如果修改一下代码,会有什么问题?p3+1 和p4+1 的值又是多少呢?

    int main()

    {

    char a[5]={‘A’,’B’,’C’,’D’};

    char (*p3)[3] = &a;

    char (*p4)[3] = a;

    return 0;

    }

    甚至还可以把代码再修改:

    int main()

    {

    char a[5]={‘A’,’B’,’C’,’D’};

    char (*p3)[10] = &a;

    char (*p4)[10] = a;

    return 0;

    }

    这个时候又会有什么样的问题?p3+1 和p4+1 的值又是多少?

    四、地址的强制转换

    先看下面这个例子:

    struct Test

    {

    int Num;

    char *pcName;

    short sDate;

    char cha[2];

    short sBa[4];

    }*p;

    假设p 的值为0×100000。如下表表达式的值分别为多少?

    p + 0×1 = 0x___ ?

    (unsigned long)p + 0×1 = 0x___?

    (unsigned int*)p + 0×1 = 0x___?

    我相信会有很多人一开始没看明白这个问题是什么意思。其实我们再仔细看看,这个知识点似曾相识。一个指针变量与一个整数相加减,到底该怎么解析呢?

    还记得前面我们的表达式“a+1”与“&a+1”之间的区别吗?其实这里也一样。指针变量与一个整数相加减并不是用指针变量里的地址直接加减这个整数。这个整数的单位不是byte 而是元素的个数。所以:p + 0×1 的值为0×100000+sizof(Test)*0×1。至于此结构体的大小为20byte,前面的章节已经详细讲解过。所以p +0×1 的值为:0×100014。

    (unsigned long)p + 0×1 的值呢?这里涉及到强制转换,将指针变量p 保存的值强制转换成无符号的长整型数。任何数值一旦被强制转换,其类型就改变了。所以这个表达式其实就是一个无符号的长整型数加上另一个整数。所以其值为:0×100001。

    (unsigned int*)p + 0×1 的值呢?这里的p 被强制转换成一个指向无符号整型的指针。所以其值为:0×100000+sizof(unsigned int)*0×1,等于0×100004。

    上面这个问题似乎还没啥技术含量,下面就来个有技术含量的:在x86 系统下,其值为多少?

    intmain()

    {

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

    int *ptr1=(int *)(&a+1);

    int *ptr2=(int *)((int)a+1);

    printf(“%x,%x”,ptr1[-1],*ptr2);

    return 0;

    }

    下面就来分析分析这个问题:

    根据上面的讲解,&a+1 与a+1 的区别已经清楚。

    ptr1:将&a+1 的值强制转换成int*类型,赋值给int* 类型的变量ptr,ptr1 肯定指到数组a 的下一个int 类型数据了。ptr1[-1]被解析成*(ptr1-1),即ptr1 往后退4 个byte。所以其值为0×4。

    ptr2:按照上面的讲解,(int)a+1 的值是元素a[0]的第二个字节的地址。然后把这个地址强制转换成int*类型的值赋给ptr2,也就是说*ptr2 的值应该为元素a[0]的第二个字节开始的连续4 个byte 的内容。

    其内存布局如下图:

    eca7f3293db5

    好,问题就来了,这连续4 个byte 里到底存了什么东西呢?也就是说元素a[0],a[1]里面的值到底怎么存储的。这就涉及到系统的大小端模式了,如果懂汇编的话,这根本就不是问题。既然不知道当前系统是什么模式,那就得想办法测试。大小端模式与测试的方法在第一章讲解union 关键字时已经详细讨论过了,请翻到彼处参看,这里就不再详述。我们可以用下面这个函数来测试当前系统的模式。

    int checkSystem( )

    {

    union check

    {

    int i;

    char ch;

    } c;

    c.i = 1;

    return (c.ch ==1);

    }

    如果当前系统为大端模式这个函数返回0;如果为小端模式,函数返回1。也就是说如果此函数的返回值为1 的话,*ptr2 的值为0×2000000。如果此函数的返回值为0 的话,*ptr2 的值为0×100。

    demo注释:https://github.com/byczd/CPointerArray

    展开全文
  • 定义字符数组定义时直接初始化,下面例子中直接将字符串123456的首地址赋值给a char a[6]=“123456”; 需要注意的是,在定义之后,不可以在对a数组使用字符串直接初始化,如下 char a[6]; a = "123456" a是一个静态...

    1.定义字符数组定义时直接初始化

    定义字符数组定义时直接初始化,下面例子中直接将字符串123456的首地址赋值给a

    char a[6]=123456;
    

    需要注意的是,在定义之后,不可以在对a数组使用字符串直接初始化,如下

    char a[6];
    a = "123456"
    

    a是一个静态数组,在C语言中其在编译期间为一个常量表达式,而常量表达式可以当做是常量来使用,所以不能对于a进行指针赋值操作,既然这样是错误的,这么对于字符数组进行赋值呢

    2.字符数组单个字符的赋值操作

    最简单的方法是通过for循环,使用数组下标方式或指针方式,来对字符数组进行赋值。
    例子:

    char a[10];
    char ch=1;
    for( i=0;i<10;i++ )
        a[i]=ch+i ; //可通过数组下标引用数组元素,完成赋值
    
    char *p;
    for(p=a; p<a+10; p++ )
        *p=ch++; //通过指针对数组相应元素赋
    

    3、字符串赋值

    实际上,可使用string.h头文件中的字符串操作函数进行赋值,那就是memcpy/strcpy或者sprintf,此memcpy 和 strcpy 的区别,后者只适用 string - 字符串,copy 数目大小由源string中的 '\0'来决定;而memcpy适用于所有类型,且由第三个参数决定 copy 的长度。函数原型为:

    char *strcpy(char *dest, const char *src)
    void *memcpy(void *dest, const void *src, size_t n)
    int sprintf( char *buffer, const char *format, [ argument]);
    

    例子:

    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        char a[10];
        strcpy(a, "123456");
        printf("%s\n", a);
        sprintf(a, "%s", "1234567");
        printf("%s\n", a);
        memcpy(a, "12345678", 8);
        printf("%s\n", a);
       
       return 0;
    }
    

    结果:

    123456
    123456
    12345678
    
    
    展开全文
  • 学了这么多年的C语言,突然发现连字符赋值都出错,真的很伤心。char a[10];怎么这个数组赋值呢?1、定义的时候直接用字符赋值char a[10]="hello";注意:不能先定义再赋值,如char a[10]; a[10]="hello";...
  • C语言字符串,数组

    2015-04-01 11:01:56
    c语言字符数组与字符串的使用详解 1、字符数组的定义与初始化 字符数组的初始化,最容易理解的方式就是逐个字符赋给数组中各元素。 char str[10]={ 'I',' ','a','m',' ',‘h','a','p','p','y'}; 即10个字符...
  • 一个字符串可以赋值给一个字符数组,只要不定义这个字符数组的长度就行 例如: char a[]=“Hello” 此时存在数组里面,也是一个字符一个位,不包括双引号 如果要输出时 就用strlen()计算数组的长度 然后用个for...
  • 问不能用赋值语句将一个字符串常量或字符数组直接一个字符数组赋值。“ 那么str1=“China”是不是错的? char a[ ]=‘toyou’; 为什么是正确的呢? 举例如下: char s[20];s=“helo”;这样是错误的,原因就是不能...
  • C语言中的字符数组

    千次阅读 2018-08-27 00:01:31
    一看博客标题好像是在说字符数组的,实际上在C语言中,字符数组包括字符数组字符数组数组知识并不是很难的知识,但是一些细节问题需要注意,繁琐的概念问题不在过于强调,只强调一些易错易忽视的一些问题;...
  • 二维数组实质上也就是一维数组,a[2][3]可看做一个2个元素的一维数组,这2个元素又是另一个数组,在内存中,它的排布如下: #include "stdio.h"int main(int argc, char *argv[]){char a[2][3]={{1,3,9},{2,4,8}};...
  • C语言总结第七章、数组一维数组一维数组的定义一维数组的引用一维数组的初始化程序举例二维数组及多维数组二维数组的定义二维数组元素的引用二维数组元素的初始化程序举例字符数组字符字符数组 第七章、数组 ...
  • C语言中,将字符串作为字符数组来处理。C语言规定了一个“字符串结束标志”,以字符‘\0’代表。也就是说,在遇到第一个‘\0’字符时,表示字符串结束,由它前面的字符组成字符串。 一、字符数组字符串常量...
  • 在采用字符串方式后,字符数组的输入输出将变得简单方便。除了上述用字符串赋初值的办法外,还可用scanf函数和printf函数一次性输入输出一个字符数组中的字符串,而不必使用循环语句逐个输入输出每个字符。要输出一...
  • 怎么这个数组赋值呢? 1、定义的时候直接用字符赋值 char a[10]="hello"; 注意:不能先定义再赋值,如char a[10]; a[10]="hello";这样是错误的! 2、对数组中字符逐个赋值 char a[10]={'h','e','l','l'...
  • 怎么这个数组赋值呢? 字符数组字符赋值的三种可行形式: 1、定义的时候直接用字符赋值 char a[10]="hello"; 【注意】不能先定义再赋值,如char a[10]; a[10]="hello";这样是错误的,一个字符怎么...
  • 29.1.C语言没有原生字符串类型 29.2.C语言字符串的本质 29.3.字符串指针和字符串本身 29.4.字符数组字符串初始化与sizeof及strlen 29.5.字符数组字符串的本质差异
  • 1、数组在定义时, ...2、单字符赋值 可通过数组下标方式或指针方式,引用数组元素,进行赋值。 例子: char a[10]; char ch=‘a’; for( i=0;i<10;i++ ) a[i]=ch+i ; //可通过数组下标引用数组元素,完成赋
  • 原创 C语言字符数组字符串指针数组 ...
  • C语言字符数组字符串指针数组

    万次阅读 多人点赞 2019-04-27 21:46:19
    1,首先,不论是局部,静态还是全局数组都必须在定义的时候初始化,否则就得通过其他方式,eg 循环操作,字符串处理函数strcpy() 2,附以下代码: 主要完成将”I am from china ”倒置为”china from am I”, ...
  • 例子1:这里我们看到,在为int a赋值的时候我们需要取a的地址对其赋值 void mian() { int dwCount; int* a = &dwCount; scanf("%d", a); } 例子2:这里我们换成一个指针,对指针int* a赋值,则不需要加取...
  • c语言字符串和字符数组的区别

    万次阅读 多人点赞 2018-08-19 11:55:05
    在函数中定义一个字符串,char *s = "asdfgh",相当于在代码段申请了7个连续的...char * s,并将这7个字节组成的这段内存的首地址赋值给s,即将字符'a'的内存地址赋值给s。 在函数中定义一个字符数组,ch...
  • C语言 字符数组赋值

    千次阅读 2018-05-29 09:24:00
    /给数组字符串/ . . . } 上面程序在编译时, 遇到char s[30]这条语句时, 编译程序会在内存的某处留 出连续30个字节的区域, 并将第一个字节的地址赋s。当遇到strcpy( strcpy 为 Turbo C2.0的函数)时, 首先在目标...
  • C语言基础知识:字符数组赋值 链接: link. 字符数组字符赋值的三种可行形式: 1、定义的时候直接用字符赋值 char a[10]=“hello”; 2、对数组中字符逐个赋值(list initialize) char a[10]={‘h’,‘e’,‘l’,...
  • 学了这么多年的C语言,突然发现连字符赋值都出错,真的很伤心。 char a[10]; 怎么这个数组赋值呢? 1、定义的时候直接用字符赋值 char a[10]="hello"; 注意:不能先定义再赋值,如char a[10]; a[10...
  • char a[3];...这样是会报错的,因为数组名相当于数组的首地址,这个操作相当于对数组的首地址赋值,所以会报错。 #include <string.h> char a[3]; strcpy(a, "xxx"); 用strcpy函数就可以实现。
  • C语言中实现字符数组

    千次阅读 2014-02-13 10:38:04
    C语言中实现字符数组 C++中实现字符数组很容易,定义一个string类型的数组就可以了。但在C语言中由于没有string这个类型实现起来就要麻烦些。以下我提供一种利用指针数组实现的方法,其实质也就是个二维字符...
  • c语言二维数组如何初始化1 有两种方法(1)在定义时可以直接赋值来初始化(2)在定义后可以为其元素一个个来赋值2 示例1234567891011121314151617181920212223242526272829#include《stdio.h》void display(int arr[2]...
  • c语言 一维字符数组

    千次阅读 2018-03-06 10:03:42
    什么是一维字符数组:char a[5];...如何来一维字符数组赋初值?1)一维字符数组从“整体上看”就是一个字符串,但是其中的每一个元素还是一个字符2)关于字符串的结束符号\0 A:\0虽然有2个字符,但是\...
  • C语言中没有字符串类型,字符串是存放在字符数组中,所以一般形式的字符串就是数组。 一般来说,大家都是使用sizeof来计算数组长度的: // 整型数组 int a[] = {1,2,3,4,5}; int length = sizeof(a)/sizeof(a...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 87,520
精华内容 35,008
关键字:

c语言怎么把字符赋值给数组

c语言 订阅