编程C本: 帖子 11 – 在C指针
1. 用C指针介绍
我们已经知道在过去使用的变量是确定的大小和数据类型变量. 他们称这种类型的变量是静态变量. 当你声明一个静态变量, 为可变数量的存储器单元将不使用其所有的存储单元或不的程序执行期间知道分配. 另一方面, 这种形式的静态变量将程序执行过程中存在的,尽管变化,该方案只使用 1 一次性.
一些限制可以使用静态变量时遇到:
- 分配存储单元的平衡, 造成浪费的存储单元.
- 缺少分配存储单元, 程序执行错误.
为了避免限制上, C语言为我们提供了具有以下特征的一个特殊的变量称为波动:
- 程序执行过程中才会出现,而不是产生在启动程序.
- 当运行程序, 变量的大小, 存储器和存储器地址被分配给该变量可以改变.
- 在完成使用它可以解放节省内存空间. 然而,变化并不涉及某些我将不能够访问它们. 因此, C语言为我们提供了一种特殊类型的变量又克服这个, 指针变量是 (指针) 与特点:
- 指针变量不包含包含该数据的地址数据或包含含有存储器的数据的地址.
- 指针的大小不依赖于数据的类型.
2. 指针
每个变量声明为已分配给 1 某些存储区,其中 (地址) 不同. 指针 变量 用来存储变量的地址.
2.1 例
// e.g about pointer - code by nguyenvanquan7826 #include <stdio.h> int main() { /* khai bao bien x va bien con tro px */ int x, *px; px = &x; /* &x : tra ve dia chi cua bien x * px = &x : gan dia chi cua bien x cho px hay px tro den x */ x = 42; printf("Vi tri cua bien x la %p \n", &x); printf("Noi dung cua bien x la %d \n", x); printf("Vi tri cua bien x la %p \n", px); printf("Noi dung cua bien x la %d \n", *px); *px = 7826; printf("\n -------- \n\n"); printf("Noi dung cua bien x la %d \n", x); printf("Noi dung cua bien x la %d \n", *px); return 0; }
结果:
结果:
记录X LA 42
六三CUA以及X 0x7ffe064348fc
记录X LA 42
--------
记录X LA 7826
记录X LA 7826
通过这个开放的例子,我们可以得出以下几点:
该. 声明游标变量
对于每种类型的数据,我们分别具有该类型的指针变量.
类型 * 名称指针;
在上面的例子中,我们声明 1 int类型PX的指针变量.
B. 指针调节指向了
我们使用操作 & 对于地址 1 变量,然后分配一个地址指针.
名称指针= &变量;
Ç. 如何访问
用光标像素以上的有 2 虽然是许可:
- PX : 获取地址,它保持 (点)
- *PX : 得到它指向的内存的值.
在上面的例子中可以看出,在分配之后 PX = &x; 那么我们写的:
- PX将相当于 &X
- *像素等价于x. 并且可以在计算*像素被用于, 表达.
ð. 对指针的一些操作
// e.g about pointer - code by nguyenvanquan7826 #include <stdio.h> int main() { /* khai bao bien x va 2 bien con tro px, qx */ int x, *px, *qx; px = &x; printf("Nhap gia tri cho vung nho px tro toi: "); scanf("%d", px); /* px la con tro nen khong viet scanf("%d", &px); */ qx = px; /* gan gia tri cua px cho qx, qx cun tro toi x*/ printf("Vi tri cua bien x la %p \n", &x); printf("Vi tri cua bien x la %p \n", px); printf("Vi tri cua bien x la %p \n", qx); printf("Noi dung cua bien x la %d \n", x); printf("Noi dung cua bien x la %d \n", *px); printf("Noi dung cua bien x la %d \n", *qx); // tang gia tri cua o nho len, <=> x = x + 7826 *px += 7826; printf("Noi dung cua bien x la %d \n", x); px++; /* cong them mot don vi cho px * => px tro toi vung nho tiep theo */ printf("Vi tri px tro toi la %p \n", px); return 0; }
结果:
输入海湾PX灰台岛值: 42
六三以及CUA X 0xbfba58a0
六三以及CUA X 0xbfba58a0
六三以及CUA X 0xbfba58a0
记录X LA 42
记录X LA 42
记录X LA 42
记录X LA 7868
六TRO排序PX你0xbfba58a4
对于例如,我们看到了一些操作后常见的指针: (除了许多其他操作).
- 2 相同类型的指针变量可以分配给彼此或整数执行公共会计, 减 2 指针每. 在上面的例子中,我们执行计算:
- 分配: Q X = PX; 当它接收到像素QX的值是变量x的地址, 即PX和QX并指着X. 此外,我们可以分配以下: Q X = PX + 2; 与QX, PX是一样的指针类型. 减法 2 相同类型的指针将返回 1 整数值 (INT). 这是距离 (一些元素) 之间 2 包括指针
- 增加: 许可证,以增加或减少, 减法是在同一个指针运算的变量进行. 唯一的区别在于,它的上升和下降, 加或减根据单个字节,它有类型.
首席执行官. 在上面的例子中,可以增加: PX ; 假定当该所指向的地址像素: 0xbfba58a0,然后使其增加其值是 (点的位置) 0xbfba58a4 (增加 4) 由于PX是int类型INT帐户的每个指针变量 4 在内存字节. - 此外,我们被允许通过* PX 数学改变变量x的值= 3; 在本质上,这操作是改变在存储器中的值 (地址) 该像素点, 这就导致了变量x的值根据改变.
你已经注意到了:
- 根据不同的编译器或操作系统是不同类型的能力. (这是int类型占翻译 4 字节,但在其他服务占用 2 字节). 对于每种类型的存储您使用的sizeof() 但在所有 2 提到.
- 另外,根据该操作系统的每个指针变量上, 不管是什么光标类型 (INT, 浮动, 双,...) 也占相同的字节数. 操作系统 32 位指针变量会计 4 字节, OS 64 位指针变量会计 8 字节.
3. 分配和恢复内存
该. 分配:
在此之前,一个小小的例子.
// e.g about pointer - code by nguyenvanquan7826 #include <stdio.h> int main() { int *px; *px = 42; printf("Vi tri con tro px la %p \n", px); printf("Gia tri con tro px tro toi la %d \n", *px); return 0; }
在编译时,它不会受益 (警告), 在运行时将无法运行该程序将退了出去.
其原因是,当游标变量声明像素新机只提供 2 字节来存储指针变量还没有为指针数据储存PX分配内存的地址. (类似的合作供应 2 大米为你做同样的,但不给你的土地你,镀金戒指公斤 ).
注意: 有一些编译器错误,但仍然无法正常运行,但最好的是,我们应该使用分配. 当您使用指针,我们将在后面讨论数组出现此错误最清楚.
好了,我们去的关键问题, 如何分配内存的指针.
为我们使用下面的函数库stdlib.h中指针分配内存.
- 的malloc : 游标名= (指针类型 *) 的malloc (的sizeof(指针类型));
- 释放calloc : 游标名= (指针类型 *) 的malloc (ñ, 的sizeof(指针类型));
在这种的sizeof(指针类型) 该类型的大小; n是的sizeof数(指针类型) 授.
// e.g about pointer - code by nguyenvanquan7826 #include <stdio.h> #include <stdlib.h> int main() { int *px, *qx; px = (int *) malloc(sizeof(int)); qx = (int *) calloc(1, sizeof(int)); printf("Vi tri con tro px la %p \n", px); printf("Gia tri con tro px tro toi la %d \n", *px); printf("Vi tri con tro qx la %p \n", qx); printf("Gia tri con tro qx tro toi la %d \n", *qx); return 0; }
在这里,您注意: malloc和释放calloc,你只需明白什么时候使用malloc分配之间的唯一区别分配机PX 1 细胞的任何细胞,而不知道什么数据或者没有数据 (* PX如此宝贵如上) 释放calloc,太多,但也有其他 1 点分配后,机器会自动总是赋值 0 该指可变QX存储器单元, 新闻QX默认值是 0.
当分配指针 1 我们缺乏的,需要分配更多的工作的过程中,一定量的存储单元中,我们使用命令 realloc的:
游标名= (指针类型 *) realloc的 (游标名, 分配到的量 * 的sizeof(指针类型));
在这: =量分配到旧 + 新.
首席执行官: 起初,我们分配的指针像素 10 存储单元.
然后它要分配更多 5 更多的存储单元,所述量分配= 15.
B. 恢复和检查剩余内存
要恢复我们使用的内存分配函数 免费(游标名);
3. 光标的功能
正如在所有 用C置换函数 我们知道如何传递参数,b在HoanVi功能是按值传递,而不是传递按地址 (或参数) 所以尽管函数变量的值发生了变化,但功能完成后,该值尚未改变. 而且,我们将通过传递参数形成光标和指针b键的交换可以在存储单元的地址被交换修改该. 而当我们得到想要的结果.
// e.g about pointer - code by nguyenvanquan7826 #include <stdio.h> void hoanVi(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } int main() { int a = 42, b = 7826; printf("Truoc khi goi ham hoan vi: a = %d, b = %d \n", a, b); hoanVi(&a, &b); printf("Sau khi goi ham hoan vi: a = %d, b = %d \n", a, b); return 0; }
你问自己 . 您对文档的指针或例子和数组不. 例如,阵列 10 光标或指针数组 10 元素!
谢谢
蔡所以它就像背着 2 鳍片战术. 你写的事故权利之前合作擦除鞭. 禁止将看到裸露的心脏
越南的内存分配 ,可以使用命令 : 指针=新的数据类型DC柯他
是的,但它是用C ++你啊
在%P他认为是什么
即变量打印的地址
如果你改变INT * INT像素 &PX不同那么他. 如果不同,他解释说DJC不帮我先生
谢谢!
为int * PX宣布当它是 1 声明变量结构指针, 而不必申报INT &PX.
为什么. 我认为初始化的人名单时,他们都宣称这种
无效khoitao(DS一,INT &ñ)
{
N = 0;
}
他是对还是错
阿那就是在函数中使用. 这样的声明时,它就像宣告* PX允许改变这个变量的值作为功能关闭. 但是,在C ++中,当此函数调用不传递到地址转变为只刚过功能.
你可以看到这个例如,以了解更多:
https://www.cachhoc.net/2014/12/12/lap-trinh-c-bai-6-ham/#VD3_Ham_hoan_vi
为什么指向他光标的规定.
这是用于光标控制该期间然后它指向一个存储单元的值…
谢谢
如果y = * Z这样TROG
y是变量
ž拉光标
金表示,帮助e为
@@ GI海不明白你
#定义PA_ODR *(无符号字符*)0X5000
这个问题的意思,你问什么是有序 ?
定义一个常量,命令
所以我用的参考 (CEO: 浮钳(浮动 &该 ) 定义函数做什么,他
所以下车后功能, giá trị của a có thể thay đổi. Ví dụ trước khi vào a là 5, sau khi vào hàm thì a là 9. Sau khi ra khỏi hàm a vẫn có giá trị là 9 chứ ko trở về 5.
dùng hàm trả về là 1 tham chiếu( CEO : INT & myfunc() )để làm gì vậy anh.!!! .em tks . em thấy mấy sách khai báo như vậy nhưng ko hiểu nó dùng làm gì ?
Cái này mình cũng chịu. Chưa dùng thử bao giờ 😉
có thể cho e vd về sử dung con trỏ kết hợp vs struct ko 🙂
你试试 2 bài này xem
https://www.cachhoc.net/2014/12/21/lap-trinh-c-bai-13-danh-sach-lien-ket-don-cai-bang-con-tro/
https://www.cachhoc.net/2014/12/19/lap-trinh-c-bai-11-kieu-cau-truc-struct/
一所军事学校这样做? 锡多少权?
第一线 6 在实施例 2 你给:
的printf(“输入海湾PX灰台岛值: “);
scanf函数(“%ð”, PX);
似乎喜欢这个:
的printf(“输入海湾PX灰台岛值: “);
scanf函数(“%ð”, *PX);
你能解释一下这个地方是不聪明????
因为光标PX PX电话始终DJK, 它像 &该. * Px活性也被称为它的价值就像调用.
他问我来检查大小的指针 2 如何先生咬.
例如检查INT您使用sizeof大小() . 但是当E使用的sizeof(P) 或的sizeof(*P) 未出 2 咬.
你好.
在文章e见的缺乏存储单元指针的提在工作过程中. 我们完全可以为孩子,但缺乏在工作的过程中,内存指针不是 ? 再加上他能告诉我更多关于你的函数释放callocñ阁先生帮我的角色 ?
例如,我们原本分配给 100 存储单元, 但需要保存后者金额超过 100 缺少.
n是存储器单元的数目需要分配.
为什么在一审中不应该分配内存的第一个例子 3 需要分配内存先生.
因为前面的例子中它被直接分配,那么你.
Sao không có nút like vậy bạn
pdest =的strstr( 串, 海峡 );
结果= (INT)(pDEST – 串 + 1);
他nguyenvanquan7826解释说,他们获得的供词儿童 2 星由字符串str返回三直流微型贷款
PSEST在香蕉叶葡萄串星毫安直流贷款定位彼此TRU
anh cho e hỏi. E也想创建一个博客网站就像一个位,所以,电子KH你的文章是如何与指令的介质,它有码. 一个可以显示E要成为KH… Ë已经知道PHP , CSS, HTML , Ë要撰写全力以赴,并保存到数据库完然后就加载thui是KH知道怎么说都只是写个帖子,如果有这样说明的代码…
你学习WordPress的NHE. 我用它.
你可以问问自己是占2字节指针到主存储器地址, 但是,例如该开口中,变量x的位置是0xbff327e4, 这个数字比大于2字节. 我还没有真正了解这个地方, 希望你能回答他们与恐惧
亲爱的,你可以到我INT * P1 =解释&X , INT ** P2 =&P1. 这意味着KO先生如何? INT * P1 =和&X是如int * P1 VS; P1 =&X先生没有? 谢谢
它被赋予x的地址指针P1, 地址分配P1到P2指针. 它张贴类似的人NHE.
服务员, 在实例 2 部2a我一个的分配, 显然他并没有分配一个值* PX, 注意底部他已经录制* PX宝贵如上. Ë索要程序的结果,这样弄出来什么,他? 和N在他释放calloc他的臀部适当的随机, 它有什么影响,如果我有更大的大小n他的臀部运行程序. Ë感谢先生
我说,该方案将出错. 此外n是您要的号码, 同 1 像其它像素为n 1. 如果测试部,该阵列具有n,n是阵列元件的数目.
他问我, 指针本身是可变, 所以它会有它自己的地址,并在内存存储单元. Vậy có thể dùng một con trỏ khác để trỏ tới địa chỉ của con trỏ kia được ko anh?
😀 Xin lỗi em chưa đọc kĩ mấy câu hỏi bên trên. Vậy cho em hỏi, khác nhau giữa con trỏ kiểu char với con trỏ của những kiểu kia là gì ạ. Như e thấy có thể khai báo: char *s={“abc xyz”}
nhưng không thể int *i={“1,2,3”} . 谢谢.
Con trỏ kiểu char cũng giống các con trỏ khác thôi. 但是,如果你读指针和数组,它将有链接, 字符指针,将被视为 1 字符阵列应被视为串.
有太多.
他问我该变量的地址指针光标的地址,不同的是它不 ?
例如,
INT A = 5;
INT * P;
P =&该;
的printf(“尾智天 : %P”,&该);
的printf(“\可变的NDIA费用是p指向%P”,P);
的printf(“\NDIA的姐姐P%p”,&P);
2 第一行是相同的,但在第二线 3 然后将其它值先生 ?? 我想他会回答你的问题 (((: .
除了你, 商店的p个地址,但它可以保存其地址在.
哥哥弟弟要求他们阅读的书籍,他们认为当我们声明 1 板是[2][3] 然后:
一个是的地址[0][0];
一个+ 1是一个地址[1][0];
一个+ 2是a的地址[2][0];
但是,当你使用%p来检查,因为它离任到+ 1点段的地址立即从后[2][3] 总是在你先生. 他与孩子们解释户, 谢谢
紧接着一[2][3] 元素?.
印刷%P电子测试 + 1
和%P &该[0][1] 见.
#包括 “stdio.h中”
#包括 “CONIO.H”
#包括 “文件math.h”
#包括 “文件string.h”
INT主要()
{
INT X = 5;
INT * P =&X;
的printf(“%d n”,*P);
P =(INT *)释放calloc(5,的sizeof(INT));
为(INT I = 0;在<5;我 )
*(P + I)= I + 1;
为(INT I = 0;在<5;我 )
的printf("%4d",*(P + I));
残培();
}
他问我这是什么代码是错误的,先生 ???
什么是错的,你跑起来是知道.
include thì dùng kí tự not “” va dùng hàm calloc thì phải khai báo hàm stdlib.h. vì hàm này hỗ trợ nó.
我跟他打招呼, 孩子们正处于一个困惑的问题, 我希望一点点时间解答来帮助你.
#包括
无效FUNC1(一个INT) {
INT x;
X = A;
的printf(“x的地址: %P, X =%d n”, &X, X);
}
无效FUNC2(一个INT) {
INTÿ;
的printf(“Y的地址: %P, Y =%d”, &和, 和);
}
INT主要() {
FUNC1(5);
FUNC2(8);
回报 0;
}
我运行这个程序,然后得到结果:
x的地址: 0x7ffeefc1a31c, X = 5
Y的地址: 0x7ffeefc1a31c, Y = 5
我想问的是,为什么地址和变量Y地址变量x的种类和价值的价值,虽然?
我也试过,但目前不明白为什么…
x的地址, Ÿ将返回该.
你可以看到校正它这一点, 我看不出有什么逻辑:
“指针的大小不依赖于数据的类型, 总有一个固定大小的 2 字节。”
据小姐, 你说指针无效 *. 这种变化取决于微控制器架构, 微处理器.
指针变量取决于它指向的数据的类型, 光标对应于存储器单元的地址的大小.
亲爱!
谢谢, 我已经纠正了NHE. 然而光标的大小总是相同的风格,虽然NHE.
另外,根据该操作系统的每个指针变量上, 不管是什么光标类型 (INT, 浮动, 双,...) 也占相同的字节数. 操作系统 32 位指针变量会计 4 字节, OS 64 位指针变量会计 8 字节.
他问我, 在他的身边声明 2 车削 , B,然后在他的下巴,使其 2 指针*一, *B. 我不明白那个地方长官, 他向我解释是不是, 谢谢
使用光标来保存变量的值之后你的下巴了. 如果不使用光标的功能,也不会保存变量,其中的值.
大家好, 我可以自己学习编程 1 这个月已经. 对于学习者来说,在cachhoc.net上的指针课程是相当模糊的, 无法显示光标之间的性质, 开启记忆.
我在daynhauhoc.com上有一份文件参考, 你可以搜索谷歌 “C用于新手编程文档” 找到那个工具包. 很容易理解, bạn học sẽ nắm rõ được bản chất và cũng rất hài hước khi học nữa 😀
Cảm ơn bạn đã chia sẻ.