c语言指针GetMemory经典例子

合集下载

C语言:二级指针的作用

C语言:二级指针的作用

C语⾔:⼆级指针的作⽤⼆级指针的作⽤⽤处特别⼤⾸先主要在数据结构之中当改变指针的时候就需要通过改变指针的指针的值来改变!在数据结构中⽤处很⼴.最普遍的⽐如说链表,通过调⽤函数改变了链表中的元素,那么整个链表就发⽣了变化,这种情况下就会⽤到⼆级指针,因为链表的起始是通过指向头结点的指针来执⾏的,所以必须要改变这个指针,怎么样使⼀个指针改变?在形参传递时,必须传递指针的地址,也就是指向指针的指针.指向指针的指针的作⽤ :当要修改实参指针的指向的时候,形参必须使⽤指向指针的指针。

当修改的是实参指针指向的内容时,则形参只需是指针即可以下是经典程序(载⾃林锐的从c\c++⾼质量编程),讲解的部分是我个⼈理解void GetMemory(char *p,int num){p=(char*)malloc(sizeof(char)*num); //p是形参指向的地址}void main(){char *str=NULL;GetMemory(str,100); //str是实参指向的地址,不能通过调⽤函数来申请内存strcpy(str,"hello");}结构是编译能通过,却不能运⾏,为什么呢?先说⼀下指针作为函数参数的意义:当将指针作为参数时,实参向形参传递的是地址,在函数执⾏过程中,既可以对该参数指针进⾏处理,也可以对该参数指针所指向的数据进⾏处理,(以上程序段来说就是可以对p或*p进⾏处理)。

由于此时形参和实参都是指向同⼀个存储单元,因此当形参指针所指向的数据改变时,实参指针所指向的数据也作相应的改变,因此这时的形参可以作为输出参数使⽤。

(str和p应同时更改!)按照上⾯的说法,这个程序应该没有问题的啊,实参str和形参p指向同⼀个存储单元,给形参分配的内存单元应该也给实参分配了才对啊,问题就是在这⾥实参和形参是指向同⼀个地址,它们只是指向相同,但它们⾃⾝的地址不是同时申请的,就是说p在申请内存时,相当于是把p的指向给改了,但是str的指向仍然没有改!所以尽管str调⽤了GetMemory,但它仍然是个空指针,所以进⾏strcpy是就不能运⾏。

C语言数组参数与指针参数

C语言数组参数与指针参数

C语言数组参数与指针参数我们都知道参数分为形参和实参。

形参是指声明或定义函数时的参数,而实参是在调用函数时主调函数传递过来的实际值。

一、一维数组参数1、能否向函数传递一个数组?看例子:void fun(char a[10]){char c = a[3];}intmain(){char b[10] = “abcdefg”;fun(b[10]);return 0;}先看上面的调用,fun(b[10]);将b[10]这个数组传递到fun 函数。

但这样正确吗?b[10]是代表一个数组吗?显然不是,我们知道b[0]代表是数组的一个元素,那b[10]又何尝不是呢?只不过这里数组越界了,这个b[10]并不存在。

但在编译阶段,编译器并不会真正计算b[10]的地址并取值,所以在编译的时候编译器并不认为这样有错误。

虽然没有错误,但是编译器仍然给出了两个警告:warning C4047: 'function' : 'char *' differs in levels of indirection from 'char 'warning C4024: 'fun' : different types for formal and actual parameter 1这是什么意思呢?这两个警告告诉我们,函数参数需要的是一个char*类型的参数,而实际参数为char 类型,不匹配。

虽然编译器没有给出错误,但是这样运行肯定会有问题。

如图:这是一个内存异常,我们分析分析其原因。

其实这里至少有两个严重的错误。

第一:b[10]并不存在,在编译的时候由于没有去实际地址取值,所以没有出错,但是在运行时,将计算b[10]的实际地址,并且取值。

这时候发生越界错误。

第二:编译器的警告已经告诉我们编译器需要的是一个char*类型的参数,而传递过去的是一个char 类型的参数,这时候fun 函数会将传入的char 类型的数据当地址处理,同样会发生错误。

C语言技术的高级用法——进阶开发技巧详解

C语言技术的高级用法——进阶开发技巧详解

C语言技术的高级用法——进阶开发技巧详解C语言作为一门广泛应用于嵌入式系统和底层软件开发的编程语言,其高级用法和进阶开发技巧对于程序员来说至关重要。

本文将详细介绍一些C语言的高级用法和进阶开发技巧,帮助读者更好地掌握和应用C语言。

一、指针的高级应用指针是C语言中的重要概念,利用指针可以实现更高效的内存管理和数据操作。

以下是一些常见的指针高级应用:1. 指针的指针指针的指针是指一个指针变量指向另一个指针变量的地址。

通过使用指针的指针,可以实现对指针变量的动态修改和访问,进一步提高程序的灵活性。

2. 函数指针函数指针可以指向程序中的函数,通过函数指针可以实现对函数的动态调用和替代。

这在实现回调函数和函数式编程时非常有用。

3. 指针与数组指针和数组之间有着密切的关系,可以通过指针来遍历和操作数组元素,这样可以减少内存的占用和提高程序的运行效率。

二、内存管理与优化技巧C语言需要手动管理内存,合理地进行内存管理和优化可以提高程序的性能和稳定性。

以下是一些常用的内存管理和优化技巧:1. 内存分配和释放C语言提供了malloc()和free()函数用于动态分配和释放内存。

合理使用这些函数可以减少内存的浪费和泄漏。

2. 内存对齐内存对齐可以提高内存访问的效率,尤其对于嵌入式系统来说更为重要。

通过使用内存对齐的技巧,可以减少内存读取的时间,提高程序的运行效率。

3. 缓存优化程序中的缓存访问对于性能有着重要影响。

通过充分利用缓存的特性,如空间局部性和时间局部性,可以减少缓存的命中不中和提高程序的效率。

三、并发编程与多线程随着多核处理器的普及,多线程编程成为了提高程序性能的重要方式。

C语言提供了一些库和技术用于并发编程和多线程的实现。

1. 线程创建与管理C语言的线程库提供了线程的创建和管理方法,可以创建多个线程来执行不同的任务,提高程序的并行性。

2. 互斥与同步多线程访问共享资源时需要进行同步和互斥操作以避免竞态条件的发生。

常见C语言笔试题

常见C语言笔试题

五、编写strcpy函数(10分)已知strcpy函数的原型是char *strcpy(char *strDest, const char *strSrc);其中strDest是目的字符串,strSrc是源字符串。

(1)不调用C++/C的字符串库函数,请编写函数strcpychar *strcpy(char *strDest, const char *strSrc);{assert((strDest!=NULL) && (strSrc !=NULL)); // 2分char *address = strDest; // 2分while( (*strDest++ = * strSrc++) != ‘\0’ ) // 2分NULL ;return address ; // 2分}(2)strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值?答:为了实现链式表达式。

// 2分例如int length = strlen( strcpy( strDest, “hello world”) );六、编写类String的构造函数、析构函数和赋值函数(25分)已知类String的原型为:class String{public:String(const char *str = NULL); // 普通构造函数String(const String &other); // 拷贝构造函数~ String(void); // 析构函数String & operate =(const String &other); // 赋值函数private:char *m_data; // 用于保存字符串};请编写String的上述4个函数。

标准答案:// String的析构函数String::~String(void) // 3分{delete [] m_data;// 由于m_data是内部数据类型,也可以写成delete m_data; }// String的普通构造函数String::String(const char *str) // 6分{if(str==NULL){m_data = new char[1]; // 若能加NULL 判断则更好*m_data = …\0‟;}else{int length = strlen(str);m_data = new char[length+1]; // 若能加NULL 判断则更好strcpy(m_data, str);}}// 拷贝构造函数String::String(const String &other) // 3分{int length = strlen(other.m_data);m_data = new char[length+1]; // 若能加NULL 判断则更好strcpy(m_data, other.m_data);}// 赋值函数String & String::operate =(const String &other) // 13分{// (1) 检查自赋值// 4分if(this == &other)return *this;// (2) 释放原有的内存资源// 3分delete [] m_data;// (3)分配新的内存资源,并复制内容// 3分int length = strlen(other.m_data);m_data = new char[length+1]; // 若能加NULL 判断则更好strcpy(m_data, other.m_data);// (4)返回本对象的引用 // 3分return *this;}华为笔试2006-2-28 星期二(Tuesday) 晴1、局部变量能否和全局变量重名?答:局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。

华三笔试题

华三笔试题

H3C华三技术有限公司[笔试题]2013-09-25注:笔试题根据面试者回忆记录,仅供参考;以下题目都是在小端结尾的32位x86 CPU上面运行的代码:一.编程题1. 请实现一个函数,对于给定的整型参数N,该函数能够打印出自然数中的头N 个质数(15分)。

#include <stdio.h>#define N 10000void find_zs(int num){int i;int j;printf("%d以前的质数是:",num);for (i=2;i<num;i++){for (j=2;j<i;j++){if (0 == i%j){break;}if (i-1 == j){printf("%d ",i);}}}}int main(){find_zs(N);return 0;}2.链表节点结构体定义struct node{int data;struct node *prev;struct node *next;}假设已经构建完毕的一个双向链表有节点A-B-C-D-E-F,从中截断,以C为截断点,传入节点C的指针,截断后重新连接的链表变为C-D-E-F-A-B的形式,写出实现这一功能的C语言代码,返回新链表的头节点指针。

(10分)#include <stdio.h>#include <stdlib.h>struct node{int data;struct node *prev;struct node *next;};int main(){//形成A-B-C-D-E-F的双向链表用1-2-3-4-5-6来表示int i;node * head = (node *)malloc(sizeof(node));head->data = 1;head->next = NULL;head->prev = NULL;node * p = head;node * q = head;for (i=0;i<5;i++){q = (node *)malloc(sizeof(node));q->data = i + 2;p->next = q;q->prev = p;q->next = NULL;p = q;}//打印链表中的data,确认双向链表生成p = head;q = head;for (i=0;i<6;i++){printf("%d-",p->data);q = p->next;p = q;}printf("\n");//找到C(3)节点,并把指针放到tmp_head,同时把p,q指向链表尾p = head;q = head;node * tmp_head = head;while(NULL != p->next){if (3 == p->data){tmp_head = p;}q = p->next;p = q;}//把A-B节点挪到F节点后面p->next = head;head->prev = p;q = head->next;q->next = NULL;//打印当前链表,验证结果是否正确p = tmp_head;q = tmp_head;for(i=0;i<6;i++){printf("%d-",p->data);q = p->next;p = q;}printf("\n");return 0;}二.问答题(每题4分)1.请写出float x 与“零值”比较的if 语句:#define EPSINON 1e-6if(x<= EPSINON && x>=- EPSINON)2. 用预处理指令#define声明一个常数,用来表示一年有多少秒(忽略闰年问题) #define N (365*24*3600)ul3. void GetMemory(char *p){p = (char *)malloc(100);}void Test(void){char *str = NULL;GetMemory(str);strcpy(str, "hello world");printf(str);}请问运行Test函数会有什么样的结果?程序崩溃这其实是一个参数传递的问题.修改变量值需要传递该变量类型的一级指针;修改一级指针指需要传递对应类型的二级指针./view/948185300b4c2e3f572763a1.html 4. char *GetMemory(void){char p[] = "hello world";return p;}void Test(void){char *str = NULL;str = GetMemory();printf(str);}请问运行Test函数会有什么样的结果程序执行后结果未知,可能是hell。

C语言内存分配问题(整理)

C语言内存分配问题(整理)
程序代码区:用来存放程序的二进制代码。
我查了下资料,有说分四个,有说分五个加一个程序代码区,我没查到参考的专业书籍。所 以麻烦知道的告知一下,完善一下。
2、 内存分配方式 内存分配方式有三种:
1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整 个运行期间都存在。例如全局变量,static 变量。
4、动态分配释放内存举例 用 malloc 动态分配内存后一定要判断一下分配是否成功,判断指针的值是否为 NULL。 内存分配成功后要对内存单元进行初始化。 内存分配成功且初始化后使用时别越界了。 内存使用完后要用 free(p)释放,注意,释放后,p 的值是不会变的,仍然是一个地址值, 仍然指向那块内存区,只是这块内存区的值变成垃圾了。为了防止后面继续使用这块内存, 应在 free(p)后,立即 p=NULL,这样后面如果要使用,判断 p 是否为 NULL 时就会判断出 来。
NO.2
char *GetMemory(void) {
char Байду номын сангаас[] = hello world; retrun p; } void Test(void) { char *str = NULL; str = GetMemory(); printf(str); }
问题同 NO.1
NO.3
void GetMemory(char **p, int num) {
free(str); if(str != NULL) {
strcpy(str,"world"); printf(str); } }
问题同 NO.1 我对以上问题的分析:
NO.1:程序首先申请一个 char 类型的指针 str,并把 str 指向 NULL(即 str 里存的是 NULL 的地址,*str 为 NULL 中的值为0),调用函数的过程中做了如下动作: 1、申请一个 char 类型的指针 p, 2、把 str 的内容 copy 到了 p 里(这是参数传递过程中系统所做的), 3、为 p 指针申请了 100 个空间, 4、返回 Test 函数.最后程序把字符串 hello world 拷贝到 str 指向的内存空间里.到这里错 误出现了! str 的空间始终为 NULL 而并没有实际的空间.深刻理解函数调用的第 2 步,将不难发现问 题所在!(注意:传递的参数和消除的参数) NO.2:程序首先申请一个 char 类型的指针 str,并把 str 指向 NULL.调用函数的过程中做了 如下动作: 1申请一数组 p[]并将其赋值为 hello world(数组的空间大小为 12), 2返回数组名 p 付给 str 指针(即返回了数组的首地址). 那么这样就可以打印出字符串"hello world"了么?当然是不能的! 因为在函数调用的时候漏掉了最后一步.也就是在第2步 return 数组名后,函数调用还要 进行一步操作,也就是释放内存空间.当一个函数被调用结束后它会释放掉它里面所有的变 量所占用的空间.所以数组空间被释放掉了,也就是说 str 所指向的内容将不确定是什么东 西. NO.3:正确答案为可以打印出 hello.但内存泄漏了! 需要用 free()函数进行释放。

c语言面试题__指针篇

c语言面试题__指针篇

c语言面试题__指针篇c语言面试题__指针篇1. char * const p;char const * pconst char *p上述三个有什么区别?char * const p; //常量指针,p的值不可以修改char const * p;//指向常量的指针,指向的常量值不可以改const char *p; //和char const *p------------------------------------------------------2. char str1[] = "abc";char str2[] = "abc";const char str3[] = "abc";const char str4[] = "abc";const char *str5 = "abc";const char *str6 = "abc";char *str7 = "abc";char *str8 = "abc";cout << ( str1 == str2 ) << endl;cout << ( str3 == str4 ) << endl;cout << ( str5 == str6 ) << endl;cout << ( str7 == str8 ) << endl;打印结果是什么?解答:结果是:0 0 1 1str1,str2,str3,str4是数组变量,它们有各自的内存空间;而str5,str6,str7,str8是指针,它们指向相同的常量区域-----------------------------------------------3. 以下代码中的两个sizeof用法有问题吗?void UpperCase( char str[] ) // 将 str 中的小写字母转换成大写字母{for( size_t i=0; i<="str[i]" )="" )<="" ++i="" if(="" p="" sizeof(str[0]);="" str[i]<="z">str[i] -= ('a'-'A' );}char str[] = "aBcDe";cout << "str字符长度为: " << sizeof(str)/sizeof(str[0]) << endl;UpperCase( str );cout << str << endl;答:函数内的sizeof有问题。

c语言经典笔试题(非常全)

c语言经典笔试题(非常全)

1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL2. 写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。

#define MIN(A,B) ((A) <= (B) (A) : (B))4. 嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环呢?这个问题用几个解决方案。

我首选的方案是:while(1){}一些程序员更喜欢如下方案:for(;;){}第三个方案是用gotoLoop:...goto Loop;5. 用变量a给出下面的定义a) 一个整型数(An integer)b) 一个指向整型数的指针(A pointer to an integer)c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer)d) 一个有10个整型数的数组(An array of 10 integers)e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers)f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数(An array of ten pointers to functions that take an integer argument and return an integer )答案是:a) int a; // An integerb) int *a; // A pointer to an integerc) int **a; // A pointer to a pointer to an integerd) int a[10]; // An array of 10 integerse) int *a[10]; // An array of 10 pointers to integersf) int (*a)[10]; // A pointer to an array of 10 integersg) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integerh) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer6. 关键字static的作用是什么?这个简单的问题很少有人能回答完全。

