首页 > 其他分享 >C语言指针的常见问题

C语言指针的常见问题

时间:2023-07-24 14:14:33浏览次数:54  
标签:常见问题 score marbles int 函数 C语言 stu ar 指针

1

值传递

下面看一个列子,student结构体中包含该学生的各种信息,我们在change函数中对其进行部分修改,再在主函数中输出其结果

#include<stdio.h>
#include<string.h>
#define format "%d\n%s\n%f\n%f\n%f\n"
struct student
{
    int num;
    char name[20];
    float score[3];
};
void change( struct student stu );
int main()
{
    
    struct student stu;
    stu.num = 12345;
    strcpy(stu.name, "Tom");
    stu.score[0] = 67.5;
    stu.score[1] = 89;
    stu.score[2] = 78.6;
    change(stu);
    printf(format, stu.num, stu.name, stu.score[0], stu.score[1],stu.score[2]);
    printf("\n");
    return 0;
}
 
void change(struct student stu)
{
    stu.score[0] = 100;
    strcpy(stu.name, "jerry");
}
View Code

 

最终输出的值并未改变。。

地址传递

#include<stdio.h>
#define format "%d\n%s\n%f\n%f\n%f\n"
struct student
{
    int num;
    char name[20];
    float score[3];
};
void change( struct student* stu );
int main()
{
    
    struct student stu;
    stu.num = 12345;
    strcpy(stu.name, "Tom");
    stu.score[0] = 67.5;
    stu.score[1] = 89;
    stu.score[2] = 78.6;
    change(&stu);
    printf(format, stu.num, stu.name, stu.score[0], stu.score[1],stu.score[2]);
    printf("\n");
    return 0;
}
 
void change(struct student* p)
{
    p->score[0] = 100;
    strcpy(p->name, "jerry");
}

 

可以看到,通过地址传递修改了结构体内的数据

用&stu做实参,&stu是结构体变量stu的地址。在调用函数时将该地址传送给形参p(p是指针变量)。这样p就指向stu。

在change函数中改变结构体内成员的值,在主函数中就输出了改变后的值

2

使用 sum()函数。该程序打印原始数 组的大小和表示该数组的函数形参的大小(如果你的编译器不支持用转换说 明%zd打印sizeof返回值,可以用%u或%lu来代替)。

// sum_arr1.c -- 数组元素之和
// 如果编译器不支持 %zd,用 %u 或 %lu 替换它
#include <stdio.h>
#define SIZE 10
int sum(int ar[], int n);
int main(void)
{
  int marbles[SIZE] = { 20, 10, 5, 39, 4, 16, 19, 26, 31, 20 };
  long answer;
  answer = sum(marbles, SIZE);
  printf("The total number of marbles is %ld.\n", answer);
  printf("The size of marbles is %zd bytes.\n",
  sizeof marbles);
  return 0;
}
int sum(int ar[], int n) // 这个数组的大小是?
{
  int i;
  int total = 0;
  for (i = 0; i < n; i++)
    total += ar[i];
  printf("The size of ar is %zd bytes.\n", sizeof ar);
  return total;
}
该程序的输出如下: The size of ar is 8 bytes. The total number of marbles is 190. The size of marbles is 40 bytes.

  

注意,marbles的大小是40字节。这没问题,因为marbles内含10个int类 型的值,每个值占4字节,所以整个marbles的大小是40字节。但是,ar才8字 节。这是因为ar并不是数组本身,它是一个指向 marbles 数组首元素的指 针。我们的系统中用 8 字节储存地址,所以指针变量的大小是 8字节(其他 系统中地址的大小可能不是8字节)。简而言之,在程序清单10.10中, marbles是一个数组, ar是一个指向marbles数组首元素的指针,利用C中数组 和指针的特殊关系,可以用数组表示法来表示指针ar。 

 

3

传递地址会导致一些问题。C 通常都按值传递数据,因为这样做可以保 证数据的完整性。如果函数使用的是原始数据的副本,就不会意外修改原始 数据。但是,处理数组的函数通常都需要使用原始数据,因此这样的函数可 以修改原数组。有时,这正是我们需要的。例如,下面的函数给数组的每个 元素都加上一个相同的值:

void add_to(double ar[], int n, double val)
{
    int i;
    for (i = 0; i < n; i++)
        ar[i] += val;
}

  

因此,调用该函数后,prices数组中的每个元素的值都增加了2.5:

add_to(prices, 100, 2.50);

该函数修改了数组中的数据。之所以可以这样做,是因为函数通过指针 直接使用了原始数据。

 

