当前位置:首页 » 编程语言 » c语言指针计算比分
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

c语言指针计算比分

发布时间: 2022-10-17 19:06:31

c语言 数组指针计算

在c语言中,当把数组名赋值给指针时,那么该指针指向数组的第一个元素,也就是该指针变量存放的是数组第一个元素的地址。所以
执行语句 int
a[5]={1,3,5,7,9},*p=a;之后,
p指向a[0],
而上面for循环中p<a+5等价于p<=a+4表示只要指针指向的元素地址小于等于数组a中的a[4]的地址,就输出p指向的元素。
而p++表示使指针p指向a的下一个元素,
所以结果自然是依次输出a[0],a[1],a[2],a[3],a[4]的值,即13579了

❷ C语言指针运算详解

C语言中的数组是指 一类 类型,数组具体区分为 int 类型数组,double类型数组,char数组 等等。同样指针 这个概念也泛指 一类 数据类型,int指针类型,double指针类型,char指针类型等等。
通常,我们用int类型保存一些整型的数据,如 int num = 97 , 我们也会用char来存储字符: char ch = 'a'。
我们也必须知道:任何程序数据载入内存后,在内存都有他们的地址,这就是指针。而为了保存一个数据在内存中的地址,我们就需要指针变量。
因此:指针是程序数据在内存中的地址,而指针变量是用来保存这些地址的变量。

❸ C语言利用指针编写函数,输入3个学生2门课成绩,计算每个学生的平均分和每门课的平均分。

给你一个简单的程序。 希望能看的懂。

#include "stdafx.h"
#include "stdio.h"

int main(int argc, char* argv[])
{
int a,b,c;
printf("a学生成绩是:");
int a1,a2;
scanf("%f,%f",&a1, &a2);
printf ("b学生成绩是:");
int b1,b2;
scanf ("%d,%d",&b1,&b2);
int c1,c2;
printf("c学生的成绩是:");
scanf("%d,%d",&c1,&c2);
a=(a1+a2)/2;
b=(b1+b2)/2;
c=(c1+c2)/2;
printf("a学生的平均成绩是:\n");
printf("%d\n",a);
printf("b学生的平均成绩是:\n");
printf("%d\n",b);
printf("c学生的平均成绩是:\n");
printf("%d\n",c);

int a_c,a_c1;
a_c=(a1+b1+c1)/3;
a_c1=(a2+b2+c2)/3;
printf("每门课的平均成绩是:\n");
printf("%d,%d\n",a_c,a_c1);
}

❹ c语言中两个指针可不可以直接比较值

可以比较,比如
int a[2] = {2,1};
int *P1 = &a[1];
int *P2 = &a[2];

如果指针指向的存储值比较,就是,*P1>*P2;
如果是指针地址比较,就是,P1<P2;

❺ c语言指针练习题动态内存分配方式计算学生成绩

参考
void getMemeory1(char *p)
{
p = (char *)malloc(100*sizeof(char));
}

char * getMemeory2()
{
char p[100] = "Hello world";
return p;
}

int main()
{
//test1
char *str1 = NULL;
getMemeory1(str1);
strcpy(str1, "Hello world");
printf("str1 = %s\n", str1);

//test2
char *str2 = NULL;
str2 = getMemeory2();
printf("str2 = %s\n", str2);
}

执行结果:test1程序报错,test2打印乱码或者“Hello world”(一般乱码)

结果分析:
test1:
在函数中给指针分配空间,实际上是给指针的临时变量分配空间,函数结束后,这个临时变量也消亡,而str仍然为NULL,没有为其分配空间,此时strcpy()是肯定会出错的。

test2:
1、可能是乱码,也有可能是正常输出,因为GetMemory返回的是指向“栈内存”的指针,该指针的地址
不是NULL,但其原来的内容已经被清除,新内容不可知,程序员面试宝典里有专门讲该部分知识的。
2、因为p的生命周期在GetMemory函数执行完了就被销毁了,str 指向的是个野指针。

