<深入理解C指针>学习笔记和总结 第四章 指针和数组

数组是一个什么玩意:

数组和指针我的理解,有相同之处也有不同之处。因有相同之处,因此一些资料上说,数组和指针本质是相同的。因有不同之处,因此也有一些资料上说,数组和指针是不一样的。

相同之处:

数组名字和指针名字都代表了一个地址。

如:int num[10];num是数组名。函数开辟了一个存储十个整数类型的空间,而num是他们的首地址。

int *p;

p=(int *)malloc(10*sizeof(int));类似的,p也指向了首地址。

不同之处是,num[10]中的空间位置是在栈中,而 ×p指向的空间是在堆中。

p可以指向别的地址(即p可以进行指针运算。是一个变量)但是num不可以运算,是一个常量。

一维数组与指针数组:

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

引用的时候:printf("%d",num[i]);

int *num2[5]={&n1,&n2,&n3,&n4,&n5};

引用的时候:printf("%d",*num[i]);

二维数组:

int num[i][j];

可以用malloc创建数组:

int *pv=(int *)malloc (5*sizeof(int));

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

p[i]=i+1;//*(p+i)=i+1;

指针的一维数组:

int *arr[5];

int i;

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

{

arr[i]=(int *)malloc(sizeof(int));

*arr[i]=i;

}

或者:

*(arr+i)=(int *)malloc(sizeof(int));

**(arr+i)=i;

第二种分析: (arr+i)表示数组第i个元素的地址。我们需要修改这个地址中的内容,因此用了×(arr+i)而 arr+i的内容是一个指针,指向一个内存。因此再此解引。返回的是所分配内存的位置。

二维数组的传递:

以2.c为例子。虽然是二维数组,但是 在函数中,是以一维数组来使用的。因为声明中就是一维数组。所以在子函数中无法以arr[i][j]的方式来使用数组里的内容。只能用

arr+偏移量 然后解引的方式: *(arr+(i*cols)+j)

也可以动态分配二维数组:

int rows2;

int columns=5;

int **matrix=(int **)malloc(rows*sizeof(int *));//类型是二维数组。里面的每一个元素是一个整形指针。

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

{

matrix[i]=(int *)malloc(colums*sizeof(int));//每一个元素都指向一个整形一维数组。

}

该方式类似于参考 字符串指针的表示方式。

代码示例:

1//指针数组:

#include <stdio.h>

int main(void)

{

int* num1[3];

int num2[3]={1,2,3};

int i;

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

num1[i]=&num2[i];

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

printf("%4d",*num1[i]);

putchar(‘\n‘);

return 0;

}

2/二维数组的表示:

#include <stdio.h>

void arr_initial(int *arr,int rows,int cols)

{

int i,j;

int num=1;

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

for(j=0;j<cols;j++)

{

*( arr+(i*cols)+j)=num++;

}

}

void arr_print(int *arr,int rows,int cols)

{

int i,j;

int num=1;

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

{for(j=0;j<cols;j++)

{

printf("%4d",*( arr+(i*cols)+j));

}

putchar(‘\n‘);

}

}

int main(void)

{

int num1[5][6];

int num2[7][8];

arr_initial(&num1[0][0],5,6);

arr_print(&num1[0][0],5,6);

arr_initial(&num2[0][0],7,8);

arr_print(&num2[0][0],7,8);

return 0;

}

<深入理解C指针>学习笔记和总结 第四章 指针和数组

时间: 2024-10-12 19:39:52

<深入理解C指针>学习笔记和总结 第四章 指针和数组的相关文章

apue学习笔记(第十四章 高级I/O)

本章涵盖了从多概念和函数:非阻塞I/O.记录锁.I/O多路转换.异步I/O.readv和writev函数以及存储映射I/O 非阻塞I/O 非阻塞I/O使我们可以发出open.read和write这样的I/O操作,并使这些操作不会永远阻塞.如果这种操作不能完成,则调用立即返回出错. 对于一个给定的文件描述符,有两种为其制定非阻塞I/O的方法: 1.如果调用open获得描述符,则可制定O_NONBLOCK标志(第三章) 2.对于已经打开的一个描述符,则可调用fcntl,由该函数打开O_NONBLOC