c语言深拷贝的三种实现方式

c语言深拷贝的三种实现方式

c语言深拷贝的三种实现方式C语言是一种广泛应用于编程领域的语言,深拷贝是在C语言中常用的一种操作,它可以创建一个新的对象并将原对象的值完全复制给新对象,而不是简单地复制指针。

本文将介绍C语言中三种实现深拷贝的方式。

1. 使用memcpy函数实现深拷贝memcpy函数是C语言中的一个库函数,它可以将指定长度的内存块从源地址复制到目标地址。

在深拷贝过程中,可以使用memcpy函数将原对象的内存块内容复制到新对象的内存块中,从而实现深拷贝。

以下是使用memcpy函数实现深拷贝的示例代码:```c#include <stdio.h>#include <stdlib.h>#include <string.h>typedef struct {int x;int y;} Point;Point* deepCopy(Point* src) {Point* dst = (Point*)malloc(sizeof(Point));memcpy(dst, src, sizeof(Point));return dst;}int main() {Point p1 = {10, 20};Point* p2 = deepCopy(&p1);printf("p1: x = %d, y = %d\n", p1.x, p1.y);printf("p2: x = %d, y = %d\n", p2->x, p2->y);free(p2);return 0;}```2. 递归实现深拷贝递归是一种常用的算法思想,可以用于深拷贝的实现。