//相关分析资料摘录
1、指针参数是如何传递内存的?

如果函数的参数是一个指针,不要指望用该指针去申请动态内存。以下Test函数的语句GetMemory(str, 200)并没有使str获得期望的内存,str依旧是NULL,为什么?
1. void GetMemory(char *p, int num)
2. {
3. p = (char *)malloc(sizeof(char) * num);
4. }
5. void Test(void)
6. {
7. char *str = NULL;
8. GetMemory(str, 100); // str 仍然为 NULL
9. strcpy(str, "hello"); // 运行错误
10. }
复制代码
示例1.1 试图用指针参数申请动态内存

毛病出在函数GetMemory中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是 _p,编译器使 _p = p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。在本例中,_p申请了新的内存,只是把 _p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory并不能输出任何东西。事实上,每执行一次GetMemory就会泄露一块内存,因为没有用free释放内存。

如果非得要用指针参数去申请内存,那么应该改用“指向指针的指针”,见示例1.2。
1. void GetMemory2(char **p, int num)
2. {
3. *p = (char *)malloc(sizeof(char) * num);
4. }
5. void Test2(void)
6. {
7. char *str = NULL;
8. GetMemory2(&str, 100); // 注意参数是 &str,而不是str
9. strcpy(str, "hello");
10. cout<< str << endl;
11. free(str);
12. }
复制代码
示例1.2用指向指针的指针申请动态内存

由于“指向指针的指针”这个概念不容易理解,我们可以用函数返回值来传递动态内存。这种方法更加简单,见示例1.3。
1. char *GetMemory3(int num)
2. {
3. char *p = (char *)malloc(sizeof(char) * num);
4. return p;
5. }
6. void Test3(void)
7. {
8. char *str = NULL;
9. str = GetMemory3(100);
10. strcpy(str, "hello");
11. cout<< str << endl;
12. free(str);
13. }
复制代码
示例1.3 用函数返回值来传递动态内存

用函数返回值来传递动态内存这种方法虽然好用,但是常常有人把return语句用错了。这里强调不要用return语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡,见示例1.4。
1. char *GetString(void)
2. {
3. char p[] = "hello world";
4. return p; // 编译器将提出警告
5. }
6. void Test4(void)
7. {
8. char *str = NULL;
9. str = GetString(); // str 的内容是垃圾
10. cout<< str << endl;
11. }
复制代码
示例1.4 return语句返回指向“栈内存”的指针

用调试器逐步跟踪Test4,发现执行str = GetString语句后str不再是NULL指针,但是str的内容不是“hello world”而是垃圾。
如果把示例1.4改写成示例1.5,会怎么样?
1. char *GetString2(void)
2. {
3. char *p = "hello world";
4. return p;
5. }
6. void Test5(void)
7. {
8. char *str = NULL;
9. str = GetString2();
10. cout<< str << endl;
11. }
复制代码
示例1.5 return语句返回常量字符串

函数Test5运行虽然不会出错,但是函数GetString2的设计概念却是错误的。因为GetString2内的“hello world”是常量字符串,位于静态存储区,它在程序生命期内恒定不变。无论什么时候调用GetString2,它返回的始终是同一个“只读”的内存块。

2、杜绝“野指针”

“野指针”不是NULL指针,是指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为用if语句很容易判断。但是“野指针”是很危险的,if语句对它不起作用。 “野指针”的成因主要有两种:

(1)指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如
1. char *p = NULL;
2. char *str = (char *) malloc(100);
复制代码
(2)指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。

(3)指针操作超越了变量的作用范围。这种情况让人防不胜防,示例程序如下:
1. class A
2. {
3. public:
4. void Func(void){ cout << “Func of class A” << endl; }
5. };
6. void Test(void)
7. {
8. A *p;
9. {
10. A a;
11. p = &a; // 注意 a 的生命期
12. }
13. p->Func(); // p是“野指针”
14. }
复制代码
函数Test在执行语句p->Func()时,对象a已经消失,而p是指向a的,所以p就成了“野指针”。但奇怪的是我运行这个程序时居然没有出错,这可能与编译器有关。

