- 一维数组
1.1数组名
int a;
int b[ 10 ];
我们把变量a称为标量,因为它是个单一的值。我们把变量b称为数组,因为它是一些值得集合。下标和数组名一起使用,用于标识该集合中某个特定的值(元素)。每个特定的值都是一个标量,可以用于任何可以使用标量数据的上下文环境中。
b[4]的类型是整型,那么数组名b的类型是什么呢?
在C中,数组名是一个指针常量,也就是数组第1个元素的地址。
程序在完成链接后,内存中数组的位置是固定的,所有当程序运行时,再想移动数组就为时已晚了。因此数组名的值是一个指针常量。
数组名不用来表示指针常量的2种情况
- sizeof( b )——返回整个数组的长度
- &b——是一个指向数组的指针,而不是一个指向某个指针常量值的指针
int *c;
c = &a[0];
c是一个指针变量,存放的是地址。和普通变量用法一样,只是存放的值不同。指针变量c被赋值为a指针常量。
所以上面那条语句等效于 c=a;
1.2下标引用
在前面声明的上下文环境中,下面这个表达式是什么意思?
*(b+3)
b的值是一个指向整型的指针,所有3这个值根据整型的长度进行调整。加法运算的结果是另一个指向整型的指针。它所指向的是数组第一个元素往后移3个整数长度的位置。然后,间接访问这个新的位置(或取得那里的值)。
array[ subscript]
*( array + ( subscript ))
这两个表达式是等同。这说明了 “除了优先级不同,下标引用和间接访问完全相同”。下标引用优先级高于间接访问。
1.3数组和指针
声明一个数组时,编译器将根据声明所指定的元素数量为数组保留内存空间,然后再创建数组名,它的值是一个常量,指向这段空间的起始位置。
声明一个指针变量时,编译器只为指针本身保留内存空间,不会为任何整型值分配内存空间。而且,指针变量未被初始化时指向任何现有的内存空间。如果他是一个自动变量,它根本就不会被初始化。
1.4字符数组的初始化
- charmsg1[] = "Hello ";
- char *msg2 = "Hello";
1.5指针数组
除了类型之外,指针变量和其他变量很相似。正如你可以创建整型数组,你也可以创建指针数组。
eg:
int *api[ 10 ];
char const *keyword[] =
{
"do",
"for",
"if",
"while",
NULL
};
这里,我们在表的末尾加上一个NULL指针,这个NULL 指针使函数在搜索这个表示能够检测到表的结束,而无需事先知道表的长度。
int lookup_keyword(charconst* desired_word,char const*keyword_table)
{
charconst *kwp;
for(kwp= keyword_table; kwp != NULL;kwp++)//遍历循环表中的每个单词
{
if( strcmp( desired_word,*kwp) == 0)//如果这个单词和目标单词匹配,就返回它在表中的位置
return kwp-keyword_table;
}
return -1;//没有匹配到,返回-1
}
补充:
当数组名作为函数参数传递是,实际传递给函数的是一个指向数组第1个元素的指针。函数接收到的形参是实参的的一份拷贝,所有函数可以对其修改而不会影响实参。但是,对指针参数进行间接访问会修改实际数组的元素。数组形参既可以声明为数组,也可以声明为指针。这两种形式只有当它们作为函数的形参才是相等的。
- intstrlen (char*string);
- intstrlen (charstring[]);