C/C++中char* 与char []定义的区别

本文详细解释了C/C++中指针和数组指针的区别,包括如何修改指针指向的地址、栈内存管理和常量字符串的概念。

转载请注明来自souldak,微博:@evagle


C/C++初学者很可能会以为这两个是一样的,其实如果不需要去修改字符串的话,那它们的效果的确是一样的。那它们的区别到底在哪儿呢?

char* s1="abc"; s1是一个指针,这个指针可以被修改,它可以指向新的地址。现在它指向的是字符串常量“abc”,字符串常量存储在constant section里,不可被修改。如果修改内容,比如s1 = "ddf", 其实修改的并不是“abc”这个内容,而是将s1指向了新的地址空间。利用printf("%p", s1); 可以查看s1的地址改变。

char s2[10]="abc"; s2是数组指针,指针指向的位置就是数组的第一个元素所在的位置,一经分配是不能被修改的了。然后它的空间是在栈里面分配的,当前存储的是字符串"abc",它的内容是可以被重新修改赋值的。例如s2[0]='F';就可以将第一个字符改成F。

char* p=s2; p和s1是一样的,可以指向s2指向的地址,所以数据在栈里面,所以p是可以修改字符串的。


Summary:

char* s1="abc"; 是指针可以被修改,指向的字符串常量不可以修改。

char s2[10]="abc"; abc是在栈里面,数值可以被修改。但是s2作为数组指针不能指向其他地址空间。

char* p=s2; p是和s1一样的指针,可以指向其他地址,因为给它赋值为s2,所以当前指向的区域是可以被修改的。如果再让p="dfg"; 那p就变成和s1一样了。



### C++中 `char* argv[]` `char **argv` 的区别和用法 在C++中,`char* argv[]` 和 `char **argv` 是两种表示字符串数组的方式,但它们在语法和语义上有一些细微的差别。以下是两者的详细分析: #### 1. 定义含义 - **`char* argv[]`** 这是一种数组的形式,表示一个由字符指针组成的数组。每个元素都是一个指向字符(`char`)的指针,通常用于存储命令行参数的字符串。例如,`argv[0]` 是程序名,`argv[1]` 是第一个参数,依此类推[^6]。 - **`char **argv`** 这是一个指向字符指针指针。它也可以用来表示一个字符串数组,但它更像是一种动态分配的指针结构,而不是固定的数组形式。`argv` 指向的是一个包含多个 `char*` 的地址[^7]。 #### 2. 使用场景 - **`char* argv[]`** 在函数参数列表中使用时,`char* argv[]` 实际上会被编译器转换为 `char** argv`,因此两者在实际使用中几乎等价。例如,在 `main` 函数中: ```cpp int main(int argc, char* argv[]) { // 或者写作 char** argv for (int i = 0; i < argc; ++i) { std::cout << argv[i] << std::endl; } return 0; } ``` 在这里,`argv` 是一个指针数组,每个元素指向一个字符串。 - **`char **argv`** 当需要动态分配或操作字符串数组时,`char **argv` 更加灵活。例如: ```cpp #include <iostream> using namespace std; int main() { char *strings[] = {"Hello", "World", "C++"}; char **argv = strings; // 将数组转换为指针 for (int i = 0; i < 3; ++i) { cout << argv[i] << endl; } return 0; } ``` #### 3. 内存模型 - **`char* argv[]`** 这是一个静态定义的数组,其大小在编译时确定。每个元素是一个 `char*` 类型的指针,指向一段内存区域(通常是字符串常量)。 - **`char **argv`** 这是一个指针变量,可以指向动态分配的内存区域。例如: ```cpp char **argv = new char*[3]; argv[0] = new char[6]; strcpy(argv[0], "Hello"); argv[1] = new char[5]; strcpy(argv[1], "World"); argv[2] = new char[3]; strcpy(argv[2], "C++"); for (int i = 0; i < 3; ++i) { cout << argv[i] << endl; } // 清理内存 for (int i = 0; i < 3; ++i) delete[] argv[i]; delete[] argv; ``` #### 4. 注意事项 - 在传递给函数时,`char* argv[]` 和 `char **argv` 是等价的,因为数组名在函数参数中会退化为指针。 - 如果需要修改字符串内容,应确保字符串不是只读的。例如,直接修改字符串字面量会导致未定义行为: ```cpp char *str = "Hello"; // 字符串字面量是只读的 str[0] = 'h'; // 错误:尝试修改只读内存 ``` --- ### 示例代码 以下是一个完整的示例,展示如何使用 `char* argv[]` 和 `char **argv`: ```cpp #include <iostream> using namespace std; void printArgs(char** args, int count) { for (int i = 0; i < count; ++i) { cout << args[i] << endl; } } int main(int argc, char* argv[]) { cout << "Using char* argv[]:" << endl; for (int i = 0; i < argc; ++i) { cout << argv[i] << endl; } cout << "\nUsing char **argv:" << endl; char *strings[] = {"Example", "String", "Array"}; char **args = strings; printArgs(args, 3); return 0; } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值