user-0 提问: 形参为指针数组，为何实参指针数组被改变

回复:
user: user-1
content: 你这里确实只是改变了指针指向,  因为你是一个二维指针啊. 每个字符串本身的保存地址中对应的内容并没有改变, 在你的程序中, 只是把字符串指针的排列顺序改变了.  传值与传址的区别, 你要记清楚.  你是直接使用传进来的值, 还是把传进来的值作为一个指针在使用, 有*或者[]的方式访问的地址内容.  (指的是修改)  如果直接使用的值, 那么主是值传递.  如果有 *或者[]的修改, 那就是传址调用.

user: user-0
content: 引用 13 楼 xiaohuh421 的回复:所谓的静态内存区无法改变, 只是一种建议,要求. 但实际上, 只要指针指向的地址有写权限, 那么就肯定能改变. 不幸的是, 静态存储区是在程序自己的空间内, 地址是完全的写权限的.   语法规定不能写, 但通过自动或者强制转换后, 仍然可以修改的.  哪怕它是const指定的那我的那个例子中，字符串是相当于互换了吗？书上说只改变了指针的指向并没有改变指针指向的字符串的值。谭浩强那本书有可能会有出错的地方，是不是他写错了

user: user-1
content: 所谓的静态内存区无法改变, 只是一种建议,要求. 但实际上, 只要指针指向的地址有写权限, 那么就肯定能改变. 不幸的是, 静态存储区是在程序自己的空间内, 地址是完全的写权限的.   语法规定不能写, 但通过自动或者强制转换后, 仍然可以修改的.  哪怕它是const指定的

user: user-0
content: 引用 6 楼 wyyy2088511 的回复:传一个数组名进来，改变数组的内容正常，只不过这里传的是指针数组，所以可以改变。指针指向的是字符串，字符串在静态内存区不是无法改变的吗

user: user-0
content: 引用 2 楼 d179212934 的回复:在这个例子中，你说传的是形参是指针数组，而不是指针所指向的变量。 我们所说的是形参的改变不影响实参，那么，如果你对该函数中的形参也就是指针进行修改，是不会影响到外面的实参指针。但是本例中，所修改的内容时指针所指向的内容！指针指向的内容是字符串，字符串分配在静态内存区，是无法修改的吧

