【第21期】观点:人工智能到底用 GPU?还是用 FPGA?

数组与指针(一)

原创 2016年05月30日 13:34:56

数组和指针

数组:同类元素的集合

指针:存放地址的变量

(图解1)

wKiom1ZfGCWCDOYIAAAchuz7YRk996.png






&a和a的区别

&a:整个数组的地址

a:在降级使用时代表了数组首元素的地址,在sizeof和&的时候代表了整个数组

尝试:

char arr[10]={};

int *p=arr;

int *p=&arr;//左右两边的类型不同,编译不通过

int (*p)[10]=&arr;//指向数组的指针

_________________________________________________________________________________________________________________________

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

sizeof(arr): 5                   strlen(arr):5

sizeof(arr+1):4               strlen(&arr):5

sizeof(&arr):4                 strlen(&arr+1):随机数

sizeof(&arr+1):4            strlen(arr+1):4

sizeof(*&a):20//数组的地址,解引用之后指向整个数组相当于int (*p)[5]

###&a+1:跳过了整个数组 开始的位置在‘\0’的后面

__________________________________________________________________________________________________________________________

char *name="abcde";

sizeof(name): 4 (指针类型的大小)                 strlen(name):5

sizeof(name+1):4                                           strlen(&name):随机值(取的是指针的地址,从指针地址处开始寻找'\0')

sizeof(&name):4(二级指针的大小)                strlen(&name+1):随机数

sizeof(&name+1):4                                        strlen(name+1):4

数组和指针的访问方式

int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);
printf("%d %d",*(a+1),*(ptr-1));

输出结果:2 5

详解:*ptr指向整个数组之后的下一个元素,将它-1相当于退回4个字节指向数组元素5;

           值得注意的是char arr[]="abcde";      char *p=(char *)(&arr +1);再次访问*(p-1)时指向'\0',因为它是一个char型的指针,它只能回退1个字节!



变量的声明:不创建空间,只声明其他部位变量,使用其时引用同一块空间!

 eg:char arr[]="abcde"; 在另一文件中:extern char arr[]; printf("%s\n",arr);使用时仍然访问arr地址。

1.现在我们来将数组声明成一个指针

eg:char arr[]="abcde"; 在另一文件中:extern char *arr;   printf("%s\n",arr);这样的方式是不被允许的,arr是一个指针变量,编译器在找arr时只可以看到4个字节(指针的大小)。

      我们可以对指针arr取地址找到arr首址printf("%s\n",(char *)(&arr));

2.我们现在定义一个指针并将其声明为数组

eg:char *p="abcdef";在另一文件中:extern char p[]; printf("%s\n",p);

此时p存储的是‘a’的地址,所以p[]里存储了‘a’的地址而不是字符串!那么我们取出的%s其实是从a地址的第一个字节开始访问!

假设‘a’的地址:0018ff44  按照小端存储模式它在内存里是这样子的:44 ff 18 00 你取出44ff88遇到0相当于遇见'\0'停下

可以这样取出(char *)(*(int *)p)将其强制类型转换成整形,取出a的完整的地址,在强制类型转换成char*型的指针,此时它就已经相当于是一个指向数组的指针!

###由此可以总结出数组和指针是两种不同的类型!它们也并没有什么联系

参考书籍:《高质量C\C++编程》《C语言深度剖析》

变量的声明可以出现在多个地方,但定义只可以出现一次.

指针数组和数组指针

int q[10]     (含有10个整形元素的数组)            开辟40字节空间

int *p[10]    (含有10个整形指针的数组)           开辟40字节空间

int (*r)[10]  (指向一个大小为10的整形数组的指针)开辟4个字节空间     初始化:int(*r)[10]=&q;

int *(*w)[10](指向大小为10整形指针数组的指针) 开辟4个字节空间       初始化:int*(*w)[10]=&p;

eg:     char a[5]={'','','','',''};

          char(*p)[4]=&a;//错       除非强制类型转换char(*p)[4]=(char*)&a; 此时p+1向后偏移4个字节

           char(*p)[5]=a;//错