流畅python学习笔记:第十四章:迭代器和生成器

迭代器和生成器是python中的重要特性,本章作者花了很大的篇幅来介绍迭代器和生成器的用法. 首先来看一个单词序列的例子: import re re_word=re.compile(r'\w+') class Sentence(object):     def __init__(self,text):         self.text=text         self.word=re_word.findall(text)     def __getitem__(self, item):   

C++ Primer 学习笔记_57_类与数据抽象 --管理指针成员

复制控制 --管理指针成员 引言: 包含指针的类需要特别注意复制控制,原因是复制指针时只是复制了指针中的地址,而不会复制指针指向的对象! 将一个指针复制到另一个指针时,两个指针指向同一对象.当两个指针指向同一对象时,可能使用任一指针改变基础对象.类似地,很可能一个指针删除了一对象时,另一指针的用户还认为基础对象仍然存在.指针成员默认具有与指针对象同样的行为. 大多数C++类采用以下三种方法之一管理指针成员: 1)指针成员采取常规指针型行为:这样的类具有指针的所有缺陷但无需特殊的复制控制! 2)类

现代C++学习笔记之一入门篇:智能指针(C++ 11)

原始指针:通过new建立的*指针 智能指针:通过智能指针关键字(unique_ptr, shared_ptr ,weak_ptr)建立的指针 在现代 C++ 编程中,标准库包含智能指针,该指针用于确保程序不存在内存和资源泄漏且是异常安全的. 在现代 C++ 中,原始指针仅用于范围有限的小代码块.循环或者性能至关重要且不会混淆所有权的 Helper 函数中. 1 void UseRawPointer() 2 { 3 // Using a raw pointer -- not recommended

C和指针 学习笔记-4.函数

参数传递: 参数传递采用按值传递 ADT&黑盒 ADT:abstract data type,抽象数据类型 c可以用于设计与实现抽象数据类型,因为它可以限制函数和数据定义的作用域,这种技巧也称为黑盒设计 user.h #define MAXLEN 3 struct UserClz { char *name; char *phone; char *address; }; typedef struct UserClz User; /* *接函数 *通地名称查找地址 */ char const * l

C和指针 学习笔记-3.数组与指针

数据名代表首地址 指向数组的指针 #include <stdio.h> extern void iterate(int *p); void main(){ int a[]={1,2,3,4,5}; iterate(a); } void iterate(int *p){ int i; for(i=0;i<5;i++){ printf("%d",*p++); } } 指向一维数组的指针 int (*p)[3] #include <stdio.h> void i

C++学习笔记31,指向引用的指针(3)

我们来看一个简单的指向引用的指针的例子. #include <iostream> using namespace std; int main(){ int x=10; int y=20; int &rtx=x; //不要写成了int& *ptrx=&rtx; //因为rtx的本质是一个int int *ptrx=&rtx; *ptrx=15; ptrx=&y; rtx=y; cin.get(); } 依次单步执行:(注意rtx值的变化和ptrx的变化)

数组与指针学习笔记

1.数组初始化说明 (1).在函数体外定义的内置数组,其元素均被初始化为0: (2).在函数体内定义的内置数组,其元素无初始化: (3).类类型的数组自动调用默认构造函数进行初始化,如果无默认构造函数,则必须为该素族元素提供显示初始化. 2.指针的定义 double *p_dbData1, p_dbData2; p_dbData1为指向double类型的指针,p_dbData2为类型为double的对象,若两个变量都定义为double指针,则如下所示: double *p_dbData1,  *

马程序员学习笔记——红黑树解析四

---------------------- ASP.Net+Unity开发..Net培训.期待与您交流! ---------------------- 本篇是将上面三篇的理论知识转化成代码,java实现 首先,看一下算法导论里的伪代码 一.左旋 The pseudocode for LEFT-ROTATE assumes that right[x] ≠ nil[T] and that the root's parent is nil[T].(伪代码的左旋方法中假设X的右孩子不为空) LEFT-