❻ C语言用指针编写的四则运算

不知道怎么左对齐,//后面是英文注释///后面是中文注释 给采纳!!

// EX6_08.CPP
// A program to implement a calculator

#include <stdio.h> // For input/output
#include <stdlib.h> // For the exit() function
#include <ctype.h> // For the isdigit() function
#include <string.h> // For the strcpy() function

void eatspaces(char * str); // Function to eliminate blanks
double expr(char * str); // Function evaluating an expression
double term(char * str, int * pindex); // Function analyzing a term
double number(char * str, int * pindex); // Function to recognize a number
char * extract(char * str, int * index); // Function to extract a substring

const int MAX = 80; // Maximum expression length including '\0'

int main(void)
{
char buffer[MAX]; // Input area for expression to be evaluated
char c;
int j,i;

printf("Welcome to your friendly calculator.\n");
printf("Enter an expression, or an empty line to quit.\n");

for(;;)///无开始无终止只有过程,就是不停的循环,保证可以连续输入好几个式子,如先求1+2回车直接3+2再回车,可以多次求
{///式子是一步一步来的,就是说不进行完这个语句是不会进行下一个的
i=0;
scanf("%c",&c); ///捕捉第一个数是c// Read an input line
while(c!='\n')
{
buffer[i++]=c;///,i++是先运算后自加,++i是先自加后运算,所以第一个数放在buffer[0]处
scanf("%c",&c);
}///把式子放在这个数列中,while控制回车时式子结束,此时i是

buffer[i]='\0';///式子最后是一个\o作为标志"\0代表字符数串的结束标志,最后一个在i-1的位置

eatspaces(buffer);///对式子去空格处理 // Remove blanks from input

if(!buffer[0]) // Empty line ends calculator
return 0;///已经去过空格了,buffer[0]应该是有值的,但是没有的话就直接结束,返还0

printf( "\t= %f\n\n",expr(buffer)); ///结果是expr分函数return的结果 // Output value of expression
}
}

// Function to eliminate blanks from a string
void eatspaces(char * str)///预处理,把指向数组的指针设为*str,其中数组中数的地址都是相连的,char数组每个地址差1,int数组每个差2依次类推,其中char型的指针加1就是加一,int型的加一是加二
{
int i=0; // 'Copy to' index to string
int j=0; // 'Copy from' index to string

while((*(str+i) = *(str+j++)) != '\0')///这里是对*(str+i)的一个赋值,没有空格时每次i都加1式子有空格时(str+i)和(str+j++)是相等的,
/// 当有空格时i不加一,就让空格这个地址等于下一个地址,即把式子向前推了一个字符,直到\0 // Loop while character copied is not \0
if(*(str+i) != ' ') // Increment i as long as
i++; // character is not a blank
return;
}

// Function to evaluate an arithmetic expression
double expr(char * str)///真正处理,对加减的分函数
{
double value = 0; ///value是结果,也就是真实值 // Store result here
int index = 0; // Keeps track of current character position

value = term(str, &index);///先解决第一步,因为数字还是char型根本没法算,先把第一个数变成数顺便有()*/都做完了直到看见-+ // Get first term

for(;;) ///保证了多加的情况,后同 // Infinite loop, all exits inside
{
switch(*(str+index++)) ///通过加数组对应的地址时数组一个一个往后推,碰到\0 + -做判断 其他符号输出错误 // Choose action based on current character
{
case '\0': ///一直到最后的标记,输出 // We're at the end of the string
return value; // so return what we have got

case '+': ///先把第一个数变成数然后有()就先()有/*就先/* 最后不都没有了就到-+了然后-+后面的也要先乘除啊,就value += term(str, &index);这样也能让后面的也能变成数,也能让后面的先*/依次类推 // + found so add in the
value += term(str, &index); // next term
break;

case '-': // - found so subtract
value -= term(str, &index); // the next term
break;

default: // If we reach here the string
printf("Arrrgh!*#!! There's an error.\n");///其他符号输出错误因为先进行的*、和()运算,所以再不是-+就一定错了
exit(1);
}
}
}

