博文

[转载][教程] C/C++指针简易教程(2008-03-19 11:10:00)

摘要:原帖请看:http://yzfy.org/bbs/viewthread.php?tid=710&extra=page%3D1
《对函数调用的深入探讨》:http://yzfy.org/bbs/viewthread.php?tid=688&extra=page%3D1

  首先声明,这篇文章是给那些学完了指针,但是对指针的使用和实质还存在疑问的朋友。
如果你根本就没有学过指针,请先去参考一下几本经典的教材,再来看本文。
因为在这里将不会解释操作符的用法。
  
  有人说,C的精髓在于指针,掌握指针的使用就掌握了C语言。当然这种说法不一定严谨,
但毕竟突出了指针的重要性,也导致了一些初学者“谈指针色变”,避指针唯恐不及,
生怕一不小心就用错导致莫名其妙的问题。那么指针是什么呢?指针的本质又是什么呢?
因为Q群里面很多人都在问相类似的问题,这里发一个指针的教程,希望对大家有帮助。
  
  在讲指针之前,我们先说说类型转换。对类型转换完全了解的人可以跳过这一部分,
直接看指针,但是还是建议大家看看,说不定会对你有所帮助呢。
  
  无论是C还是C++,类型转换都是比较难的。何谓类型转换?从一种类型转换位另一种类型是也!
C++是强类型语言,而C要宽松一些,所有的强类型语言都会有类型转换的操作,
因此看完这里大家就可以举一反三,对Java等等其他语言的类型转换有比较深的了解。
  
  类型转换分为两种,一种是隐式类型转换,一种是显式类型转换。这里举一个例子:


int a=8.0/3;

.
  8.0是double类型(C规定,程序中出现的任何无后缀小数都为double类型,
而出现的任何无后缀整数都为int型,在写程序时一定要记住),而3是int型。
除法运算可否在两种不同类型的变量之间进行呢?显然是不行的。因此,这里就需要转换。
  
  我们知道,double型可表示的范围远远大于int型。而C和C++在这类转换中的原则就是,
范围小的类型向范围大的类型转换。所以,3被转换成了double值3.0,然后做除法。
  
  8.0/3.0=......

阅读全文(3312) | 评论:0

为何数组名是指针常量(2008-03-16 12:09:00)

摘要:看了《C和指针》一书后了解到,当程序编译的时候, 数组的内存就已经分配好了,此时如果想要改变指针值,因为数组各元素的地址是连续的,那么就得将整个数组进行移动,因为数组名是指针常量,不能做左值。......

阅读全文(2585) | 评论:0

将getchar()获取的字符不赋任何变量时,这个字符它会被丢到哪(2008-03-16 12:01:00)

摘要:之前在书上看到,说是在调用有返回值的函数时其返回值会先放到寄存器中,然后再由寄存器来赋值给变量。于是我觉得,getchar()获取的字符不赋任何变量时,那么这个字符就不会赋值给任何变量,而且当再出现需要来调用该寄存器时,该寄存器中的值就会被顶掉。......

阅读全文(1626) | 评论:0

关于结构体中的"对齐"的目的(2008-03-16 11:44:00)

摘要:看汇编时发现了这么一句话:

"...同一个地址即可以看作字节单元的地址,又可以看成字单元、双字单元或4字单元的地址,这要根据使用情况确定。字单元的地址可以是偶数也可以是奇数。但是,在8086和80286中,访问存储器(要求取数或存数)都是以字为单位进行的,也就是说,机器是以偶地址访问存储器的,这样,对于奇地址的单元,要去一个字需要访问两次存储器,当然这样花费的时间多。在8086及其以后续的32位处理机中,双字节单元地址为4的整数倍数时访问存储器的速度可以较快.同样,4字单元的地址为8的倍数时访问速度更快..."

看了这句话后我就在想,结构体中的'对齐'是不是就是因为这个而产生的。后来多亏论坛上各路朋友的帮忙答疑,证实了我的看法,"对齐"目的确实是为了减少取指令次数,提升速度,代价是耗费较多的空间。 并且请他们的回帖中还了解到,结构体中的“对齐”其实是“补白”,而真正的对齐(alignment)其实是语言本身要求的,比如C/C++规定对齐很多时候处于类型转换等考虑的,具体情况请看C99和C++2003标准。这个对齐对于多数系统一般而言8字节足够。......

阅读全文(2274) | 评论:0

在一个C/C++群里的搞笑发言(2008-03-15 22:36:00)

摘要:  Q群里的人聊的很是火热,说了很多程序方面的小问题,群主(群创建人)间群里都挺专业的,于是突然发言说那位自认为学得好的话请说话(估计意思是想让他以后多多代代大家),突然间群里没人说话了!持续了好几分钟。 太搞笑了......