在递归实现深拷贝时,可以先创建一个新对象,然后递归地将原对象的每个成员进行深拷贝,最后将每个深拷贝的成员赋值给新对象的相应成员。

以下是使用递归实现深拷贝的示例代码:```c#include <stdio.h>#include <stdlib.h>typedef struct Node {int data;struct Node* next;} Node;Node* deepCopy(Node* src) {if (src == NULL) {return NULL;}Node* dst = (Node*)malloc(sizeof(Node)); dst->data = src->data;dst->next = deepCopy(src->next);return dst;}int main() {Node* head = (Node*)malloc(sizeof(Node)); Node* node1 = (Node*)malloc(sizeof(Node)); Node* node2 = (Node*)malloc(sizeof(Node)); head->data = 1;head->next = node1;node1->data = 2;node1->next = node2;node2->data = 3;node2->next = NULL;Node* copy = deepCopy(head); printf("Original list: ");Node* curr = head;while (curr != NULL) {printf("%d ", curr->data); curr = curr->next;}printf("\n");printf("Copied list: ");curr = copy;while (curr != NULL) {printf("%d ", curr->data); curr = curr->next;}printf("\n");free(head);free(node1);free(node2);free(copy);return 0;}```3. 使用自定义的复制函数实现深拷贝在C语言中,可以通过自定义的复制函数来实现深拷贝。

