标签:void std The 作业 方法 指针的指针 img src one
比如: int **p; //定义了int类型的二级指针
注意:你定义的二级指针,它的类型必须跟一级指针类型一致
作用:用来指向另外一个一级指针在内存当中的地址(指向指针的指针)
总结:二级指针在使用的时候无非就两种情况
**q
*q 二级指针解引用一次和两次分别代表什么??这个搞清楚代码就不会写错
#include <stdio.h> int main() { int a = 888; int *p = &a; //定义一级指针p int **q = &p; //定义二级指针q,指向一级指针p的地址 //通过二级指针去访问a //把二级指针解引用两次 **q--》**&p --》*p --》*&a--》a //把二级指针解引用一次 *q--》*&p--》p printf("通过二级指针q访问a: %d\n", **q); //q解引用两次即可 printf("通过二级指针q访问a: %d\n", **&p); printf("二级指针q存放的是指针p的首地址:%p\n", &p); printf("二级指针q存放的是指针p的首地址:%p\n", q); }
#include <stdio.h> #include <string.h> int main() { int i; char buf[10] = "hello"; char *p = buf; char **q = &p; // 定义二级指针q //通过二级指针访问修改buf中的内容 //**q --》**&p--》*p --》*&buf[0] --》buf[0] //*q --》p --》buf--》&buf[0] printf("通过二级指针q访问buf完整的字符串 %s\n", *q); for (i = 0; i < strlen(buf); i++) printf("通过二级指针q访问buf中的单个字符 %c\n", *(*q + i)); }
1. char buf[3][10]={"hello","hehe","haha"};
char *p=buf[0];
char **q=&p;
//通过q访问二维数组中的三个字符串 %s
//通过q访问二维数组中的单个字符%c
#include <stdio.h> #include <string.h> /* 二级指针使用的套路: 通过等价替换--》把二级指针解引用替换成你熟悉的一级指针 */ int main() { int i, j; char buf[3][10] = {"hello", "hehe", "haha"}; /* char *p=buf[0]; char **q=&p; //访问二维数组中的字符 for(i=0; i<30; i++) printf("二级指针q访问数组:%c\n",*(*q+i)); //访问二维数组中的字符串--》找到字符串的起始地址即可 for(i=0; i<30; i+=10) printf("三个字符串分别是:%s\n",*q+i); //等价于p+i */ //扩展思考: char(*p)[10] = &buf[0]; //数组指针 //二级指针的类型要跟一级指针类型一致 char(**q)[10] = &p; //p的类型是数组指针 //通过二级指针q去遍历访问二维数组的字符 // *q相当于p for (i = 0; i < 3; i++) { for (j = 0; j < 10; j++) printf("(*q)[%d][%d] is:%c\n",i,j, (*q)[i][j]); } //通过二级指针q去遍历字符串 for (i = 0; i < 3; i++) printf("%s\n", *(*q + i)); }
数学当中:函数就是别人提供给你公式方法 sin() cos()
C语言中:为了提高代码的复用性,把一些功能封装成函数供开发人员使用
printf() --》函数 strcmp() strcpy()
函数的定义都是写在main函数的外面
返回值类型 函数名(形参列表) //函数头
{
函数体;
}
返回值: 告诉函数的调用者,我这个函数执行完毕之后的结果
函数名: 变量名规则一样,通俗易懂,不能跟C语言的关键字以及C语言的函数名字冲突
形参列表:告诉程序员,在使用这个函数的使用需要传递多少个实参,每个实参分别是什么类型
实参(实际参数):函数调用的使用,传递的参数就是实参
形参(形式参数):函数定义的时候出现在圆括号里面的都是形参
函数的调用
语法格式: 函数名(实参列表) //实参的个数,类型必须跟形参保存一致
#include <stdio.h> //把比较两个整数大小的代码--》封装成函数 //函数如何封装--》程序员说了算,封装的函数用起来很方便--》成功 //目的:为了提高代码的重复使用效率,任何其他代码将来都能使用 int numcmp(int n1, int n2) //形式参数 { if (n1 > n2) return 1; else if (n1 < n2) return -1; else return 0; //通过返回值判断大小 } void othernumcmp(int n1, int n2) //没有返回值 { if (n1 > n2) printf("n1>n2"); else if (n1 < n2) printf("n1<n2"); else printf("n1==n2"); } int main() { int a; int b; printf("请输入两个整数!\n"); scanf("%d%d", &a, &b); //调用函数 //实参赋值给形参 int ret = numcmp(a, b); //编译器翻译这句话 n1=a n2=b if (ret > 0) printf("a>b\n"); else if (ret < 0) printf("a<b\n"); else printf("a==b\n"); }
第一个: 函数的定义要么写在main函数的前面,要么写在main函数的后面(注意提前声明)
第二个:实参和形参的关系一定要搞清楚
#include <stdio.h> //numcmp定义在main的后面 int numcmp(int a, int b); //声明了函数头,形式参数 //fun定义在main的前面 int fun(int c, int d) //故意迷惑你,把形参的名字取得跟实参一模一样 { c += 18; d += 10; return 0; } int main() //C语言代码都是从main函数开始往下执行 { int a; int b; int c = 6; int d = 12; printf("请输入两个整数!\n"); scanf("%d%d", &a, &b); //调用函数fun fun(c, d); printf("c is:%d\n", c); printf("d is:%d\n", d); //调用函数numcmp //实参赋值给形参 int ret = numcmp(a, b); //编译器翻译这句话 n1=a n2=b if (ret > 0) printf("a>b\n"); else if (ret < 0) printf("a<b\n"); else printf("a==b\n"); } int numcmp(int a, int b) { if (a > b) return 1; else if (a < b) return -1; else return 0; //通过返回值判断大小 }
C语言中函数调用传递参数只有两种写法: 传值和传地址
区分传值和传地址: 函数的形参是普通变量 --》传值
函数的形参是指针--》传地址
传值:实参把自己的值拷贝一份给形参
传地址:实参把自己的地址赋值给形参指针
#include <stdio.h> //经典例子--》定义一个函数交换两个整数的值 void swapnum(int n1, int n2) //实参传值给形参 //实参a,b和形参n1,n2是四个独立的变量,a,b只是把自己的值拷贝它们 { printf("形参n1 n2地址是:%p\n", &n1); printf("形参n1 n2地址是:%p\n", &n2); int temp; temp = n1; n1 = n2; n2 = temp; //跟实参a,b没有任何关系 printf("函数中n1 n2: %d %d\n", n1, n2); } void otherswap(int *p1, int *p2) //实参传地址给形参 { printf("形参p1存放的地址:%p\n", p1); printf("形参p2存放的地址:%p\n", p2); int temp; temp = *p1; *p1 = *p2; *p2 = temp; //把p1和p2两个指针中的内容交换 } int main() { int a = 89; int b = 63; printf("实参a的地址:%p\n", &a); printf("实参b的地址:%p\n", &b); printf("交换之前: %d %d \n", a, b); //调用函数swapnum swapnum(a, b); //编译器翻译: n1=a n2=b //调用otherswap // otherswap(&a,&b); //编译器翻译:p1=&a p2=&b printf("交换之后: %d %d \n", a, b); }
第三个:数组作为实参和形参
数组作为实参: 传递的地址(指针)
数组作为形参: 要么写成指针的形式,或者写成 数组+n(n表示元素个数)
第四个:局部变量和全局变量--》作用域
全局变量: 定义在main函数外面以及其他函数的外面
全局变量在定义的.c文件中任何函数都能使用,并且其他.c文件也能使用
全局变量是所有函数共享的,作用域属于整个文件
局部变量: 定义在某个函数的花括号里面的,作用域仅限于函数内部
作用域(作用区域):指的是这个变量的使用范围
需要注意的问题:
第一个: 全局变量跟局部变量同名,优先使用自己定义的局部变量(全局
变量不起作用了)
#include <stdio.h> int num = 100; //全局变量 int fun(int a) //形参a也是局部变量 { //由于fun函数中没有单独定义num,使用的是全局变量num num += 5; //使用的全局变量 printf("num在fun函数中被修改了%d\n", num); printf("a is:%d\n", a); } int main() { printf("main函数中使用num %d\n", num); //全局变量num int num = 888; //局部变量如果跟全局变量同名,会覆盖掉同名的全局变量 fun(num); //num用的是哪个num printf("调用fun之后,main函数中使用num %d\n", num); }
封装一个函数,把用户从键盘输入的任意一个字符串中的非英文字符去除
#include <stdio.h> #include <string.h> /* 函数名的不同风格: getnum() get_num() //ubuntu系统中采用这种风格 getNum() //C++ JAVA 驼峰命名 */ //封装函数实现去除字符串中的非英文字符 void rmchar(char *buf) //char *buf=buf实参传递地址给形参 { int i, j; for (i = 0; i < strlen(buf); i++) { if (buf[i] < ‘a‘ || buf[i] > ‘z‘) { for (j = i; j < strlen(buf); j++) buf[j] = buf[j + 1]; i--; } } } //这种封装通用性比较差 //void otherchar(char otherbuf[20]) //要求你传递char [20]类型的数组 //通用性好一些,n表示数组元素个数 void otherchar(char otherbuf[], int n) { int i, j; for (i = 0; i < strlen(otherbuf); i++) { if (otherbuf[i] < ‘a‘ || otherbuf[i] > ‘z‘) { for (j = i; j < strlen(otherbuf); j++) otherbuf[j] = otherbuf[j + 1]; i--; } } } int main() { char buf[16]; scanf("%s", buf); //rmchar(buf); //编译器翻译:char *buf=buf otherchar(buf, 16); printf("去除非英文字符之后:%s\n", buf); }
第一题: 明确指出每个num是全局还是局部,值是多少,不要编译运行
#include <stdio.h> int num = 100; //全局变量 int fun(int num) //任何函数的形参都是局部变量,跟全局变量同名 { num += 5; //fun自己的形参num 87 printf("num在fun函数中被修改了%d\n", num); //fun自己的形参num 87 return num; //fun自己的形参num 87 } int main() { //到目前为止main没有定义自己的num num -= 18; //全局变量num==82 fun(num); //函数调用 printf("main函数中使用num %d\n", num); // 全局变量num==82 int num = 888; //main自己局部变量 fun(num); //main自己的num printf("调用fun之后,main函数中使用num %d\n", num); //main自己的num }
第二题:请问程序执行结果是多少??
void foo(int b[][3]); void main() { int a[3][3]={{1,2,3},{4,5,6},{7,8,9}}; foo(a); printf("%d",a[2][1]); } void foo(int b[][3]) { ++b; b[1][1]=9; }
难点:知识点 数组作为形参--》理解为指针,传地址
指针的运算,写法 ++b很好理解 b[1][1]的理解
结果为:9 因为foo(a)//a为数组名,int(*)[3]的指针; 将首地址赋值给b,进入函数后,立马执行++; 此时b的指引的地址+1了,指向了a的第2位数组的首地址 即{4,5,6}这个数组 然后b[1][1]=9;则表示数组{7,8,9}中的8替换成了9; 回到主函数,打印的是a[2][1]即是被替换后的那个值。 最后结果为:9。
第三题: 封装一个函数 int fun(int n) 该函数可以把1到n之间(1<= 数字 <=n)所有能被6整除的数,或者数字中包含6的全部找到并打印出来
#include <stdio.h> /* *封装一个函数 int fun(int n) *该函数可以把1到n之间(1<= 数字 <=n)所有能被6整除的数, *或者数字中包含6的全部找到并打印出来 */ int fun(int n) //能被6整除,或数字包含6的数打印出来; { int i; for (i = 1; i <= n; i++) { if (i % 6 == 0 || i % 10 == 6 || i / 10 == 6 || i / 100 == 6 || i / 1000 == 6) { printf("%d ", i); } } } int main() { int input = 0; printf("Please enter a number\n"); scanf("%d", &input); fun(input); return 0; }
标签:void std The 作业 方法 指针的指针 img src one
原文地址:https://www.cnblogs.com/xiaojian98/p/12470872.html