ANSI C提供 了一种预防手段。如果函数的意图不是修改数组中的数据内容,那么在函数 原型和函数定义中声明形式参数时应使用关键字const。例如,sum()函数的 原型和定义如下:

int sum(const int ar[], int n); /* 函数原型 */
int sum(const int ar[], int n) /* 函数定义 */
{
int i;
int total = 0;
for( i = 0; i < n; i++)
    total += ar[i];
return total;
}

  

以上代码中的const告诉编译器,该函数不能修改ar指向的数组中的内 容。如果在函数中不小心使用类似ar[i]++的表达式,编译器会捕获这个错 误,并生成一条错误信息。

标签:常见问题,score,marbles,int,函数,C语言,stu,ar,指针
From: https://www.cnblogs.com/cyj22/p/17577051.html

相关文章

  • C语言模拟银行排队叫号系统(链队)
    一.队列队列是一种具有先进先出(FIFO)特性的线性数据结构,它只允许在队列的两端进行插入和删除操作。队列的一端称为队尾(rear),另一端称为队头(front)。新元素总是插入在队列的队尾,而从队列中删除元素时则总是删除队头元素。由于队列具有FIFO特性,因此队列通常用于需要按照顺序处理数据的场......
  • 11.数组名和指针(这⾥为指向数组⾸元素的指针)区别
    1intmain()2{3inta[2]={1,2};4int*p=a;5cout<<"a+1"<<a+1<<endl;6cout<<"p+1"<<p+1<<endl;7cout<<"*(a+1)"<<*(a+1......
  • 初始C语言
    基本了解C语言的基础知识,对C语言有个初步的认识。C语言是什么?人与人之间的交流使用的是自然语言。如汉语,英语,日语。人与计算机是怎么交流的呢?使用计算机语言。目前已知已经有上千种计算机语言。人们是通过计算机语言写的程序,给计算机工作的。C语言是一门通用的计算机编程语......
  • C语言的一些不常用的编译知识
    1.__stringifyLinux内核中有如下两个宏:#define__stringify_1(x...)#x#define__stringify(x...)__stringify_1(x)作用:会将x替换成()里面的内容。2.GCC__attribute__使用__attribute__((used)):表示对于这个函数可能不会调用它、可能用不到它,编译器不用进行warning提......
  • C语言数据类型和变量
    一.数据类型介绍1.概念所谓类型,就是相似的数据所拥有的共同特征,编译器只有知道了数据的类型,才能知道如何操作数据。2.数据类型分类**内置类型:字符,整型,浮点型,布尔类型自定义类型:数组,结构体-struct,枚举-enum,联合体-union**(自己创造类型)a.字符类型char[signed]char-有符号的charunsi......
  • c语言当中的COORD ,GetStdHandle(),SetConsoleCursorPosition(),以及避免清屏和反复刷新
    这是WindowsAPI定义的结构体类型COORD来表示字符在控制台屏幕上的坐标,结构体类型COORD定义为:typedefstruct_COORD{SHORTx;SHORTy;}COORD;使用WindowsAPI GetStdHandle()从一个特定的标准设备获取表示设备的句柄(用来标识不同设备的一个数值),SetConsoleCursor......
  • C语言实现飞机大战手机游戏完整代码
    ​大一课设做的飞机大战手机游戏,可以进行登入和注册,这个是利用单链表做的,源代码已经给出,这个是最基本的飞机大战模式,我设置了几个功能,比如排行榜之类的。排行榜是用结构体数组做的,已及冒泡排序,并且在文件里保存信息。比较简单。#include"stdio.h"#include"windows.h"  //用......
  • 用c语言实现2048小游戏
    ​ #include<time.h> #include<stdlib.h> #include<conio.h> #include<stdio.h> #include<windows.h> #definex026 #definey01 HANDLEhOutput=GetStdHandle(STD_OUTPUT_HANDLE); /*显示声明*/ voidp(int*a,inti,intx,inty); /*部......
  • c语言_十大排序算法
    1.冒泡排序思想:通过比较相邻的元素并交换它们来排序。时间复杂度为O(n^2); #include<stdio.h>voidbubble_sort(intarr[],intlen){inti,j,temp;for(i=0;i<len-1;i++)for(j=0;j<len-1-i;j++)if(arr[j]>arr[j+......
  • c语言_练习实例100
     题1:1.有 1、2、3、4 四个数字,能组成多少个互不相同且无重复数字的三位数?都是多少?#include<stdio.h>intmain(){for(inti=1;i<5;i++){//取百位for(intj=1;j<5;j++){//取十位for(intk=1;k<5;k++){//取个位if(i!=j&&j!......