char p[] = "hello world"; -称为A定义方式
char * p = "hello world"; -称为B定义方式
两个p的区别
分两种情况:
1
这个p是全局变量(通俗点就是在函数外面定义的)
那么这两种方式, 产生的效果有点相同的地方:
A:使用A定义方式, 只分配了 sizeof(p) == sizeof("hello world") == 12 字节的内存
(字符串长度为11, 加上一个字节的结束符号)
p是这段内存的开始地址, 他不是实际的指针变量,所以 p = p+1; 这类的操作,连编译都通过不了。
B:使用B定义方式,字符串分配了 sizeof("hello world") == 12
的内存,除了这之外还分配了sizeof(p) == sizeof(void *) 的内存(一个指针的内存一般是4或8字节)
p是一个指针, 它存的值是这个字符串的开始地址。 所以 p++; p = "shit"; 这类的操作都是合法的。
但是如果B方式没有修改p指针的指向,这两种方式使用p都能够获取到字符串"hello world", 产生是一样的错觉,其实差别很大。
但是有一点是相同的: 相同的字符串 "hello world" 会存放在全局变量存放的地方。
2
这个p是局部变量(通俗点就是在函数内部定义的)
那么这两种方式, 产生的效果就会有很大的不同:
A:使用A定义方式, 只在stack(栈)中分配了12字节的内存
p是这段内存的开始地址, 他不是实际的指针变量,所以 p = p+1; 这类的操作,连编译都通过不了。
而且只能在函数内部使用p,函数返回后,p这块内存值就是非法的了
B:使用B定义方式,也是在全局变量区分配了 sizeof("hello world") == 12的内存,
除了这之外还在stack(栈)中分配了一个指针的内存
p是一个指针, 它存的值是这个字符串的开始地址。 所以 p++; p = "shit"; 这类的操作都是合法的。
但是只能在函数内部使用p