// Function to get the value of a term
double term(char * str, int * pindex)///对乘除的分函数
{
double value = 0; // Somewhere to accumulate the result

value = number(str, pindex); // Get the first number in the term

// Loop as long as we have a good operator
while((*(str+(*pindex))=='*')||(*(str+(*pindex))=='/'))///进来的是/或者*才继续,不然直接输出了
{

if(*(str+(*pindex))=='*') // If it's multiply,
{
++(*pindex);///是乘先加,就是乘的是后面的
value *= number(str, pindex); ///通过这样,先括号后乘除解决第一步以后的 // multiply by next number
}

if(*(str+(*pindex))=='/') // If it's divide,
{
++(*pindex);
value /= number(str, pindex); // divide by next number
}
}
return value; // We've finished, so return what we've got
}

// Function to recognize a number in a string
double number(char * str, int * pindex)///对(的分函数
{
double value = 0.0; // Store the resulting value

char * psubstr; // Pointer for substring
if(*(str + (*pindex)) == '(') // Start of parentheses
{
++(*pindex);
psubstr = extract(str, pindex);///先看后括号 // Extract substring in brackets
value = expr(psubstr); ///打回来以后再直接用大的顺序进行计算 // Get the value of the substring
return value; // Return substring value
}
///以下是将我们在数组中定义为char的数变为int形式
while(isdigit(*(str+(*pindex)))) ///isdidit是调用的<ctype.h> 这个库函数的一种函数,判断字符是否为阿拉伯数字 // Loop accumulating leading digits
value=10*value + (*(str+(*pindex)++) - 48);///因为ASC码48就是'0',也就是说'0'的值是48,而后依次是'1'到'9'。这样正好是char型的减去48就是它对应的int值
///这样层层推进,直到value是这个数为止(如125就会定义为三个char变量,先判断1是阿拉伯数字,让它乘10加2就成12,再看5是阿拉伯数字,12乘10加5就成了125,变成阿拉伯数字了)

// Not a digit when we get to here

if(*(str+(*pindex))!='.') ///如果没有小数点可以回去了,这里小数点显然无法通过上面的isdigit,就是会有123.45这原来是六个字符(1/2/3/。/4/5)通过上面变成了(123/。/4/5)其中4/5还是char型 // so check for decimal point
return value; // and if not, return value

double factor = 1.0; // Factor for decimal places
while(isdigit(*(str+(++(*pindex)))))///当检测到小数点后面是数的时候就会进行 // Loop as long as we have digits
{
factor *= 0.1; // Decrease factor by factor of 10
value=value + (*(str+(*pindex))-48)*factor;///这里直接第一轮123加0.1*4,第二轮再加0.01*5 // Add decimal place
}

return value; // On loop exit we are done
if(*(str+(*pindex))!='.') // so check for decimal point
return value; ///在此看后面有无小数点,没有就回去,有的话就双小数点,没有返回值发生错误 // and if not, return value

}