阅读全文(2832) | 评论:0

将数倒置(如123倒置后321)的方法(2008-03-13 21:36:00)

摘要:自己弄着玩呢。
不为实用,只为能用 我的分析如下:
  1的倒置数为10,那么10与1的差恰好是9,而任意一个两位数,如13与它的倒置数31的差恰好是9的整倍数。
  于是,如输入2385,用千位减个位所得到的值乘以9后保存到一个临时变量temp中,与此同时将个位与千位组成一个新数,即25,之后再将25加到temp中,最后将temp中的十位加到2385的2上,个位加到5上。于此类似,2385的十位与百位也是同样的操作。
  注明:如果所输入的数的对称两位,如上例中的4位数其个位与千位对称,十位与百位对称,相同则可不做操作而直接进行下一对称的两位;若最高位大于个位则执行减法。

以上就是我的想法,尽管,很显然这个方法根本没什么效率,也不严禁,但我仍想发上来让大家帮忙看看有没有什么缺陷。......

阅读全文(2486) | 评论:0

<算法 i~iv>-4.11(2008-03-09 17:13:00)

摘要://///////////////////////////////////////////////////////////
//  <算法 i~iv>
// 
//  Exercise : 4.11  , Page : 103
//
//  exercises description:
//   给定两个序列,给出算法来判断是否可以在序列中插入星号,
//  使得第一个序列可以生成第二个序列.生成规则由练习4.10来解释.
//
//         zhaoyg 2008.3.5
///////////////////////////////////////////////////////////// #include <stdio.h>
#include <stdlib.h>
#include <string.h> #define MAX 20 int main()
{
 int source[2][MAX];
 int (*p_source)[MAX]=source;  int target[MAX];
 int *p_target=target;  int lenth_between_sur_tar=0 , count_lenth_source=0 ,temp;
 int i , j , end ,count=0;  //printf("enter source string\n");  while (1)
 {
  lenth_between_sur_tar=0 , count_lenth_source=0 ;
  printf("enter source string\n");
  while((temp=getchar())!='\n')
 &......

阅读全文(1637) | 评论:0

<算法 i~iv>-3.43(2008-03-09 17:12:00)

摘要:////////////////////////////////////////////
//  <算法 i~iv>
// 
//  Exercise : 3.43  , Page : 75
//  exercise description:
//   实现一个程序,互换一个双向链表中两个给定的节点的位置.
//  
//  P.S: 对于相邻节点尚未考虑,还需几行代码即可
//  zhaoyg   2008.2.
////////////////////////////////////////////
#include <iostream> using namespace std; const int times = 10; struct node 
{
 int item;
 node *prev;
 node *next;  node (int value , node *p , node *n)
 {
  item = value;
  prev = p;
  next = n;
 }
}; void creat_node(node **head,int times);
void test_list(node *temp);
void transposition(node **head,int item_1,int item_2);
void free_list(node *head); int main()
{
 node *head = NULL;
 node *temp;
 int item_a,item_b;  cout <<"请输入需要交换节点的位置,用空格分隔\n当前链表中共有"<<times<<"个节点"&l......

阅读全文(1765) | 评论:0

<算法 i~iv>-3.41(2008-03-09 17:10:00)

摘要:////////////////////////////////////////////
//  <算法 i~iv>
// 
//  Exercise : 3.41  , Page : 75
//  exercise description:
//   实现程序3.11的一个使用头节点的版本
//  
//   P.S : 有时候不使用哑元节点确实麻烦
//  zhaoyg   2008.1.24
////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime> using namespace std; struct node
{
    int item;
    node *next;
   
    node(int x,node *t)
    {
        item=x;
        next=t;
    }
}; int main()
{
 ofstream outf;
 outf.open("result.txt");     node *head_a=NULL;
    node *a=NULL , *t;
    node *temp;  srand(......

阅读全文(2078) | 评论:0

<算法 i~iv>-3.35(2008-03-09 17:08:00)

摘要://////////////////////////////////////
//  <算法 i~iv>
// 
//  Exercise : 3.35  , Page : 75
//
//  exercises description:
//   编写一个函数,重新排列一个链表.使偶数位置的节点集中到链表后半部分,奇数位置节点集中
// 到链表前半部分,同时分别使奇数位节点和偶数位节点之间的顺序保持不变.
//
//  zhaoyg  2008.1.22
//////////////////////////////////////
#include <iostream>
using namespace std; struct list
{
    int content;
    list * next;
}; void fun (list * head); int main()
{
    list *head = NULL,*current,*temp;
    int value;
   
    cout << "enter value,q to quit\n";
   
    while (cin >> value)
    {
        if (head==NULL)
            current = head = new list;
   &nbs......

阅读全文(1830) | 评论:0