用变量A给出下面的定义

用变量A给出下面的定义
{
cout <<sizeof( str )//=
}
(3)void *p = malloc( 100 );
请计算:
sizeof ( p )=
9、头文件中的ifndef/define/endif干什么用?
10、#include <filename.h>和#include “filename.h”有什么区别?
11、下面是有关内存的思考题,请问运行Test函数会有什么样的结果?
(1)void GetMemory(char *p)
{ p = (char *)malloc(100); }
voidTest(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "helloworld");
{*p = (char *)malloc(num); }
void Test(void)
{
char *str = NULL;
GetMemory(&str,100);
strcpy(str, "hello");
printf(str);
}
(4)void Test(void)
{
char *str = (char *) malloc(100);
strcpy(str,“hello”);
free(str);
if(str != NULL)
{
strcpy(str,“world”);
printf(str);
}
}
12、已知strcpy函数的原型是:
char *strcpy(char *strDest, const char *strSrc);

c语言笔试题(答案)

c语言笔试题(答案)

笔试题一、填空题(每一个空4分,共28分)1)struct tagABC{char name[10];char sex;long sno;float score[4];}*pAbc;(四字节对齐)pAbc=NULL;那么,执行pAbc+=2;以后pAbc的值为(64 )2)如下代码,最终value的值是(8)int *p1,*p2;int value;p1=(int*)0×400;p2=(int*)0×408;value = p2-p1;3)如下代码,printf的结果为(2)#include〈〉#include〈〉void main(void){char acNew[20]= “\\0\0”;printf(“%d\n”,strlen(acNew));}4) 有如下程序段,运行该程序的输出结果是(33)main (){int y=3,x=3,z=1;printf(“%d%d\n”,(++x,y++),z+2);}5)设有:int a=1,b=2,c=3,d=4,m=2,n=2;执行(m=a>b)&&(n=c>d)后,n的值为(2)6)struct tagAAA{Unsigned char ucId:1;Unsigned char ucPara0:2;Unsigned char ucState:6;Unsigned char ucTail:4;Unsigned char ucAvail;Unsigned char unTail2:4;Unsigned long ulData;}AAA_S问:AAA_S在字节对齐别离为1,4情形下,占用的空间大小别离是多少?(9)(12 )二、选择题(每题2分,共34分)1)如有说明int(*p)[3];以下表达正确的选项是(D )A:p是指针数组B:(*p)[3]和*p[3]等价C:p是指向一维数组中任何一个元素的指针D:p是指向含有3个整型元素的一维数组的指针2)以下关于单元测试的描述,哪些是对的?(D)A:黑盒测试针对软件的功能,不考虑功能的实现细节;B:白盒测试针对源代码的测试,从程序功能的具体实现上找错;C:途径覆盖是黑盒测试的一种方式,编写测试用例使程序的每条语句都能走到;D:条件覆盖是百盒测试的一种方式, 编写测试用例使程序的每一个判定的各类情形都能到3)以下能够用于任务间通信的有(ABCD)A:共享内存B:信号量C:消息队列和管道D:socket挪用4)有关结构,以下哪些描述是对的?(BC)A:为了测试方便,尽可能把一个结构的功能设计得多一些B:不同结构间的关系不要过于复杂C:结构中的各元素应代表同一事务的不同侧面,而不该把描述没有关系或关系很弱的不同事务的元素放到同一结构中D:结构中元素的布局与排列顺序能够随意设计5)关于强制类型转化,下面说法正确的选项是(ABCD)A:当目的结构的空间大于源结构的空间时,要重点关注内存访问超过源结构范围的情形,可能越界;B:当目的结构的空间小于源结构的空间时,要重点关注对目的结构赋值不能完全覆盖源结构范围的情形,可能遗漏;C:结构体之间的强制类型转换时,其成员字段的数据类型的不同也是要额外警戒的;D:与结构体之间的强制类型转换相较,大体数据结构的强制类型转换更易显现上面描述的情形,利用的时候,必然要慎之又慎;6)正确的利用assert,软件系统可不能对人为缘故造成的错误进行处置。