eg:     struct Test

           {

                  ...

            }*p;//指向结构体的指针

            atruct Test test;//假设p保存0x00000000 假设结构体为20字节

             p+0x1 = 0x00000014//指向大小20的结构体的指针+1等于向后偏移20字节

             (unsigned long)p+0x1 = 0x00000001//把指针强制类型转换成一个长整形,数字加一就相当于直接加一

             (unsigned int *)p+0x1 = 0x0000004//把结构体指针强制类型转换成一个int型指针,偏移4字节

int a[]={1,2,3,4};
int *p1=(int*)(&a+1);
int *p2=(int *)((int)a+1);
printf("%x %x",p1[-1],*p2);

详解:&a+1的位置是数组后面的一个字节空间p1[-1]向前退4 个字节

           (int )a+1将数组首址数字化加一就等于让p2从数组首址处向后偏移了一个字节的大小

             注意:我们取出的时候应该注意一下你的计算机是大端还是小端的存储方式,两种存储方式取出的数据是不一样的~

(图解2)

wKiom1ZfGGnjJCqsAAA0xsaSm5A212.png


利用联合完成大端小端的测试

     void check()
     {
          union UN//所有变量共用同一块空间,空间大小是最大成员的空间,联合成员一次只能使用一个
           {
               int c;//4字节
               char i;//1个字节
           }
           UN.c=1;
           if(UN.i==1)
               printf("little!");
          else
               printf("big!"); 
     }


版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

C语言:用指针访问数组元素:

任务代码: (如下) 执行情况: 知识总结: 知识点1:用指针访问数组元素: 单独输出数组的名字就是相当于输出数组首元素的地址!= 数组的名字代表数组首元素的地址 int a[10]={1,...

C语言 结构体相关 函数 指针 数组

. 作者 : 万境绝尘 <span style="color: #

数组指针的三种定义形式

//定义数组指针1 void main2201() { //定义一个数组数据类型 typedef int (MyArrayType)[5]; int i = 0; //用类型定义变量 MyArrayT...

C-数组指针(7)

利用指针间接修改数组元素与遍历数组元素 #include &lt;stdio.h&gt; void test(); void test1(); int main() { test(); test1(); return 0; } //利用指针修改数组元素 void test(){ int a[2];//d定义一个数组元素 //数组中 a相当于&amp;a[0

指针与数组

指针与数组的对比   C++/C程序中,指针和数组在不少地方可以相互替换着用,让人产生一种错觉,以为两者是等价的。   数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而...

从编译器角度分析C语言中数组名和指针的区别--转

从编译器角度分析C语言中数组名和指针的区别 数组名和指针是两个往往很容易让人们混淆的概念,很多人以为数组名就是一个指针,也有很多人知道数组名不同于指针但是仅知道数组名的值不能像指针一样改变,例如你可以写出下面这样的代码: int *p; p++; 却不能写这样的代码: int a[]; a++; 那么数组名跟指针之间到底有什么区别呢? 第一,在声明上,除了作为函数参数的数组名总是编译器转化成指针,其他情况下,数组名就是数组名,指针就是指针,二者不能混淆,你不能在一个文件中定义一个数组,而在另一个文件中把它声明成一个指针。 char a[]; //定义一个数组a  

指针与数组的基础知识分析

> 一级指针 > 二级指针 > 一维数组 > 二维数组 > 指针和数组的关系 > 指针数组 > 数组指针 > 函数指针

C语言之指针、数组和函数

基本解释  1、指针的本质是一个与地址相关的复合类型,它的值是数据存放的位置(地址);数组的本质则是一系列的变量。  2、数组名对应着(而不是指向)一块内存,其地址与容量在生命期内保持不变,只有数组的内容可以改变。指针可以随时指向任意类型的内存块,它的特征是“可变”,所以我们常用指针来操作动态内存。  3、当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针。   问题:指针与数组  听说char a[]与char *a是一致的,是不是这样呢?  答案与分析:  

数组和指针

一.数组和指针 int arr[5]; int *p; 首先要搞清楚数组是什么?数组表示相同数据类型的数的集合,arr[5]表示有5个整形元素的集合。 p是变量,对于变量可以理解为左值,编译器会开辟一...

C语法总结 数组和指针

  数组 #define N 10 int a[N]; for(int i=0;i&lt;N;i++) { a[i] = 0; } //初始化,没有被初始化到的数组下标就被设置为0 int a[1
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)