指针数组和数组指针

简介: 一、指针和数组的区别二、指针数组和数组指针

指针数组和数组指针

 

目录

一、指针和数组的区别

二、指针数组和数组指针

 

 

一、指针和数组的区别


1、例:计算一个字符串里面的字符个数,打开Oracle VM VirtualBox软件,输入代码,

代码如下:

#include <stdio. h>

int main( )

{

char str[] = "I love FishC. com!";

int count=0;  定一个变量用来计算这个字符的个数

while (*str++ != '\0' )  

{

count++ ;

}

Printf("总共有%d个字符!\n",count );  打印结果

return 0;

}

[fishc@localhost s1e23]$ vi test1.c

[fishc@localhost sle23]$ gcc test1.c && ./a. out

test1.c: In function ' main' :

test1.c:8: error: lvalue required as increment operand指针运算符的操作对象操作数必须是一个左值。

[fishc@localhost sle23]$

 

2、str必须是一个lvaluestr是数组的名字,数组名是不是左值呢?

从定义上来看,C语言的术语Ivalue指用于识别或定位一个存储位置的标识符。

( 注意:左值同时还必须是可改变的)数组名定义的就是数组的位置,数组名是不可修改的,它是一个地址常量,字符串的地址,所以要对代码进行修改,

 

修改后的代码如下:

#include <stdio. h>

int main( )

{

char str[] = "I love FishC. com!";

Char *target=str; 指向字符串

int count=0;  

 

while (*target++ != '\0' )  target进行处理,这是一个复合语句,复合表达式,操作数有两个运算符对它进行作用,一个是自增运算符,一个是取值运算符,运算符的优先级,自增运算运算符比取值运算符高一个级别,

 

所以先运算target++,后缀运算符有一个特性,作用效果要在下一条语句才会显示,虽然是自增,但是这一句还是使用target本身的值,取*target值跟\0匹配,是否等于字符串的结束符,如果不是就加1,如果是就退出循环,再下一次碰到的时候,target++后的结果,以此类推,计算出总共有多少个字符

{

count++ ;

}

Printf("总共有%d个字符!\n",count );  

return 0;

}

[ fishc@localhost s1e23]$ gcc test1.c && ./a. out

总共有17个字符!

 

 

3、最后可以从这个程序看出指针变量跟字符串名字有什么区别?同样都是指向地址,但是指针变量是一个左值,字符串名字是地址常量,不是左值,因为++运算符要对target进行赋值,必须是可改变的,target本身指向1++后指向2,再++指向3,如此反复。

 

4、结论:数组名只是一个地址,而指针是一个左值。

 

二、指针数组和数组指针


1、指针数组是数组,数组指针是指针。


2、例:int *p1[5];int (*p2)[5];哪个是指针数组,哪个是数组指针?

 

1int *p1[5]是指针数组

从运算符的优先级和结合性入手,定义同时有取值运算符和下标运算符作用于变量p1,数组下标比取值运算符级别高,所以p1[5]先结合,p1被定义为具有5个元素的数组,所以它是数组,数组类型不是整型,有*是指向整型变量的指针,所以在内存中的定义是每一个数组的元素,都是一个整型指针变量。

下标

0

1

2

3

4

元素

Int*

Int*

Int*

Int*

Int*

 

结论:指针数组是一个数组,每个数组元素存放一个指针变量。

指针数组如何初始化呢?代码如下:

#include <stdio . h>

int main( )

{

int a=1;

Int b=2;

int c=3;

int d=4;

Int e=5;

int *p1[5] = {&a, &b, &c, &d, &e];

int i;

for(i=0;i<5;i++)

{

printf("%d\n", *p1[i]);

}

return 0 ;

}

[ fishc@localhost s1le23]$ gcc test2.c && ./a . out

1

2

3

4

5

指向字符指针时的代码如下:

#incLude <stdio.h>

int main( )

{

char *p1[5] = {

"让编程改变世界--C工作室",

"Just do it--NIKE"

"一切皆有可能--李宁",

"永不止步--安踏",

"One more thing.. --苹果"

};

int i;

for(i=0;i<5;i++)

{

printf("%s\n", p1[i]);

}

return 0 ;

}

[ fishc@localhost s1le23]$ gcc test3.c && ./a . out

让编程改变世界--C工作室

Just do it--NIKE

一切皆有可能--李宁

永不止步--安踏

One more thing.. --苹果

 

2int (*p2)[5]是数组指针

从运算符的优先级来看,它们在同一级,所以从结合性来看,左到右,就是左边的先结合,p2先被定义为指针变量,指针变量的类型指向元素的类型,所以int定义的是数组元素的类型。

下标

0

1

2

3

4

元素

Int

Int

Int

Int

Int

 

结论:数组指针是一个指针,它指向的是一个数组。

 

数组指针如何初始化呢?

warning是它认为代码有问题,但还是会尊重程序员进行编译执行,error就是编译不成功,p2是一个指针所以要给它一个地址,编译器提醒,指针类型初始化不一致,数组名是数组第一个元素的地址,

 

正确代码如下:

#include <stdio. h>

int main( )

{

int temp[5] = {1, 2, 3, 4, 5};

int (*p 2)[5]=& temp;

 

指针指向的是数组一个的元素的地址,指向整型变量的指针,指向第一个元素,而不是数组,虽然数组第一个元素的地址等于数组名等于数组的地址,但是概念不同,数组的所有元素都是挨个存放的,当知道第一个元素的地址时,要变量它所有元素也是没有问题的。

 

所以这里不是要一个变量的地址,而是要一个真正的身份,数组把它当作一个整体,取出这个数组的地址,才是这个数组指针想要的内容。

int i;

for(i=0;i<5;i++)

{

printf("%d\n", *(*p2+ i)); *p2表示数组的地址,再+i是取出它的值

}

return 0 ;

}

[fishc@localhost s1e23]$ gcc test4.c && ./a. out

1

2

3

4

5

相关文章
|
1月前
|
C语言
指向结构体数组的指针
指向结构体数组的指针
13 2
|
1月前
|
存储 算法 C语言
通过指针引用数组元素
通过指针引用数组元素
20 0
|
1月前
|
C语言 C++
数组元素的指针
数组元素的指针
10 0
|
1月前
|
存储 C++
使用字符指针变量和字符数组的比较
使用字符指针变量和字符数组的比较
10 0
|
1月前
|
存储 C语言 C++
c语言从入门到实战——数组指针与函数指针
数组指针和函数指针都是指针类型,但是它们指向不同的数据类型。 数组指针:数组指针指向的是数组类型。 函数指针:函数指针指向的是函数类型。 数组指针和函数指针是C语言中的两种重要指针类型。数组指针指向一个数组,可以用来访问和修改数组中的元素;而函数指针则指向一个函数,可以用来调用该函数。两者在语法和用法上有所不同,需要仔细区分。正确理解和使用它们可以提高程序的效率和可维护性。
33 0
C4.
|
1月前
|
算法 安全 程序员
C语言中如何通过指针引用数组
C语言中如何通过指针引用数组
C4.
20 0
C4.
|
1月前
|
存储 算法 C语言
C语言的指针数组与多重数组
C语言的指针数组与多重数组
C4.
22 0
|
3天前
|
存储 人工智能 C++
【重学C++】【指针】详解让人迷茫的指针数组和数组指针
【重学C++】【指针】详解让人迷茫的指针数组和数组指针
25 1
|
3天前
|
存储 C语言
指针数组作为main函数的形参
指针数组作为main函数的形参
12 0
|
1月前
|
存储 程序员 C++
指针数组和多重指针
指针数组和多重指针
17 2