软件开发笔试题

软件开发笔试题

软件开发类笔试题Part I: C语言基础(30分)1.(4分)用变量a给出下面的定义a)一个整型数:__________________b)一个指向整型数的指针:__________________c)一个指向指针的的指针,它指向的指针是指向一个整型数:__________________d)一个有10个整型数的数组:__________________e)一个有10个指针的数组,该指针是指向一个整型数的:__________________f)一个指向有10个整型数数组的指针:__________________g)一个指向函数的指针,该函数有一个整型参数并返回一个整型数:_____________________h)一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数___________________________________________________________________________________2.(2分)请写出以下语句输出的结果:int i = 43 ;int j = 5 ;double f = 25.45181 ;a)printf("i=%d, j=%d, f=%3.2f" , i , j , f ) :_________________________________________b)printf("i=%X, j=%06d, i/j=%d" , i , j , i/j ) :_________________________________________3.(2分)请完成以下宏定义a)用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)_______________________________________________________________________________ b)写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个_______________________________________________________________________________4.(3分)以下为32位Windows下的C++程序,请计算:char srt[]=“Hello”;char *p=str;请计算:sizeof(str)=sizeof(p)=strlen(p)=void Func (char str[100]){void *p=malloc(100);}请计算sizeof(str)=sizeof(p)=int a[3]={1,2,3};int b=sizeof(a)/sizeof(a[0]);请计算:b=5.(2分)设有定义:int n=0,*p=&n,**q=&p;则以下选项中,正确的赋值语句是()A)p=1; B)*q=2; C)q=p; D)*p=5;6.(1分)下面是C语言中两种if语句判断方式。

程序员面试题1

程序员面试题1

本文的写作目的并不在于提供C/C++程序员求职面试指导,而旨在从技术上分析面试题的内涵。

文中的大多数面试题来自各大论坛,部分试题解答也参考了网友的意见。

许多面试题看似简单,却需要深厚的基本功才能给出完美的解答。

企业要求面试者写一个最简单的strcpy函数都可看出面试者在技术上究竟达到了怎样的程度,我们能真正写好一个strcpy函数吗?我们都觉得自己能,可是我们写出的strcpy很可能只能拿到10分中的2分。

读者可从本文看到strcpy函数从2分到10分解答的例子,看看自己属于什么样的层次。

此外,还有一些面试题考查面试者敏捷的思维能力。

分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的深入剖析则可进一步增强自身的内功。

2.找错题试题1:void test1(){char string[10];char* str1 = "0123456789";strcpy( string, str1 );}试题2:void test2(){char string[10], str1[10];int i;for(i=0; i<10; i++){str1[i] = 'a';}strcpy( string, str1 );}试题3:void test3(char* str1){char string[10];if( strlen( str1 ) <= 10 ){strcpy( string, str1 );}}解答:试题1字符串str1需要11个字节才能存放下(包括末尾的’\0’),而string只有10个字节的空间,strcpy会导致数组越界;对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10分;对试题3,if(strlen(str1) <= 10)应改为if(strlen(str1) < 10),因为strlen的结果未统计’\0’所占用的1个字节。

c语言申请内存的语句

c语言申请内存的语句

c语言申请内存的语句在C语言中,申请内存的语句是使用malloc函数来完成的。

malloc函数的原型为:void *malloc(size_t size);其中,size_t是无符号整数类型,表示要分配的内存大小(以字节为单位)。

malloc函数返回一个指向分配内存的指针,如果分配失败,则返回NULL。

下面是符合要求的10个申请内存的语句:1. 申请一个整型变量所需的内存:int *ptr = (int*)malloc(sizeof(int));2. 申请一个字符型变量所需的内存:char *ptr = (char*)malloc(sizeof(char));3. 申请一个浮点型变量所需的内存:float *ptr = (float*)malloc(sizeof(float));4. 申请一个指针变量所需的内存:int **ptr = (int**)malloc(sizeof(int*));5. 申请一个结构体变量所需的内存:struct student *ptr = (struct student*)malloc(sizeof(structstudent));6. 申请一个数组所需的内存:int *arr = (int*)malloc(n * sizeof(int));7. 申请一个字符串所需的内存:char *str = (char*)malloc((strlen("hello") + 1) * sizeof(char));8. 申请一个二维数组所需的内存:int **matrix = (int**)malloc(m * sizeof(int*));for (int i = 0; i < m; i++) {matrix[i] = (int*)malloc(n * sizeof(int));}9. 申请一个动态大小的数组所需的内存:int *arr = (int*)malloc(size * sizeof(int));10. 申请一个动态大小的字符串所需的内存:char *str = (char*)malloc((length + 1) * sizeof(char));以上是10个常见的申请内存的语句示例,可以根据具体的需求来选择使用。

c语言面试题__指针篇

c语言面试题__指针篇

