C Language Fundamentals: Pointers and Arrays

First, the relationship between pointers and arrays        

        In fact, there is no essential difference between a pointer and an array variable. A pointer variable is an array variable, and an array variable is also a pointer variable. Why do you say that? Let's take a look at the above code, define an array array and a pointer p pointing to the address of the first element of the array, and assign the array variable directly to a pointer variable p1:

int array[4] = { 0, 1, 2, 3 };
int *p = &array[0];
int *p1 = array;
for (int i = 0; i < 4; i++)
{
    printf("%d %d %d\n", array[i], p[i], p1[i]);
}

0 0 0
1 1 1
2 2 2
3 3 3

       From the running results, we can see that there is no difference between the defined pointers and arrays. The locations of these three variables in memory are as follows

       

        For the above program, we need to explain that int *p = &array[0]; means assigning the address of the first element in the array variable to the pointer variable p, and int *p1 = array; means assigning the array The value of the variable is assigned to the p pointer p21. The results of these two statements are the same, because the value of the array variable in the C language is the address of the first element in the array, which is the first address of the array. Note: array is an address, which represents the first address of the array, and &array[0] represents the address of the first element of the array, which is also the first address of the array, so these two The value of the address is the same. For pointer type variables p and p1, what they represent is an address, so we can use the method of fetching array elements to perform array element operations on this pointer, such as p[0], p[1], [2] And statements like p1[0], p1[1], p1[2] are all legal. Similarly, we know that the ampersand is to take the address of the variable, and * is to take the variable of the pointer address, so *p represents the value of the variable of the first element in the array, for example, the value of *p is 0.

 

2. Arithmetic operations on pointers

        在上面例子中我们已经知道了指针与数组的关系接下来我们来看一看指针的四则运算。指针变量与其它变量一样,也可以进行四则运算,但通常我们只对指针做加法和减法运算。例如我们可以将指针先指向一个数组,然后再对其做加法运算

char array[6] = "hello";
char *p = array;
printf("%c", *p);
printf("%c", *(p + 1));
printf("%c", *(p + 2));
printf("%c", *(p + 3));
printf("%c", *(p + 4));

hello

        我们来分析一下上面例子中指针变量的运算过程,由于p是一个指针型变量,它指向了一个数组,也就是说p这个指针变量中存放了一个内存地址,这个地址就是数组array首个元素的地址,也就是array[0]的地址,对指针进行p+1操作时, p+1表示的也同样是一个指针,它指向数组中第二个变量array[1]。同理当执行p+2时,p+2也表示一个指针,它指向的是是array[2],p+3指向array[3]。p+4指向array[4]。因为它们都表示的是指针,所以我们可以对它们做取变量操作,也就是使用 * 来根据它们所指向的地址取出这些变量。上面程序还可以使用循环来实现:

char array[6] = "hello";
char *p = array;
for (int i = 0; i < 5; i++)
{
    printf("%c", *(p + i));
}

hello

        我们使用变量i来对指针做加法运算,然后再通过循环将其显示出来。我们现在再通过数组与指针在内存中的关系来看看这一过程:

        同样的,我们也可以对指针p做++操作,从而达到指向下一个数组元素的目的。例如我们使用针指来实现一个字符串拷贝的功能:

char source[6] = "hello";
char target[6];
char *s = source;
char *t = target;
while (*s != '\0')
{
    *t++ = *s++;
}
*t = '\0';
printf("%s\n", target);

hello

        对于上面的例子我们一定要注意运算符的优先级,什么时候加小括号,什么时候不加括号。

        注意:在C语言中对指针的加减实际上是对指针类型占用字节数的加减。也就是说,对于字符型指针的+1表示指针增加一个的字节的地址;而对于short型的指针+1表示增加2个字节的地址;对于int型的地址对其+1表示增加4个字节的地址等等。

        另外,通常情况下我们只能对指针变量做加法和减法操作,而其它的运算是不可以用在指针变量上的,例如我们不能直接对指针变量做乘法和除法运算,但可以通过使用类型转换的办法将其转为一个整数,对其做完运算之后再将其转为指针变量。有兴趣的读者可以参见《C语言深处》

        关于指针的减法与加法类似,这里不再赘述。


欢迎关注公众号:编程外星人

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325691199&siteId=291194637