user: user-0
content: 引用 3 楼 xiaohuh421 的回复:传址和传值,  楼主没有搞清楚. 如果你懂点汇编, 就知道, 所谓的值传递和地址传递, 其实都是在函数开始的地方, 把参数"值" push到堆栈中了. 而这个值, 可能是一个真数值,也可能是一个地址.  如果是地址, 那么这个地址你在函数内部把可重新指向, 但不影响外部, 相当于值传递, 但如果你通过这个地址, 修改了地址对应位置内存的值, 那么这个地址对应的内存中的数据就会真正改变了.  void swap(int *val1, int *val2) {     //交换指针指向的内存中的值      int temp = *val2;      *val2 = *val1;      *val1 = temp;           //交换指针变量     int *pT = val1;     val1 = val2;     val2 = pT; }  void main() {     int val1 = 10;     int val2 = 20;     int  *p1 = &val1;     int *p2 = &val2;    printf("val1=%d  val2=%d  p1=%p   p2=%p\n",val1,val2, p1,p2);     swap(p1,p2);     printf("val1=%d  val2=%d  p1=%p   p2=%p\n",val1,val2, p1,p2);     //交换后, 你会发现, val1,和val2的值交换了, p1和p2是没有变的. }  原因在上面已经说了. 对于p1,p2指针变量本身来说, 他们是值传递的,  只是对于val1和val2来说, 是传递的他们的地址.所以函数内部可以通过地址来修改它们的值.这个确实改变的是指针指向的整形变量的值，不过我的那个改变的应该是实参的指向，因为字符串分配在静态内存区是无法改变的啊

user: user-2
content: 引用 8 楼 zihui0459 的回复:[quote=引用 5 楼 cfjtaishan 的回复:] 这个并没有不是形参改变了实参，描述本身就有问题。形参就是一个变量，实参将值传递给形参，形参接收，这个动作并没有改变实参。而是函数里的逻辑改变了实参的值（地址值），所以描述还是要准确一些。 参数（形参）分为传入参数和传出参数。这个函数的形参，即作为该函数的传入参数，也做为这个函数的传出参数，即将实参的值带给函数，并修改实参的值，并将实参修改后的值反给调用函数，即传出参数。怎么看传出参数是什么呢？如果是交换两个指向int变量的指针swap（int*p1,int*p2） temp=p1; p1=p2;  p2=temp;肯定是换不了的，必须用*p1改变指针指向的变量的值，但是改变字符数组的那个，字符串是分配在静态内存区，字符串的值是没办法改变的啊[/quote] 字符串是分配在静态内存区？什么是静态内存区，你描述的是只读内存区？ 你的这个字符串排序，应该时字符串指针数组吧，指针数组交换每个元素指向的地址值，就可以改变它所指向的字符串。

user: user-0
content: 引用 5 楼 cfjtaishan 的回复:这个并没有不是形参改变了实参，描述本身就有问题。形参就是一个变量，实参将值传递给形参，形参接收，这个动作并没有改变实参。而是函数里的逻辑改变了实参的值（地址值），所以描述还是要准确一些。 参数（形参）分为传入参数和传出参数。这个函数的形参，即作为该函数的传入参数，也做为这个函数的传出参数，即将实参的值带给函数，并修改实参的值，并将实参修改后的值反给调用函数，即传出参数。怎么看传出参数是什么呢？如果是交换两个指向int变量的指针swap（int*p1,int*p2） temp=p1; p1=p2;  p2=temp;肯定是换不了的，必须用*p1改变指针指向的变量的值，但是改变字符数组的那个，字符串是分配在静态内存区，字符串的值是没办法改变的啊

user: user-0
content: 引用 1 楼 user-6 的回复:首先你要搞清楚到底传的什么参数。 指针传值时，参数是指针，而不是指针指向的量，此时在函数内对指针本身进行修改，是不会影响到外面的实参指针，但是如果函数内是对指针指向的量的修改，因为形参指针和实参指针都指向同一个量，自然会影响到该量的值。 char* name[]作为参数时，相当于二级指针 char **name，name是传值，对name的修改不会影响到外面的数组，但对name[i]以及*(name+i)的修改，就会影响到外面的数组。对name[i]的修改也不会改变字符串的值吧？字符串存储在静态内存区，不是无法改变的吗？谭浩强的书上说实参数组和形参数组是同一数组，改变了他们的指向，并没有改变字符串的值。但问题是为什么形参和实参是同一数组，这样说的话那为什么指向int变量的实参和形参不能像这样互换呢？

user: user-2
content: 这个并没有不是形参改变了实参，描述本身就有问题。形参就是一个变量，实参将值传递给形参，形参接收，这个动作并没有改变实参。而是函数里的逻辑改变了实参的值（地址值），所以描述还是要准确一些。 参数（形参）分为传入参数和传出参数。这个函数的形参，即作为该函数的传入参数，也做为这个函数的传出参数，即将实参的值带给函数，并修改实参的值，并将实参修改后的值反给调用函数，即传出参数。

user: user-3
content: http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

user: user-1
content: 传址和传值,  楼主没有搞清楚. 如果你懂点汇编, 就知道, 所谓的值传递和地址传递, 其实都是在函数开始的地方, 把参数"值" push到堆栈中了. 而这个值, 可能是一个真数值,也可能是一个地址.  如果是地址, 那么这个地址你在函数内部把可重新指向, 但不影响外部, 相当于值传递, 但如果你通过这个地址, 修改了地址对应位置内存的值, 那么这个地址对应的内存中的数据就会真正改变了.  void swap(int *val1, int *val2) {     //交换指针指向的内存中的值      int temp = *val2;      *val2 = *val1;      *val1 = temp;           //交换指针变量     int *pT = val1;     val1 = val2;     val2 = pT; }  void main() {     int val1 = 10;     int val2 = 20;     int  *p1 = &val1;     int *p2 = &val2;    printf("val1=%d  val2=%d  p1=%p   p2=%p\n",val1,val2, p1,p2);     swap(p1,p2);     printf("val1=%d  val2=%d  p1=%p   p2=%p\n",val1,val2, p1,p2);     //交换后, 你会发现, val1,和val2的值交换了, p1和p2是没有变的. }  原因在上面已经说了. 对于p1,p2指针变量本身来说, 他们是值传递的,  只是对于val1和val2来说, 是传递的他们的地址.所以函数内部可以通过地址来修改它们的值.

user: user-4
content: 传一个数组名进来，改变数组的内容正常，只不过这里传的是指针数组，所以可以改变。

user: user-5
content: 在这个例子中，你说传的是形参是指针数组，而不是指针所指向的变量。 我们所说的是形参的改变不影响实参，那么，如果你对该函数中的形参也就是指针进行修改，是不会影响到外面的实参指针。但是本例中，所修改的内容时指针所指向的内容！

user: user-6
content: 首先你要搞清楚到底传的什么参数。 指针传值时，参数是指针，而不是指针指向的量，此时在函数内对指针本身进行修改，是不会影响到外面的实参指针，但是如果函数内是对指针指向的量的修改，因为形参指针和实参指针都指向同一个量，自然会影响到该量的值。 char* name[]作为参数时，相当于二级指针 char **name，name是传值，对name的修改不会影响到外面的数组，但对name[i]以及*(name+i)的修改，就会影响到外面的数组。