c语言面试题__指针篇1. char * const p;char const * pconst char *p上述三个有什么区别?char * const p; //常量指针,p的值不可以修改char const * p;//指向常量的指针,指向的常量值不可以改const char *p; //和char const *p------------------------------------------------------2. char str1[] = "abc";char str2[] = "abc";const char str3[] = "abc";const char str4[] = "abc";const char *str5 = "abc";const char *str6 = "abc";char *str7 = "abc";char *str8 = "abc";cout << ( str1 == str2 ) << endl;cout << ( str3 == str4 ) << endl;cout << ( str5 == str6 ) << endl;cout << ( str7 == str8 ) << endl;打印结果是什么?解答:结果是:0 0 1 1str1,str2,str3,str4是数组变量,它们有各自的内存空间;而str5,str6,str7,str8是指针,它们指向相同的常量区域-----------------------------------------------3. 以下代码中的两个sizeof用法有问题吗?void UpperCase( char str[] ) // 将 str 中的小写字母转换成大写字母{for( size_t i=0; i<sizeof(str)/sizeof(str[0]); ++i ) if( 'a'<=str[i] && str[i]<='z' )str[i] -= ('a'-'A' );}char str[] = "aBcDe";cout << "str字符长度为: " << sizeof(str)/sizeof(str[0]) << endl;UpperCase( str );cout << str << endl;答:函数内的sizeof有问题。

c语言memcpy函数用法

c语言memcpy函数用法

c语言memcpy函数用法`memcpy`函数是C语言中的一个函数,用于在内存之间进行数据的拷贝。

它的原型如下:```cvoid* memcpy(void* dest, const void* src, size_t n);````memcpy`函数的作用是将`src`指针指向的内存中的数据拷贝到`dest`指针指向的内存中,拷贝的字节数由`n`指定。

该函数返回一个指向`dest`的指针,也就是第一个参数的值。

`memcpy`函数的常见用法有以下几种情况:1.拷贝字符串:```cchar dest[20];char src[] = "Hello, world!";memcpy(dest, src, strlen(src)+1);```上述代码将字符串`src`的内容拷贝到数组`dest`中,并且包括字符串结束符`\0`。

需要注意的是,这里的拷贝长度需要加1,以便拷贝字符串结束符。

2.拷贝结构体:```cstruct Personchar name[20];int age;};struct Person p1 = {"Alice", 25};struct Person p2;memcpy(&p2, &p1, sizeof(struct Person));```上述代码将结构体`p1`的内容拷贝到结构体`p2`中。

因为结构体的字节数可以使用`sizeof`关键字获取,所以可以通过将结构体的大小作为拷贝的字节数来确保拷贝的完整性。

3.拷贝数组:```cint arr1[] = {1, 2, 3, 4, 5};int arr2[5];memcpy(arr2, arr1, sizeof(arr1));```上述代码将数组`arr1`的内容拷贝到数组`arr2`中,实现了对数组的快速复制。

4.拷贝部分数据:```cchar str[] = "Hello, world!";char str2[7];memcpy(str2, str, 6);str2[6] = '\0';```上述代码将字符串`str`的前6个字节拷贝到`str2`中,并在`str2`的第7个字节位置添加字符串结束符`\0`。

c语言经典编程题abc

c语言经典编程题abc

c语言经典编程题abc C语言面试编程题篇1考查的是结构体和数组的内存布局情况。

#include#includetypedeftructarray1{intID;tructarray1某ne某t;}A;typedeftructarray2{intID;inta;intb;intc;}某B;intmain(){A1[15];A某2;B3;for(inti=0;i<10;i++){1[i].ID=i+64;}2=1+3;3=(B)2;printf("%d/n",3->b);return0;}C语言面试编程题篇2从字符串数组和指针字符串在内存中的分配情况考查指针的使用。

#include#include#includechar某GetMemory(char某p){p=(char某)malloc(100);returnp;}//当调用此函数时,会在栈里分配一个空间存储p,p指向堆当中的一块内存区,当函数调用结束后,若函数没有返回值,//系统自动释放栈中的PvoidTet(void){char某tr=NULL;tr=GetMemory(tr);trcpy(tr,"tet");printf("%/n",tr);}char某GetMemory1(void){char某p="Tet1";returnp;}//若换成charp[]="helloworld";就会在函数调用结束后,释放掉为"Tet1"的拷贝分配的空间,返回的P只是一个野指针voidTet1(){char某tr="";tr=GetMemory1();printf("%/n",tr);//tr=GetMemory();}voidGetMemory2(char某某p,intnum){某p=(char某)malloc(num);}//当调用此函数时,会在栈里分配一个空间存储p,p指向栈中的一变量tr,在此函数中为tr在堆当中分配了一段内存空间//函数调用结束后,会释放p,但tr所在的函数Tet2还没运行完,所以tr此时还在栈里.voidTet2(void){char某tr=NULL;GetMemory2(&tr,100);trcpy(tr,"hello");printf("%/n",tr);}voidTet3(void){char某tr=(char某)malloc(100);trcpy(tr,"hello");//此时的tr指向的是拷贝到栈里的"hello",所以当释放掉tr指向的堆空间时,tr指向的栈里的值还是不变free(tr);if(tr!=NULL){trcpy(tr,"world");printf("%/n",tr);}}intmain(){Tet();Tet1();Tet2();Tet3();}C语言面试编程题篇3C语言中izeof的用法voidfun(char[10]){printf("%/n",);printf("%d/n",izeof());//引用的大小}intmain(){chartr[]={"adade"};printf("%d/n",izeof(tr));//字符串数组的大小10(包含了字符'/0')printf("%d/n",trlen(tr)));//字符串的长度9char某p=tr;printf("%d/n",izeof(p));//指针的大小4printf("%d/n",trlen(p));//字符串的长度9fun(tr);void某h=malloc(100);char[100]="abcd";printf("%d/n",izeof());//字符串数组的大小100printf("%d/n",trlen());//字符串的长度4printf("%d/n",izeof(h));//指针的大小4 }。

c语言笔试题(答案)

c语言笔试题(答案)

