1.https://blog.youkuaiyun.com/weixin_34128237/article/details/91711327
一、函数的参数
1.C语言所有参数均以“传值调用”方式进行传递,这意味着函数将获得参数值的一份拷贝,这样,函数可以放心修改这个拷贝值,而不必担心会修改调用程序实际传递给它的参数。
2.如果被传递的参数是一个数组名,并且在函数中使用下标引用该数组的参数,那么在函数中对数组元素进行修改实际上修改的是调用程序中的数组元素。函数将访问调用程序的数组元素,数组不好被复制,这种行为被称为“传址调用”
整数交换:无效版本
void swap( int x, int y )
{
int temp;
temp = x;
x = y;
y = temp;
}
为了访问调用程序的值,你必须向函数传递指向你希望修改的变量的指针。接着函数必须对指针使用简介访问操作,修改需要修改的变量。
void swap( int *x, int *y )
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
因为函数期望接受的参数是指针,所以我们可以这样调用它:
swap ( &a, &b );
以前我曾傻乎乎写下下面这段代码,并认为是正确的:
void swap( int *x, int *y )
{
int temp;
temp = x;
x = y;
y = temp;
}
但后面发现,x,y虽然表示的是地址,但是它们为常量,不能当作左值,即不能被赋值。
二.数组
1.数组名的值是一个指针常量,也就是数组第一个元素的地址
2.array[subscript]
*(array + (subscript) )这两个表达式等效
3.数组和指针的区别:
声明一个数组时,编译器将根据声明所指定的元素数量为数组保留内存空间,然后再创建数组名,它的值是一个指针常量,指向这段空间的起始地址;
声明一个指针时,编译器只为指针本身保留内存空间,并不为任何值分配内存空间。
4.声明数组参数
形参实际是个指针,这就是为什么函数形参中,一维数组形参无需写明它的元素数目,因为函数并不为数组参数分配内存空间,下面两个表达等效,指针更好
int strlen(char *string);
int strlen(char string[]);
5.初始化
当数组的初始化局部于一个函数时,你应该仔细考虑一下,在程序的执行流每次进入该函数时,每次都对数组重新初始化是否值得,如果是否定的,就把数组声明为static,这样数组的初始化只需在程序开始前执行一次
6.自动计算数组长度
int vector[] = {10, 20, 30, 40, 50};
如果声明中未给出数组的长度,编译器就把数组的长度设置为刚好容纳所有的初始值的长度。如果初始值列表经常修改,这个技巧很有用
7.字符数组的初始化
char msg[] = {'H', 'e', 'l', 'l', 'o', 0};
char msg[] = "Hello";
上面是字符数组的初始化的两种形式
char msg[] = "Hello";
char *msg = "Hello";
这两个初始化看上去很像,但前者初始化一个字符数组,而后者则是一个真正的字符串常量。
8.存储顺序
int array[3][6];
在 C 中多维数组的元素存储顺序按照最右边的下标率先变化的原则,称为行主序。array[2][3]下一个元素是array[2][4]
9.数组名
一维数组名的值是一个指针常量,它的类型是“指向元素类型的指针”,它指向数组的第 1 个元素。多维数组也差不多。唯一的区别是多维数组第 1 维的元素实际上是另一个数组,也就是 一个指向数组的指针,这个很重要。
int matrix[3][10]
matrix这个名字的值是指向它第一个元素的指针,所以matrix是指向一个包含10个整形元素的数组的指针
10.下标
下标
int matrix[3][10];
matrix[1][5]; 下标引用实际上只是间接访问表达式的一种伪装形式,即使在多维数组中亦是如此。
matrix,它的类型是“指向包含 10 个整型元素的数组的指针”。
matrix+1,也是一个指向“指向包含 10 个整型元素的数组的指针”,但它指向 matrix 下一行。因为 1 这个值根据包含 10 个整型元素的数组长度进行调整,所以它指向 matrix 的下一行。
*(matrix+1),事实上标识了一个包含 10 个整型元素的子数组。数组名的值是个常量指针,它指向数组的第一个元素。它的类型是“指向整型的指针”,记住这个指针很重要,说明是个地址。
*(matrix+1)+5,刚刚说了 *(matrix+1) 是个指针,那么 +5,就是根据整型的长度进行调整。整个表达式结果是一个指针,它指向的位置比原先表达式所指向的位置向后移动了 5 个整型元素。
*(*(matrix+1)+5),作为右值,就是取得存储于那个位置的值;如果作为左值,这个位置存储一个新值。表达式等效为*(matrix[1]+5)----maxtrix[1][5]
11.指向数组的指针
int vector[10], *vp = vector; // 合法的
int matr[3][10]; *mp = martix; // 非法的
int (*p)[10]; 声明一个指向整型数组的指针。
int (*p)[10] = matrix; 它使 p 指向 matrix 第一个行。
p 是一个指向拥有 10 个整型元素的数组的指针。当把 p 与一个整数相加时,该整数首先根据 10 个整型值的长度进行调整,然后再执行加法。所以可以使用这个指针一行一行地在 matrix 中移动。
如果你需要一个指针逐个访问整形元素而不是逐行在数组中移动,下面以两种方式进行初始化,指向matrix的第一个整形元素
int *p = &matrix[0][0];
int *p = &matrix[0];