C语言char指针数组wsklan[0]与wsklan[0][0]地址差异及puts用法疑问
C语言指针数组相关问题解答
问题1:地址差异与字符串存储逻辑
两个地址不同的原因
你的猜测完全正确,二者本质是完全不同的内存区域地址:
&wsklan[0]取的是指针数组wsklan第一个元素本身的内存地址:wsklan是存储20个char*类型指针的数组,每个元素本身占指针大小的内存(32位系统占4字节、64位系统占8字节),&wsklan[0]就是这个指针变量在栈上的存储地址。&wsklan[0][0]取的是**wsklan[0]指向的字符串第一个字符的内存地址**:wsklan[0]里存储的值是data[0]的首地址,也就是二维数组data第一行的起始位置,所以这个地址对应实际存储字符的内存区域。
简单来说,前者是「装指针的盒子的地址」,后者是「盒子里存的地址指向的内存位置」,自然不会相等。
字符串存储与连续性问题
你测试代码里的字符串存储在二维数组char data[20][300]中,这个数组的内存布局是固定的:每一行固定占用300字节,data[0]占0~299字节的位置,data[1]紧接着占300~599字节的位置,以此类推。
所以你输入的onetwo存在data[0]开头,后面跟着\0结束符,剩下的290+字节都是data[0]的预留空间,第二个字符串threefour存在data[1]的开头,和第一个字符串之间隔了几百字节的空位,不会连续排布。如果需要两个字符串连续存储,需要用一维字符数组手动分配空间。
问题2:puts参数的差异原因
puts函数要求传入的参数是char*类型,指向要输出的字符串的首字符地址:
wsklan[1]的类型是char*,它的值是data[1]的首地址,完全符合puts的参数要求,所以可以正常运行。wsklan作为数组名会隐式转换为char**类型的指针,指向wsklan[0]的位置;wsklan+1的类型仍然是char**,指向wsklan[1]这个指针变量本身的地址,不是指针指向的字符串地址,类型不匹配,传入puts会触发未定义行为(大概率段错误)。
如果你想通过指针偏移的方式实现和puts(wsklan[1])等价的写法,可以写为puts(*(wsklan+1)),解引用char**得到char*类型的字符串地址即可正常运行。
内容的提问来源于stack exchange,提问作者tetektoza
相关产品推荐
相关产品推荐