笔试题一、填空题(每个空4分,共28分)1)struct tagABC{char name[10];char sex;long sno;float score[4];}*pAbc;(四字节对齐)pAbc=NULL;那么,执行pAbc+=2;之后pAbc的值为(64 )2)如下代码,最终value的值是(8)int *p1,*p2;int value;p1=(int*)0×400;p2=(int*)0×408;value = p2-p1;3)如下代码,printf的结果为(2)#include〈stdio.h〉#include〈string.h〉void main(void){char acNew[20]= “\\0\0”;printf(“%d\n”,strlen(acNew));}4) 有如下程序段,运行该程序的输出结果是(33)main (){int y=3,x=3,z=1;printf(“%d%d\n”,(++x,y++),z+2);}5)设有:int a=1,b=2,c=3,d=4,m=2,n=2;执行(m=a>b)&&(n=c>d)后,n的值为(2)6)struct tagAAA{Unsigned char ucId:1;Unsigned char ucPara0:2;Unsigned char ucState:6;Unsigned char ucTail:4;Unsigned char ucAvail;Unsigned char unTail2:4;Unsigned long ulData;}AAA_S问:AAA_S在字节对齐分别为1,4情况下,占用的空间大小分别是多少?( 9)(12 )二、选择题(每题2分,共34分)1)若有说明int(*p)[3];以下叙述正确的是( D )A:p是指针数组B:(*p)[3]和*p[3]等价C:p是指向一维数组中任何一个元素的指针D:p是指向含有3个整型元素的一维数组的指针2)以下关于单元测试的描述,哪些是对的?(D)A:黑盒测试针对软件的功能,不考虑功能的实现细节;B:白盒测试针对源代码的测试,从程序功能的具体实现上找错;C:路径覆盖是黑盒测试的一种方法,编写测试用例使程序的每条语句都能走到;D:条件覆盖是百盒测试的一种方法, 编写测试用例使程序的每个判断的各种情况都能到3)以下可以用于任务间通信的有(ABCD)A:共享内存 B:信号量C:消息队列和管道 D:socket调用4)有关结构,以下哪些描述是对的?(BC)A:为了测试方便,尽量把一个结构的功能设计得多一些B:不同结构间的关系不要过于复杂C:结构中的各元素应代表同一事务的不同侧面,而不应把描述没有关系或关系很弱的不同事务的元素放到同一结构中D:结构中元素的布局与排列顺序可以随意设计5)关于强制类型转化,下面说法正确的是(ABCD)A:当目的结构的空间大于源结构的空间时,要重点关注内存访问超过源结构范围的情形,可能越界;B:当目的结构的空间小于源结构的空间时,要重点关注对目的结构赋值不能完全覆盖源结构范围的情形,可能遗漏;C:结构体之间的强制类型转换时,其成员字段的数据类型的差异也是要格外小心的; D:与结构体之间的强制类型转换相比,基本数据结构的强制类型转换更容易出现上面描述的情况,使用的时候,一定要慎之又慎;6)正确的使用assert,软件系统不会对人为原因造成的错误进行处理。

c语言经典笔试题(非常全)

c语言经典笔试题(非常全)

1. 用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题)#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL2. 写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。

#define MIN(A,B) ((A) <= (B) (A) : (B))4. 嵌入式系统中经常要用到无限循环,你怎么样用C编写死循环呢?这个问题用几个解决方案。

我首选的方案是:while(1){}一些程序员更喜欢如下方案:for(;;){}第三个方案是用gotoLoop:...goto Loop;5. 用变量a给出下面的定义a) 一个整型数(An integer)b) 一个指向整型数的指针(A pointer to an integer)c) 一个指向指针的的指针,它指向的指针是指向一个整型数(A pointer to a pointer to an integer)d) 一个有10个整型数的数组(An array of 10 integers)e) 一个有10个指针的数组,该指针是指向一个整型数的(An array of 10 pointers to integers)f) 一个指向有10个整型数数组的指针(A pointer to an array of 10 integers)g) 一个指向函数的指针,该函数有一个整型参数并返回一个整型数(A pointer to a function that takes an integer as an argument and returns an integer)h) 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数(An array of ten pointers to functions that take an integer argument and return an integer )答案是:a) int a; // An integerb) int *a; // A pointer to an integerc) int **a; // A pointer to a pointer to an integerd) int a[10]; // An array of 10 integerse) int *a[10]; // An array of 10 pointers to integersf) int (*a)[10]; // A pointer to an array of 10 integersg) int (*a)(int); // A pointer to a function a that takes an integer argument and returns an integerh) int (*a[10])(int); // An array of 10 pointers to functions that take an integer argument and return an integer6. 关键字static的作用是什么?这个简单的问题很少有人能回答完全。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

