1.以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写
"abc",那么编译器帮你存储的是"abc\0"
2."abc"是常量吗?答案是有时是,有时不是。
不是常量的情况:"abc"作为字符数组初始值的时候就不是,如
char str[] = "abc";
因为定义的是一个字符数组,所以就相当于定义了一些空间来存放"abc",而又因为
字符数组就是把字符一个一个地存放的,所以编译器把这个语句解析为
char str[3] = {'a','b','c'};
又根据上面的总结1,所以char str[] = "abc";的最终结果是
char str[4] = {'a','b','c','\0'};
做一下扩展,如果char str[] = "abc";是在函数内部写的话,那么这里
的"abc\0"因为不是常量,所以应该被放在栈上。
是常量的情况: 把"abc"赋给一个字符指针变量时,如
char* ptr = "abc";
因为定义的是一个普通指针,并没有定义空间来存放"abc",所以编译器得帮我们
找地方来放"abc",显然,把这里的"abc"当成常量并把它放到程序的常量区是编译器
最合适的选择。所以尽管ptr的类型不是const char*,并且ptr[0] = 'x';也能编译
通过,但是执行ptr[0] = 'x';就会发生运行时异常,因为这个语句试图去修改程序
常量区中的东西。
记得哪本书中曾经说过char* ptr = "abc";这种写法原来在c++标准中是不允许的,
但是因为这种写法在c中实在是太多了,为了兼容c,不允许也得允许。虽然允许,
但是建议的写法应该是const char* ptr = "abc";这样如果后面写ptr[0] = 'x'的
话编译器就不会让它编译通过,也就避免了上面说的运行时异常。
又扩展一下,如果char* ptr = "abc";写在函数体内,那么虽然这里的"abc\0"被
放在常量区中,但是ptr本身只是一个普通的指针变量,所以ptr是被放在栈上的,
只不过是它所指向的东西被放在常量区罢了。
3.数组的类型是由该数组所存放的东西的类型以及数组本身的大小决定的。
如char s1[3]和char s2[4],s1的类型就是char[3],s2的类型就是char[4],
也就是说尽管s1和s2都是字符数组,但两者的类型却是不同的。
4.字符串常量的类型可以理解为相应字符常量数组的类型,
如"abcdef"的类型就可以看成是const char[7]
5.sizeof是用来求类型的字节数的。如int a;那么无论sizeof(int)或者是sizeof(a)都
是等于4,因为sizeof(a)其实就是sizeof(type of a)
6.对于函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通
的指针类型,如对于void func(char sa[100],int ia[20],char *p)
则sa的类型为char*,ia的类型为int*,p的类型为char*
7.根据上面的总结,来实战一下:
对于char str[] = "abcdef";就有sizeof(str) == 7,因为str的类型是char[7],
也有sizeof("abcdef") == 7,因为"abcdef"的类型是const char[7]。
对于char *ptr = "abcdef";就有sizeof(ptr) == 4,因为ptr的类型是char*。
对于char str2[10] = "abcdef";就有sizeof(str2) == 10,因为str2的类型是char[10]。
对于void func(char sa[100],int ia[20],char *p);
就有sizeof(sa) == sizeof(ia) == sizeof(p) == 4,
因为sa的类型是char*,ia的类型是int*,p的类型是char*。
分享到:
相关推荐
### 字符数组与字符指针详解 #### 一、字符数组与字符指针的基本概念 ...以上内容总结了字符数组与字符指针的基础知识,以及 `sizeof` 和 `strlen` 的用法和区别。这些知识点对于理解C语言中的字符串处理非常关键。
使用sizeof操作符时,字符数组和字符指针的结果也不同。例如: ```c char str[] = "This is a string."; char *strPtr = "This is a string."; ``` 对于str,sizeof(str)将会返回整个数组的大小,包括结束符'\0'。而...
### 字符数组与字符指针详解 #### 一、引言 在C语言中,处理文本数据时,经常需要使用到字符数组与字符指针。本文将详细介绍这两者的基本概念、区别及其用法,并通过具体实例帮助读者更好地理解和掌握。 #### 二、...
本文将深入探讨内存的堆分配和栈分配,以及字符数组、字符指针和`sizeof`运算符的相关知识。 1. **堆和栈分配** - **栈区**:栈由编译器自动分配和释放,用于存放函数参数值和局部变量。栈的操作遵循后进先出...
2. **段2**: 此段代码展示了如何使用 `print_char` 函数来打印字符指针数组中的内容。通过 `char *array[]` 定义了一个字符指针数组,并通过循环输出每个元素的内容。这里 `array++` 的操作使得 `array` 指向数组中...
(2)对于字符指针,如`char *str`,`strlen(str)`同样计算从指针指向的地址开始到'\0'的字符数。 3. `sizeof()`与 `strlen()`的区别 - `sizeof()`返回的是类型或变量的总字节数,包括数组的所有元素或者对象的...
例如,在WIN32平台上,`sizeof`操作符用于获取对象或类型所占的字节数,对于数组名,它返回的是整个数组所占的字节数,而对于指针变量,它只返回指针本身的字节数(通常为4或8字节)。 #### 1.2 数组名神似指针 ...
//p 为字符指针,指针的大小为定值,为 4 cout; i=sizeof(*p); //这是指 B[0]所占空间的大小 cout; //结果为 1 2. strlen() strlen()是一个函数,它返回字符串的实际长度,而不是所占空间的字节数。 (1) 针对...
`(2)用字符指针指向一个字符串,例如:`char* str="I love China";` 8. 字符串的输出 无论使用哪种表示方法,字符串的输出都可以使用printf("%s\n",str);%s表示输出一个字符串,给出字符指针变量名str。 字符...
总结一下,本文介绍了如何在C语言中使用自定义函数实现字符数组的复制,这涉及到对字符数组的理解,字符串的结束标志,以及如何遍历和操作字符数组。通过这个程序,我们可以更好地理解C语言中的字符串处理和内存管理...
此外,标准C库函数 `strcpy` 可以接受两个字符指针作为参数,但也可以直接使用数组名: ```cpp char str1[10] = "Hello"; char str2[10]; strcpy(str2, str1); ``` 这段代码将 `str1` 中的内容复制到了 `str2` 中...
虽然传递了数组`str1`,但在`arrayTest`函数内部,`sizeof(str)`只返回指针的大小,而非整个数组的大小。 #### 小结 通过对上述示例的理解,我们可以总结出以下几点: - 数组名在很多情况下可以被视为指向数组首...
在这个例子中,`concat`函数接收一个字符指针数组和数组长度,返回一个拼接后的字符串。 二维字符数组在很多场景下都有着广泛的应用,如命令行参数解析、文本处理、文件操作等。理解其工作原理并能灵活运用,是成为...
这里`sizeof(str)`返回的是整个数组的大小(10个字符的大小),而`sizeof(pStr)`返回的是指针本身的大小(通常是4或8字节,取决于系统)。这证明了数组名不是指针,而是具有特定含义的标识符。 **2. 数组名神似指针...
- `sizeof(str)`返回的是数组`str`的大小,即10个字符的大小。 - `sizeof(pStr)`返回的是指针变量`pStr`本身的大小,通常为4或8(取决于平台)。 再来看另一段代码: ```cpp #include #include int main() { ...
当我们将数组名用作表达式时,除了在特定的上下文(如sizeof运算符、取址运算符&或字符串字面量初始化数组)之外,数组通常会“退化”为指向其首元素的指针。这意味着,尽管`s`在语法上不是一个指针,但在大多数情况...
字符串的表示形式有两种:一是通过字符数组,二是通过字符指针。第一种,如`char str[] = "I love China"`,数组直接存储字符串。第二种,如`char *str = "I love China"`,这里的`str`是一个指向字符数组的指针,它...
在C语言中,数组是一种非常重要的数据结构,它允许存储一系列具有相同类型的元素。...在深入学习C语言指针时,还会涉及到二级指针、指针数组、字符串指针、函数指针等各种复杂情况,这些都需要逐步学习和实践。
在C语言中,字符数组的名称实际上是指向数组第一个元素的指针,但这并不意味着它等同于字符串指针。数组名是一个标识符,而不是实际的内存地址,因此不能像指针那样进行地址运算。这一点在处理字符数组和字符串时...