// Function to extract a substring between parentheses
// (requires string.h)
char * extract(char * str, int * pindex)///对)的分函数
{
char buffer[MAX]; // Temporary space for substring
char * pstr = NULL; ///代表一个空指针 // Pointer to new string for return
int numL = 0; // Count of left parentheses found
int bufindex = *pindex;///这个定义是 bufindex直接指向当前所指了 // Save starting value for index
do///多次循环
{
buffer[(*pindex) - bufindex] = *(str + (*pindex));///这相当于重新引进了一套目的是不会混乱
switch(buffer[(*pindex) - bufindex])
{
case ')':///当遇到)时
if(numL == 0)///第一次就代表只有()没有套((()))这种情况,((()))会一层一层的算
{
buffer[(*pindex) - bufindex] = '\0'; ///就直接算()里面的把)当成结束去算 // Replace ')' with '\0'
++(*pindex);
pstr = (char *) malloc((*pindex) - bufindex + 1);///malloc是申请使用((*pindex) - bufindex + 1)大小的空间然后指向这个空间的指针设为pstr
if (!pstr)///指针无效就会运行下面这个
{
printf("Memory allocation failed, program terminated.") ;
exit(1);
}
strcpy(pstr, buffer); /// strcpy也是一个函数复制字符串买就是吧buffer的复制到 pstr中去// Copy substring to new memory
return pstr; ///把()里面的东西直接打回去。 // Return substring in new memory
}
else
numL--; // Rece count of '(' to be matched
break;
case '(':
numL++; ///说明有((()))这样的结构,用numl记录有几个(,有一个)减一个1 // Increase count of '(' to be // matched
break;
}
} while(*(str + (*pindex)++) != '\0'); ///没有)直接结束会输出这句话 // Loop - don't overrun end of string
printf("Ran off the end of the expression, must be bad input.\n");
exit(1);
}

❼ 用C语言结构体指针编程序实现输入十个学生的学号,期中和期末成绩,计算输出成绩表和学生平均分

#include<iostream>
#include<string>

using namespace std;
//=============<开始定义结构体>===================================================
struct combox{

int num;
int mark;
string name;
combox *next;

};
//=============<结束定义结构体>===================================================

//=============<开始定义Commonbox类>==============================================

//-----类体开始------------------------
class Commonbox{

private:

combox *head;void Swap(combox *,combox *); //交换两个combox变量的数据域

void Print(combox *); //输出一combox指定的记录

combox *Find(int); //查找条例条件的记录,并返回该记录的指针

public:

Commonbox(){head=NULL;}

int ListCount(); //统计当前链表的记录总数,返回一个整数

void AddItem(int num, string name, int mark); //添加一条记录到表尾
void RemoveItem(int); //删除一条指定的记录

void List(); //列出当前链表中的所有记录

void Sort(); //对当前链表进行排序

void Search(int); //在当前链表查找指定记录并输出

float Average(); //计算平均成绩

(7)c语言指针计算比分扩展阅读

用C语言结构体指针编程序应用方法:

将一个结构体变量中的数据传递给另一个函数,有下列3种方法:

(1) 用结构体变量名作参数。一般较少用这种方法。

(2) 用指向结构体变量的指针作实参,将结构体变量的地址传给形参。

(3) 用结构体变量的引用变量作函数参数。

在软件开发过程中,常常需要动态地分配和撤销内存空间,例如对动态链表中结点的插入与删除。C语言中是利用库函数malloc和free来分配和撤销内存空间的。

❽ C语言指针的计算搞不懂。

你可以把指针看出是一个一维数组,其实指针就是数组,数组就是拿指针来实现的!
1、程序中把a[5]的地址给了指针p,即p指针指向了a[5]
2、那么把p看成数组,因为是int,所以可以存在负的里面,则p看成数组为p[0]=a[5],
3、那么p[-2]则是a[3]对应的值为54
4、你可以验证这样写看if(&p[-2]!=&a[3]),如果相等则验证了,事实就是相等
希望可以帮到你,如果满意请采纳!

❾ c语言 数组指针计算

#include<stdio.h>
main(){
//设数组a的首地址为2000,
int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};
printf("a[2][1]=%d\n",a[2][1]);// 得值19
printf("a[1]=%d\n",a[1]);//9的地址2016
printf("a =%d\n",a);//1的地址2000
printf("a+1 =%d\n",a+1);//9的地址2016
printf("*a+1=%d\n",*a+1);//3的地址2004
printf("*(a+1)=%d\n",*(a+1));//9的地址2016
printf("a[2]+1=%d\n",a[2]+1);//19的地址2036
printf("*(a+1)+1=%d\n",*(a+1)+1);//11的地址2020
printf("*(*(a+2)+2)=%d\n",*(*(a+2)+2));//得值21
}

//以上结果我试过了