GetMemory的典型例子2010-01-13 18:24 520人阅读评论(2) 收藏举报//NO.1:程序首先申请一个char类型的指针str,并把str指向NULL(即str里存的是NULL的地址,*str为NULL中的值为0),调用函数的过程中做了如下动作:1申请一个char 类型的指针p,2把str的内容copy到了p里(这是参数传递过程中系统所做的),3为p指针申请了100个空间,4返回Test函数.最后程序把字符串hello world拷贝到str 指向的内存空间里.到这里错误出现了!str的空间始终为NULL而并没有实际的空间.深刻理解函数调用的第2步,将不难发现问题所在!void GetMemory(char *p){p = (char*)malloc(100);}void Test(void){char *str = NULL;GetMemory(str);strcpy(str, "hello world");printf(str);}//请问运行Test函数后会是什么样的结果?//NO.2:程序首先申请一个char类型的指针str,并把str指向NULL.调用函数的过程中做了如下动作:1申请一数组p[]并将其赋值为hello world(数组的空间大小为12),2返回数组名p付给str指针(即返回了数组的首地址).那么这样就可以打印出字符串"hello world"了么?当然是不能的!因为在函数调用的时候漏掉了最后一步.也就是在第2步return数组名后,函数调用还要进行一步操作,也就是释放内存空间.当一个函数被调用结束后它会释放掉它里面所有的变量所占用的空间.所以数组空间被释放掉了,也就是说str所指向的内容将不确定是什么东西.char *GetMemory(void){char p[] = "hello world";return p;void Test(void){char *str = NULL;str = GetMemory();printf(str);}//NO.3:问题同NO.1,正确答案为可以打印出hello.但内存泄漏了!void GetMemory(char **p, int num){*p = (char*)malloc(num);}void Test(void){char *str = NULL;GetMemory(&str, 100);strcpy(str, "hello");printf(str);}//NO.4:申请空间,拷贝字符串,释放空间.前三步操作都没有任何问题.到if语句里的判断条件开始出错了,因为一个指针被释放之后其内容并不是NULL,而是一个不确定的值.所以if语句永远都不能被执行.这也是著名的"野"指针问题.所以我们在编写程序释放一个指针之后一定要人为的将指针付成NULL.这样就会避免出现"野"指针的出现.有人说"野"指针很可怕,会带来意想不到的错误.void Test(void){char *str = (char*)malloc(100);strcpy(str, "hello");free(str);if (str != NULL)strcpy(str, "world");printf(str);}}void GetMemory1(char *p) {p = (char *)malloc(100); }void Test1(void){char *str = NULL;GetMemory1(str);strcpy(str, "hello world");printf(str);}//str一直是空,程序崩溃char *GetMemory2(void) {char p[] = "hello world";return p;}void Test2(void){char *str = NULL;str = GetMemory2();printf(str);}char *GetMemory3(void)return "hello world";}void Test3(void){char *str = NULL;str = GetMemory3();printf(str);}//Test3 中打印hello world,因为返回常量区,而且并没有被修改过。

Test2中不一定能打印出hello world,因为指向的是栈。

void GetMemory4(char **p, int num){*p = (char *)malloc(num);}void Test4(void){char *str = NULL;GetMemory3(&str, 100);strcpy(str, "hello");printf(str);}//内存没释放void Test5(void){char *str = (char *) malloc(100);strcpy(str, "hello");free(str);if(str != NULL)strcpy(str, "world");printf(str);}}//str为野指针,打印的结果不得而知void Test6(){char *str=(char *)malloc(100);strcpy(str, "hello");str+=6;free(str);if(str!=NULL){strcpy(str, "world");printf(str);}}//VC断言失败,运行错误另转一则:char *GetMemory3(int num){char *p = (char *)malloc (sizeof(char) * num); return p; //返回指针 p}void Test3(void){char *str = NULL;str = GetMemory3(100); //这里指针 str也和指针 p的指向一样的内存块。

strcpy(str, "hello");cout<< str << endl;free(str); //这里最终只是释放了str指向的内存块,对于str指针依然还是指向那块内存,看了一些资料说应该加一句str=0;那指针 p呢?p也依然在指向那块内存啊。

}回复:答者:wutaozhao() 信誉:100 级别:user2 日期:2007-6-29 21:42:21 id:41451636指针之间传递的就是地址,所以str和p所指向的内存块是同一个,释放其中任何一个即可答者:what_a_big() 信誉:100 级别:user1 日期:2007-6-29 21:42:21 id:41451637那指针 p呢?=================================================================== ==========after returning from GetMemory()p (局部变量)没了,那块内存还在。

现在str 指向那块内存。

看了一些资料说应该加一句str=0=================================也可以不写str=NULL,只要你不再引用str。

答者:believefym(feng) 信誉:100 级别:user5 日期:2007-6-29 21:50:38 id:41451675同一块内存,释放一次即可,只不过所有指向那块内存的指针都失效了,就像楼主代码里的p和str释放之后str就变成了野指针,加str=NULL,可以避免之后错误使用该指针,方便调试答者:lightnut() 信誉:100 级别:star1 日期:2007-6-29 22:05:48 id:414517361.函数进入Test3():char* str = NULL;======================变量变量的地址变量的值(内容)str 0x0013fe8c 02.str = GetMemory3(..)=====>char *p = (char *)malloc (sizeof(char) * num);将分配的内存起始地址(0x003a60b0)赋给栈变量p,===============================================变量变量的地址变量的值(内容)p 0x0013fda8 0x003a60b03. 从GetMemory3(..)返回, p的值(0x003a60b0)拷贝给str, 栈变量p生命结束, 释放其所占栈内存(地址0x0013fda8)=================================================变量变量的地址变量的值(内容)str 0x0013fe8c 0x003a60b04. free(str): 释放str指向的内存(0x003a60b0开始的内存空间)5. 推出Test3()后, 栈变量str生命结束, 释放其所占栈内存(地址0x0013fe8c)答者:freshui(五月的风-最近老犯困) 信誉:100 级别:user1 日期:2007-6-29 22:12:07 id:41451763呵呵 p没了已经死了:)注意看变量的作用域答者:buhaohaoxuexi() 信誉:100 级别:user1 日期:2007-6-29 22:37:00 id:41451888为什么会死呢,不是说动态分配是分配在堆上的吗?他不应该死啊。

答者:yydrewdrew(满堂花醉三千客,一剑霜寒十四州) 信誉:100 级别:user1 日期:2007-6-29 23:55:01 id:41452325char *GetMemory3(int num){char *p = (char *)malloc (sizeof(char) * num);return p; //返回指针 p}void Test3(void){char *str = NULL;str = GetMemory3(100); //调用完后p被析构,p为局部作用域存在于函数GetMemory3的栈中,当GetMemory3被调用完后,栈空间被释放,因而被析构。

strcpy(str, "hello");cout<< str << endl;free(str); //这里最好加一句str = NULL。

相关文档
最新文档